1. 程式人生 > >【pwnable.kr】 codemap

【pwnable.kr】 codemap

hunk see seed heap while malloc cati 根據 ont

pwnable新的一題。

技術分享

download: http://pwnable.kr/bin/codemap.exe

ssh [email protected] -p2222 (pw:guest)

這道題雖然是在pwnable下,但是是一道逆向題。。。 //前web狗膜一發二進制大佬

根據提示,需要查看 0x403E65 運行時,寄存器 EAX,EBX 的內容。

先不考慮運行的內容,先看程序。首先這個程序沒有加殼,直接可以用ida查看內容.

然後可以看到程序的框架,在main函數中,默默按下F5...

int __cdecl main(int argc, const char **argv, const
char **envp) { int seed; // [email protected] int (***v4)(void); // [email protected] int (***v5)(void); // [email protected] int v6; // [email protected] int (**v7)(void); // [email protected] int (***random_funtion)(void); // [email protected] unsigned int
v9; // [email protected] unsigned int v10; // [email protected] char *eax_now_str; // [email protected] unsigned int i; // [email protected] char *max_eax_str; // [sp+10h] [bp-60h]@0 unsigned int eax_now; // [sp+14h] [bp-5Ch]@8 unsigned int count; // [sp+18h] [bp-58h]@1 unsigned int
max_eax; // [sp+1Ch] [bp-54h]@1 char word_str; // [sp+20h] [bp-50h]@9 int v19; // [sp+6Ch] [bp-4h]@3 printf("I will make 1000 heap chunks with random size\n"); printf("each heap chunk has a random string\n"); printf("press enter to start the memory allocation\n"); sub_3440B1(); max_eax = 0; count = 0; srand(0); while ( 1 ) { seed = 10000 * rand() % 1337; v4 = (int (***)(void))operator new(8u); v5 = v4; v19 = 0; if ( v4 ) { *v4 = (int (**)(void))&off_34F2EC; v6 = (10000 * seed >> 1) + 123; v7 = (int (**)(void))operator new(8u); if ( v7 ) { v7[1] = (int (*)(void))v6; v5[1] = v7; random_funtion = v5; } else { v5[1] = 0; random_funtion = v5; } } else { random_funtion = 0; } v19 = -1; v9 = (**random_funtion)(); v10 = v9 % 0x186A0; eax_now = v9 % 0x186A0; eax_now_str = (char *)malloc(v9 % 0x186A0); if ( v10 >= 0x10 ) { qmemcpy(&word_str, "abcdefghijklmnopqrstubwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890", 0x3Fu); i = 0; do eax_now_str[++i - 1] = *(&word_str + rand() % 62); while ( i < 0xF ); eax_now_str[15] = 0; if ( eax_now > max_eax ) { max_eax = eax_now; max_eax_str = eax_now_str; } } if ( ++count >= 0x3E8 ) // 0x3e8 = 1000 break; srand(count); } printf("the allcated memory size of biggest chunk is %d byte\n", max_eax); printf("the string inside that chunk is %s\n", max_eax_str); printf("log in to pwnable.kr and anwer some question to get flag.\n"); sub_3440B1(); return 0; }

這是把F5以後的反編譯程序,加上自己的理解改成了這個樣子。

這個是一個循環申請內存空間,並隨機填充16個a~Z0~9字符的程序,循環次數為1000次。

每次循環後,找到申請空間最大的那次,並打印出來。

上面最重要的是random_function變量,它的結果是下圖這些sub_*的函數,內容就是根據現在的執行上下文生成一個隨機數。

技術分享

由於上面代碼中用的隨機函數都是偽隨機,或者種子固定,因此,每次運行該程序,申請的大小、字符串的添加都是一樣的。

而題目中給的提示,EAX、EBX是執行的結果,其中EAX存儲的是申請內存的大小、EBX存儲一個char指針,指向填充的字符串。

做了以上分析之後,可以想出解決思路,每次在該位置下斷點,獲取EAX、EBX的內容,最後做刪選即可。

而通過服務器上所給的提示,隨後需要提交第二、第三大分配內存塊所填充的字符串內容。

由於做了1000次循環,因此人工尋找幾乎不可能。

還好ida工具有ida 腳本這樣一種工具,可以動態獲取指定內容。

可以編寫ida腳本來完成查找。我使用了IDA Python這一工具。其實和idc基本相同。

思路就是下斷點——獲取EAX\EBX的值,最終進行比較,由於沒想到好的排序算法,就直接采用最簡單粗暴的方法

腳本如下,另外每次程序加載到內存中的位置不同,使用時應修改添加斷點的內存地址。

from idaapi import *  
from idc import *  
import os

count = 0
eax_list = list()
ebx_list = list()

  
try:
    if debugger:
        print("Removing previous hook ...")
        debugger.unhook()
except:
    pass
AddBpt (0x403e65)
print "[*] set hook OK...\n"
StartDebugger("","","")  
for i in range(0,999):
    GetDebuggerEvent(WFNE_SUSP|WFNE_CONT, -1)
    print "[+]",i
    eax = GetRegValue("EAX")
    eax_list.append(eax)
    ebx = GetRegValue("EBX")
    ebx_list.append(ebx)
    if i == 998:
        print [+] eax max : ,max(eax_list)
        index = eax_list.index(max(eax_list))
        a = ebx_list[index]
        #message( "[+] ebx max : %x",%(ebx_list[eax_list.index(max(eax_list))]))
        Message("%x"%a)
        print "max",GetString(a)
        del(eax_list[index])
        del(ebx_list[index])
#        
        print [+] eax second : ,max(eax_list)
        index = eax_list.index(max(eax_list))
        a = ebx_list[index]
        #message( "[+] ebx max : %x",%(ebx_list[eax_list.index(max(eax_list))]))
        Message("%x"%a)
        print "second",GetString(a)
        del(eax_list[index])
        del(ebx_list[index])        
#        
        print [+] eax third : ,max(eax_list)
        index = eax_list.index(max(eax_list))
        a = ebx_list[index]
        #message( "[+] ebx max : %x",%(ebx_list[eax_list.index(max(eax_list))]))
        Message("%x"%a)
        print "third",GetString(a)
        del(eax_list[index])
        del(ebx_list[index])

最終,運行的結果如下:

技術分享

nc 0 9021輸入字符串之後可以獲得該題的flag:

技術分享

【pwnable.kr】 codemap