1. 程式人生 > >實驗吧逆向之迷路

實驗吧逆向之迷路

後記:寫了篇部落格一個月後我重新分析這道題發現,這個題的flag實驗吧可以提交,但是這個程式本身過不了,後來研究一下發現,當程式輸入的字串中含有‘0’時,演算法不太對了,主要是v5的值受到了字元0的影響........

首先執行程式是這個樣子的:

然後隨便輸入一串字元後,有視窗提示:

然後載入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;