Pwn學習隨筆

Pwn題做題流程

  • 使用checksec檢查ELF文件保護開啟的狀態
  • IDApro逆向分析程序漏洞(邏輯復雜的可以使用動態調試)
  • 編寫python的exp腳本進行攻擊
    • (若攻擊不成功)進行GDB動態調試,查找原因
    • (若攻擊成功)獲取flag , 編寫Writeup
一般都會在C代碼開頭設置setbuf(stdout, 0)表示設置printf緩沖區為0,有就輸出而不是等到輸出\n時一塊輸出
ebp + 0x4 存放函數中第一個局部變量,ebp - 0x4是返回地址ebp - 0x8 存放函數第一個參數
棧幀基本知識
Pwn學習隨筆

文章插圖
下面解釋一下下面的匯編代碼(AT&T格式) , 
首先push %ebp,保存調用者的調用者的ebp寄存器,move %esp, %ebp開始創建caller函數的棧幀,然后sub $0x10, %esp,在32位程序下是4字節對齊的,將esp指針向下移動16字節(參數占12字節 , 局部變量4字節),即四格,此時esp指向3上面的地址,
然后將callee函數的參數入棧(cdecl從右往左入棧),然后調用call callee,call指令其實是兩條指令 , 先push esp + 0xc , 將返回地址壓棧,然后jmp 00000000跳到callee函數的位置開始執行,然后同樣的操作,先將caller函數的ebp寄存器壓棧,然后mov esp. ebp開始創建callee函數的棧幀,之后開始callee函數的計算功能,取出之前入棧的參數進行加法操作 。執行完后將棧中保存的caller函數ebp寄存器的內容再popebp寄存器,此時ebp指向最上面的位置 。然后esp - 4,上移一格 。最后執行ret指令 , 其實也是兩條指令 , pop eipcaller調用callee函數之前入棧的返回地址popeip , 下一步就執行該地址 。然后esp + 4,回到caller函數的棧幀 , 可以看到首先是add $0xc, %esp , 將棧頂指針提升到3上面的位置 , 然后mov %eax, -0x4(%ebp) , 意思就是將eax寄存器的值 (callee的返回值) 賦給ebp-4的位置,即caller函數的局部變量ret , 然后addl $0x4,-0x4(%ebp)將局部變量ret的值 + 4 , 最后再把局部變量賦給eax寄存區準備返回
Pwn學習隨筆

文章插圖
call指令執行完后 , 會在esp中存儲返回地址0x401171 = 0x40116c + 4 , 
Pwn學習隨筆

文章插圖
進入函數內部后 , 需要首先執行push ebp,保存調用它的函數的棧幀 。然后ebp = esp,提升棧底,準備創建本函數的棧幀,
sub esp, 50,會將esp的位置往上提升0x40 / 4 = 0x10即16格,然后push ebx | esi | edi保存現場到堆棧中,lea edi, dword ptr ss:[ebp-40]取地址編號賦給ediedi = esp + 3*0x4,下面三條之路是一組,stos用于將eax的值存儲到edi的地址編號中,ecx記錄執行次數 。每執行一次,ecx - 1, edi + 4(df位為0)或者edi - 4(df位為1) 。ccccccccint 3的硬編碼int 3是端點,這樣做為了防止緩沖區溢出,未到的棧空間都被設置為cccccccc,CPU執行遇到這里就會將程序停下來了 。下一步mov eax, dword ptr ss:[ebp+8]是函數的第二個參數,ebp+c是函數的第一個參數,這兩步執行了關鍵操作 2 + 1 = 3此時函數功能就完成了,下面就是恢復現場了,pop edi,可分為兩步,mov edi, espadd esp,4,先push的后pop然后執行mov, esp, ebp,即將棧指針esp下降到之前sub執行前的位置,棧中的數據并沒有清除
然后pop ebp,即將0x12ff30賦給ebp然后esp + 4,最后執行retn,相當于pop eipmov eip, 401171然后esp + 4,這個地址就很關鍵了,這就是我們在pwn中經常覆蓋的返回地址 。然后返回到調用者中執行 , 但是需要注意此時

推薦閱讀