题目描述:菜鸡听说有的程序运行就能拿Flag?
ELF文件,32位,没有加壳
先看main函数
main函数一共调用了四个函数,一个个看
setlocale
banner
prompt_authentication
authenticate
通览一遍,感觉最重要的函数是authenticate
记下来我们详细看一下authenticate
先分别看一下其中的unk_8048B44
和unk_8048BA4
unk_8048B44
.rodata:08048B44 unk_8048B44 db 53h ; S ; DATA XREF: authenticate+78↑o .rodata:08048B45 db 0 .rodata:08048B46 db 0 .rodata:08048B47 db 0 .rodata:08048B48 db 75h ; u .rodata:08048B49 db 0 .rodata:08048B4A db 0 .rodata:08048B4B db 0 .rodata:08048B4C db 63h ; c .rodata:08048B4D db 0 .rodata:08048B4E db 0 .rodata:08048B4F db 0 .rodata:08048B50 db 63h ; c .rodata:08048B51 db 0 .rodata:08048B52 db 0 .rodata:08048B53 db 0 .rodata:08048B54 db 65h ; e .rodata:08048B55 db 0 .rodata:08048B56 db 0 .rodata:08048B57 db 0 .rodata:08048B58 db 73h ; s .rodata:08048B59 db 0 .rodata:08048B5A db 0 .rodata:08048B5B db 0 .rodata:08048B5C db 73h ; s .rodata:08048B5D db 0 .rodata:08048B5E db 0 .rodata:08048B5F db 0 .rodata:08048B60 db 21h ; !
success
unk_8048BA4
.rodata:08048BA4 unk_8048BA4 db 41h ; A ; DATA XREF: authenticate:loc_804878F↑o .rodata:08048BA5 db 0 .rodata:08048BA6 db 0 .rodata:08048BA7 db 0 .rodata:08048BA8 db 63h ; c .rodata:08048BA9 db 0 .rodata:08048BAA db 0 .rodata:08048BAB db 0 .rodata:08048BAC db 63h ; c .rodata:08048BAD db 0 .rodata:08048BAE db 0 .rodata:08048BAF db 0 .rodata:08048BB0 db 65h ; e .rodata:08048BB1 db 0 .rodata:08048BB2 db 0 .rodata:08048BB3 db 0 .rodata:08048BB4 db 73h ; s .rodata:08048BB5 db 0 .rodata:08048BB6 db 0 .rodata:08048BB7 db 0 .rodata:08048BB8 db 73h ; s .rodata:08048BB9 db 0 .rodata:08048BBA db 0 .rodata:08048BBB db 0 .rodata:08048BBC db 20h .rodata:08048BBD db 0 .rodata:08048BBE db 0 .rodata:08048BBF db 0 .rodata:08048BC0 db 64h ; d .rodata:08048BC1 db 0 .rodata:08048BC2 db 0 .rodata:08048BC3 db 0 .rodata:08048BC4 db 65h ; e .rodata:08048BC5 db 0 .rodata:08048BC6 db 0 .rodata:08048BC7 db 0 .rodata:08048BC8 db 6Eh ; n .rodata:08048BC9 db 0 .rodata:08048BCA db 0 .rodata:08048BCB db 0 .rodata:08048BCC db 69h ; i .rodata:08048BCD db 0 .rodata:08048BCE db 0 .rodata:08048BCF db 0 .rodata:08048BD0 db 65h ; e .rodata:08048BD1 db 0 .rodata:08048BD2 db 0 .rodata:08048BD3 db 0 .rodata:08048BD4 db 64h ; d .rodata:08048BD5 db 0 .rodata:08048BD6 db 0 .rodata:08048BD7 db 0 .rodata:08048BD8 db 21h ; ! .rodata:08048BD9 db 0 .rodata:08048BDA db 0 .rodata:08048BDB db 0 .rodata:08048BDC db 0Ah .rodata:08048BDD db 0
accessdenied
一个是成功,一个是访问被拒,很显然,这个就是输出我们flag是否正确的函数
接下来我们向上看
s2 = decrypt(&s, &dword_8048A90); if ( fgetws(ws, 0x2000, stdin) ) { ws[wcslen(ws) - 1] = 0; if ( !wcscmp(ws, s2) ) wprintf(&unk_8048B44); else wprintf(&unk_8048BA4); } free(s2); }
判断s2和ws是否匹配
匹配输出success
,反之输出accessdenied
而s2是经过decrypt
函数加密过的,我们跟进一下decrypt
函数
可以大致看出函数的加密流程,但是加密流程较为复杂(我看不懂)所以在这考虑使用动态分析的方式,直接读取寄存器中加密过后的s2数值
接下来我们需要找到s2加密后储存在那个寄存器中
而这就需要去authenticate
函数的汇编代码里面找
可以看到其中有一处是通过call汇编指令,将数据送入了decrypt
函数,出来后的数据被直接存放在eax
中
现在我们的目的就是让程序执行decrypt
函数,然后查看eax
寄存器中的值
先给decrypt
函数打个断点
接下来程序运行到打断点的位置停下来
这时候程序在刚碰到decrypt
函数的时候就停了下来,所以我们需要让他步进这段函数
可以看到gdb输出的信息,其中说明了程序已经执行完了decrypt
函数
接下来我们直接查看eax寄存器中的值
6--显示6行数据
s--字符型
w--字节形式
当然,上面这个是试出来的