​一道逆向的三种解题思路


题目分析

 

1. IDA 打开程序,main 函数反汇编,大概逻辑是输入三次的字符串到 s 中。前两次只可以输入 2 个字符和4 个,第三次输入的是拼接在前两次后面。

 

下面会经过一个判断,通过之后就会将 data 中的数据经过输入异或之后的运算,写入到 flag.jpg 中。


  • data


 

通过判断,输入的传入到 hash 函数里:


v3 =( v9 == 20 &&hash(s) == 3522040383264150944LL);


hash 函数:


__int64 __fastcall hash(char *a1)
{  
char *v1; // rax  
char *v3; //[rsp+0h] [rbp-18h]  
signed __int64 v4;// [rsp+10h] [rbp-8h]
   
v3 = a1;  
v4 = 5381LL;  
while ( *v3 )  
  {
  v1 = v3++;   
  v4 = 33 * v4 + *v1; 
   }  
 return v4;
 }


第一种思路

所以第一种思路就是逆向这个算法,找到这个原来的字符串,但是我这垃圾逆向功底完全就搞不定这个算法。只能用取巧的方法来做了。

  • 这里也可以使用 Z3 来约束求解,但是貌似也跑不出结果。

 

第二种思路

因为已知程序程序输出会错误输出是两个不同的提示,所以可以尝试一下使用 angr 来通过符号执行的方法来解题。

if ( stream ){ 
   ...   
   puts("yougot my secret photo");
   }else{ 
       puts("hakerhaker go away");
       }


 

直接载入,添加 find 路径和 avoid 路径,开始跑。。

这里没跑出来,应该是没有限制路径和一些约束条件,但这不妨是一种思路。


 

第三种思路

 

因为发现到最后是将输入的 s 在长度值(v9)的偏移和 data 异或,然后输出到 jpg 文件中。因为我们知道最后的结果是 jpg 文件,那么可以通过 JPG 的文件头部特征,和 data 进行异或,就可以得到原始的 s 的值。


 

例如,我们知道 jpg 文件头的 magic number 为:FFD8FFE0,和这里的 data 开头:8CB28B95 进行异或,就可以得到前四位为 "sjtu"



 


以此类推,我们找到一个正常的 jpg 文件,对他的头部 20 个字节和 data 的 20 个字节进行异或就行了,最后得到的 s 的值为:

sjtu93hechangeschina


直接输入就会在当前目录下生成一个 flag.jpg 文件。

打开就可以得到最后的 flag。


 

 


本文作者:星盟安全团队

本文为安全脉搏专栏作者发布,转载请注明:https://www.secpulse.com/archives/116548.html

Tags:
评论  (0)
快来写下你的想法吧!

星盟安全团队

文章数:31 积分: 75

星盟安全团队---"VENI VIDI VICI"(我来,我见,我征服),我们的征途是星辰大海。从事各类安全研究,专注于知识分享。

安全问答社区

安全问答社区

脉搏官方公众号

脉搏公众号