这是一个 32 为 ELF 文件,用 ida 打开之后,发现没有什么明显的字符串出现,那么看到主函数
1 2 3 4 5 6 7 8
| int __cdecl main(int argc, const char **argv, const char **envp) { setlocale(6, &locale); banner(); prompt_authentication(); authenticate(); return 0; }
|
表面上没有什么值得注意的,经过检查后发现 authenticate 才是关键函数
# authenticate 函数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| void authenticate() { wchar_t ws[8192]; wchar_t *s2;
s2 = decrypt(&s, &dword_8048A90); if ( fgetws(ws, 8192, stdin) ) { ws[wcslen(ws) - 1] = 0; if ( !wcscmp(ws, s2) ) wprintf(&unk_8048B44); else wprintf(&unk_8048BA4); } free(s2); }
|
其中 ws 是输入的 flag,输入的 flag 等于 s2 则输出 & unk_8048B44 这个字符串,点开之后得知就是 Success,也就是正确,所以 s2 就是 flag,但是并不能直接找到,我们先看一下 authenticate 函数的汇编代码
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
| .text:08048708 push ebp .text:08048709 mov ebp, esp .text:0804870B sub esp, 8028h .text:08048711 mov dword ptr [esp+4], offset dword_8048A90 ; wchar_t * .text:08048719 mov dword ptr [esp], offset s ; s .text:08048720 call decrypt .text:08048725 mov [ebp+s2], eax .text:08048728 mov eax, ds:stdin@@GLIBC_2_0 .text:0804872D mov [esp+8], eax ; stream .text:08048731 mov dword ptr [esp+4], 2000h ; n .text:08048739 lea eax, [ebp+ws] .text:0804873F mov [esp], eax ; ws .text:08048742 call _fgetws .text:08048747 test eax, eax .text:08048749 jz short loc_804879C .text:0804874B lea eax, [ebp+ws] .text:08048751 mov [esp], eax ; s .text:08048754 call _wcslen .text:08048759 sub eax, 1 .text:0804875C mov [ebp+eax*4+ws], 0 .text:08048767 mov eax, [ebp+s2] .text:0804876A mov [esp+4], eax ; s2 .text:0804876E lea eax, [ebp+ws] .text:08048774 mov [esp], eax ; s1 .text:08048777 call _wcscmp .text:0804877C test eax, eax .text:0804877E jnz short loc_804878F .text:08048780 mov eax, offset unk_8048B44 .text:08048785 mov [esp], eax .text:08048788 call _wprintf .text:0804878D jmp short loc_804879C
|
看到 6、7 行我们可以知道,我们的 s2 字符串在调用 decrypt 函数的时候杯传入了 eax 寄存器中,如果我们可以获取 eax 中的值就可以直接得到 flag 了,而这里我们需要用到 gdb 调试
# gdb 调试
首先用 gdb 打开文件
然后在 decrypt 函数处设置断点
1
| b decrypt // (breakpoint)
|
再执行到断点处
单步执行 decrypt
显示寄存器
最后就可以查看 eax 中的数据了
其中
6:显示六行数据
s:字符串形式
w:word(4 字节)形式
得到 flag:9447{you_are_an_international_mystery}
题目来源:攻防世界 (xctf.org.cn)——no-strings-attached