love
其实是比较简单的逆向,但是毕竟上手时间短,写一写顺便把思路缕清
题目
打开是dos窗口,等待输入flag,随便输入后直接退出
拖入IDA,重点函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| __int64 main_0() { int len; // eax const char *v1; // eax size_t real_len; // eax int v3; // edx __int64 v4; // ST08_8 signed int j; // [esp-B0h] [ebp-B0h] signed int i; // [esp-A4h] [ebp-A4h] signed int v8; // [esp-A4h] [ebp-A4h] int v9; // [esp-98h] [ebp-98h] int flag; // [esp-2Ch] [ebp-2Ch] int v11; // [esp-10h] [ebp-10h] int v12; // [esp-4h] [ebp-4h]
for ( i = 0; i < 100; ++i ) { if ( (unsigned int)i >= 0x64 ) j____report_rangecheckfailure(); *((_BYTE *)&v12 + i - 0x94) = 0; } puts_("please enter the flag:"); scanf("%20s", &flag); len = j_strlen((const char *)&flag); v1 = (const char *)deal((int)&flag, len, (int)&v11); strncpy((char *)&v9, v1, 40u); v8 = j_strlen((const char *)&v9); for ( j = 0; j < v8; ++j ) *((_BYTE *)&v12 + j - 0x94) += j;
real_len = j_strlen((const char *)&v9); if ( !strncmp((const char *)&v9, Str2, real_len) ) puts_("rigth flag!\n"); else puts_("wrong flag!\n"); HIDWORD(v4) = v3; LODWORD(v4) = 0; return v4; }
Str2 db 'e3nifIH9b_C@n@dH',0
|
分析
程序流程也比较清晰,初始时将一段栈内存置为0,可以看到是在v9处,之后请求输入flag,然后对输入的flag deal加密处理
然后处理得到的字符串再次每位加i,相当于第二次加密,之后将其与一段字符串相比,相等的话就输出right flag
所以问题的重点其实是第一次加密是怎样处理的,ida中看到一堆abcdef…,想着可能是base64,但是不确定。
将文件拖入x32dbg 先运行起来,然后搜索字符串,找到主函数的位置,根据ida可以知道在第一次加密之后调用了strncpy,所以我们在搜索到wrong flag地址,往上翻,可以大概确定加密的地址,在其之后下断点,运行程序输入任意flag,因为约定函数返回值是存在eax中的,查看此时的eax,发现其值就是输入flag的base64,接下来写脚本就完事了
脚本
1 2 3 4 5 6 7 8 9 10 11 12 13
| import base64
string='e3nifIH9b_C@n@dH' unstring = '' for i in range(len(string)): unstring += chr(ord(string[i])-i)
flag = base64.b64decode(unstring) print flag
$ python lovewp.py {i_l0ve_you}
|