实验吧逆向之迷路

今天来看看逆向中一些比较有脑洞的思路方法,以实验吧中的一道名为迷路(http://www.shiyanbar.com/ctf/1915)的题为例.

首先运行程序是这个样子的:

然后随便输入一串字符后,有窗口提示:

然后载入IDA,查看一下字符串,搜索Pls Try  ag@in!等字样,再结合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;

猜你喜欢

转载自blog.csdn.net/qq_40827990/article/details/83212779
今日推荐