实验吧逆向之迷路
今天来看看逆向中一些比较有脑洞的思路方法,以实验吧中的一道名为迷路(http://www.shiyanbar.com/ctf/1915)的题为例.
首先运行程序是这个样子的:
然后随便输入一串字符后,有窗口提示:
然后载入IDA,查看一下字符串,搜索Pls Try [email protected]!等字样,再结合ollydbg动态分析之后,明白了程序的基本流程:
首先将获取的输入经atol()函数转为数字,并与0x92381221做比较,之后对输入的字符串做md5并将结果与4850B7446BBB20AAD140E7B0A964A57D进行比较,如果都相同就成功;
但是查询4850B7446BBB20AAD140E7B0A964A57D对应的明文是sakjflks,既要等于92381221h又要是sakjflsk显然是不可能的,所以在这里面一定还有什么东西;
之后我们再OD中查看句柄窗口,果然发现这里有两个input,说明其中一个input被隐藏起来了:
在OD中重新加载程序,Ctrl+g搜索ShowWindow下断点,可以看到有一个按钮被hide了,把它的值00000000改成00000001即可;
隐藏的input被显示出来了;
然后我们Ctrl+g搜索GetWindowTextA下断点,然后重新输入flag,点击左边的input键,然后程序在0x00410A6B的位置停了下来;
然后一步一步的跟,发现这里是有个很关键的地方0x401F96,不注意就跳到失败的地方去了,IDA里f5看看0x401740里面是什么
可以看到输入需要满足格式OOCTF{里面有32位},满足这些条件后,程序运行到这里,调用0x00401860处函数的函数处理后,得到另外一串字符串,且传入的参数正是{}里面的32位字符串,最后处理结果由0x00402d06函数判断是否等于b5h760h64R867618bBwB48BrW92H4w5r
该函数对于字符串中的数字不做处理,字母转化成字母表中对应的0-25之间的数值,之后将得到的v9再转化成相应的字母;
知道了算法之后,就可以倒退出flag了:
name="b5h760h64R867618bBwB48BrW92H4w5r"
lenth=len(name)
def fun(a,i):
edx=0x5
edi=0x1c
if(i==0):
edx=0x3 #第一次调用为0x3
eax=a*edx
eax=eax+edi
edx=eax%0x1A
#print(edx)
return edx
key=""
le=0
while(le!=lenth):
for i in range(ord('0'),ord('z')):
if(i>=ord('A') and i<=ord('Z')):
a=i-ord('A')
b=fun(a,i)+ord('A')
if(name[le]==chr(b)):
key=key+chr(i)
le=le+1
break
elif(i>=ord('a') and i<=ord('z')):
a=i-ord('a')
b=fun(a,i)+ord('a')
if(name[le]==chr(b)):
key=key+chr(i)
le=le+1
break
elif(i>=ord('0') and i<=ord('9')):
if(name[le]==chr(i)):
key=key+chr(i)
le=le+1
break
else:
b=fun(i,i)+ord('A')
if(name[le]==chr(b)):
key=key+chr(i)
le=le+1
break
print("flag: OOCTF{"+key+"}")
代码的处理和OD中跟出来的步骤基本一样,fun函数的结果加ord('A')或ord('a')就是v9;