是的,很多類似的問題已經存在(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
?也許這個例子畢竟不是最簡單的...
我感到困惑。有任何想法嗎?
事實上,由於'printf'的參數將被壓入堆棧,返回地址的地址會根據您的輸入而改變。然後,您的格式字符串必須「消耗」與自身一樣多的字節,再加上返回地址以外的所有內容。 –
你可能舉一個具體的例子,假設例如一個50字節的shellcode並且沒有NOP? –
http://stackoverflow.com/questions/7459630/how-can-a-format-string-vulnerability-be-exploited –