​一道逆向的三种解题思路
2019-10-28 17:53:30 Author: www.secpulse.com(查看原文) 阅读量:237 收藏

题目分析

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
如有侵权请联系:admin#unsafe.sh