緩沖區溢出實驗 5 Snprintf


實驗環境、代碼、及准備

 https://www.cnblogs.com/lqerio/p/12870834.html

 vul5

 

 

 

Snprintf函數,百度百科:

將可變個參數(...)按照format格式化成字符串,然后將其復制到str中。

(1) 如果格式化后的字符串長度 < size,則將此字符串全部復制到str中,並給其后添加一個字符串結束符('\0');

(2) 如果格式化后的字符串長度 >= size,則只將其中的(size-1)個字符復制到str中,並給其后添加一個字符串結束符('\0'),返回值為欲寫入的字符串長度。

查閱資料可知:

snprintf(buf, sizeof buf, arg);

snprintf()函數,該函數的作用為將第三個參數生成的格式化字符串拷貝到第一個參數中,拷貝的大小由第二個參數進行設置。並且其會根據格式化字符串的形式進行替換:在遇到格式化字符串參數之前,它會先將字符拷貝,當遇到格式化字符參數時,該函數會對指定的格式化字符進行替換。

%n:將%n之前printf已經打印的字符個數賦值給偏移處指針所指向的地址位置,如%100×10$n表示將0x64寫入偏移10處保存的指針所指向的地址(4字節),而%$hn表示寫入的地址空間為2字節,%$hhn表示寫入的地址空間為1字節

格式參考了:

https://blog.csdn.net/u010517901/article/details/46486341

https://blog.csdn.net/qq_36779888/article/details/89684453

故此次溢出的構造應該是構造合適的arg,從而構造合適的參數(%n),從而修改snprintf函數的返回地址,跳轉到payload。

 

 

shellcode(構造過程)

原理是運行/bin/sh 來得到shell,構造過程是將具有運行/bin/sh的C代碼轉換成有相同功能的機器碼。注意代碼中用到  0  的地方改成用 xor  eax,eax,這樣可以避免復制字符串時遇到/0 中斷。

下面的shellcode長度為45字節(不含/0)

 

/*

 * Aleph One shellcode.

 */

static const char shellcode[] =

  "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b"

  "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd"

  "\x80\xe8\xdc\xff\xff\xff/bin/sh";

 

exploit5

 

Gdb /tmp/vul5

Disas foo

 

 

 

0x80484cb 0x80484e3

先構造一個簡單的payload,用做測試

 

 

 

gdb -e exploit5 -s /tmp/vul5

catch exec

r

break *0x80484cb

c

 

 

 

此時剛剛進入fooebpbuf地址分別為

 

 

 

B snprintf

 

 

此時disas查看snprintf的匯編

 

 

查看此時的,ebp,esp及其內容,可見snprintf沒有改變ebp,而esp(0xbffffb2c)指向的是0x80484e8,是snprintf的返回地址(下一條指令),所以我們只要構造合適的payload,覆蓋0xbffffb2c中的返回地址,使其指向我們的payload即可。

 

 

 

 

 

所以payload需要使用合適的參數修改esp(0xbffffb2c)的值。能修改的參數只有%n,寫入的數據是已經輸出的字符數,所以只需要構造合適的數目的字符就可以修改為指定地址。(比如40個字符,就寫入0x28)

Vul5中,Snprintf用到%u參數時不斷的修改buf,所以返回的地址不能是buf,那么只能是arg。

查看arg的地址:重新gdb調試,在foo break查看

為 0xbffffcd4,而buf地址在0xbffffb3c,相差408字節,為了不覆蓋到arg,payload需要不超過408字節。(這里我覺得其實snprintf限制了不超過buf的400字節了)

 

 

 

 

考慮到添加一些nop,最終返回地址可以是&arg+0x40=0xbffffd14

字符串長度不應該過長,所以每次修改esp指向的一字節。比如往esp(0xbffffb2c)寫入0xbffffcf4的f4,需要有16*f+4=244個字符

寫fc需要252個字符,ff需要255字符,最后的bf,需要191個字符

 

修改地址的payload部分為

 

 

然后填nop和shellcode即可

然后這樣出了問題,總是跳到一個隨機的地址

 

 

 

 

Gdb調試,發現是arg的地址出錯。是0xbffffe62

 

 

目標地址改為 0xbffffea2即可

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM