最近参加了某某ctf比赛,初赛非常业余的那种,算是第一次接触ctf的题目,找flag的过程还觉得蛮刺激的,这不经让我想起了想起了刚开始学习python的时候接触到的Python Challenge,不知道现在学python的小朋友还玩不玩这个游戏?
下面是其中一道逆向题的解题过程,这道题极度简单,其实这道题根本不需要逆向就能解决,因为在cmd中运行一下flag就显示出来了。但是我还是想在熟悉逆向工具IDA的过程中以逆向的方式来找一下flag。
首先在IDA中打开这个文件 easy_easy。
找到_main
这个函数,按F5
可以得到反编译后的伪代码。如下
int __cdecl main(int argc, const char **argv, const char **envp)
{
char v4[210]; // [esp+1Ah] [ebp-E2h]
int v5; // [esp+ECh] [ebp-10h]
__main();
menu();
system("cls");
v5 = 0;
qmemcpy(&v4[42], &unk_403040, 0xA8u);
while ( v5 <= 41 )
{
v4[v5] = v4[4 * v5 + 42] - 52;
++v5;
}
puts(v4);
return 0;
}
第16行的puts(v4)
应该就是输出的flag,让我们来看看flag到底藏在哪里?
v4是一个长度为210存储字符的数组。
第10行的qmemcpy
函数应该就是快速复制内存数据的函数,将unk_403040
中数据复制到v4
42位的后面,长度0xA8
就是168,这个长度就是v4
长度210-42=168,这个长度帮助我们理解后面的内容。
再接下来就是一个for循环,遍历0到41来构造v4中的数据生成flag用来输出。
v4[v5] = v4[4 * v5 + 42] - 52;
因为前面把unk_403040
的数据复制到了v4[42:210]
的位置,也就是对这部分的数据每四位的第一个数据减去52依次放到v4[0:42]
的位置。
我们双击unk_403040
会跳到相应的区域可以看到下面这样的数据
.data:00403040 unk_403040 db 9Ah ; DATA XREF: _main+34↑o
.data:00403041 db 0
.data:00403042 db 0
.data:00403043 db 0
.data:00403044 db 0A0h
.data:00403045 db 0
.data:00403046 db 0
.data:00403047 db 0
.data:00403048 db 95h
.data:00403049 db 0
.data:0040304A db 0
.data:0040304B db 0
.data:0040304C db 9Bh
.data:0040304D db 0
.data:0040304E db 0
.data:0040304F db 0
.data:00403050 db 0AFh
.data:00403051 db 0
.data:00403052 db 0
.data:00403053 db 0
.data:00403054 db 95h
.data:00403055 db 0
.data:00403056 db 0
.data:00403057 db 0
.data:00403058 db 67h ; g
.data:00403059 db 0
.data:0040305A db 0
.data:0040305B db 0
.data:0040305C db 6Bh ; k
.data:0040305D db 0
.data:0040305E db 0
.data:0040305F db 0
......
......
......
.data:004030E1 db 0
.data:004030E2 db 0
.data:004030E3 db 0
.data:004030E4 db 0B1h
.data:004030E5 db 0
.data:004030E6 db 0
.data:004030E7 db 0
.data:004030E8 db 0
.data:004030E9 db 0
.data:004030EA db 0
.data:004030EB db 0
.data:004030EC db 0
.data:004030ED db 0
.data:004030EE db 0
.data:004030EF db 0
.data:004030F0 db 0
.data:004030F1 db 0
.data:004030F2 db 0
.data:004030F3 db 0
.data:004030F4 db 0
.data:004030F5 db 0
.data:004030F6 db 0
.data:004030F7 db 0
.data:004030F8 db 0
.data:004030F9 db 0
.data:004030FA db 0
.data:004030FB db 0
.data:004030FC db 0
.data:004030FD db 0
.data:004030FE db 0
.data:004030FF db 0
目测第四列的数据就是我们要找的flag。先把这些个数据复制粘贴到sublime text中处理,我还是觉得sublime text多行编辑功能很好用,经过几个多行编辑以及查找替换终于得到我们想要的数据,一段十六进制数字,只要把他们丢到python中稍微处理一下打印出来就得到flag了。
9A A0 95 9B AF 95 67 6B 6B 6D 68 6D 68 61 6D 95 6A 64 61 68 68 97 65 61 6C 6B 95 96 61 65 9A 6B 64 6A 9A 96 97 67 66 99 9A B1
flag = "9A A0 95 9B AF 95 67 6B 6B 6D 68 6D 68 61 6D 95 6A 64 61 68 68 97 65 61 6C 6B 95 96 61 65 9A 6B 64 6A 9A 96 97 67 66 99 9A B1".split(" ")
"".join([chr(int(x,16)-52) for x in flag ])
整个过程就是这么简单。