2011-08-18 32 views
2

我正在做一些計算機安全研究,並且我正在嘗試瞭解字符串格式漏洞。我運行包含此代碼的程序:當我養活程序的參數「。%08X%08X%08X%08X%08X」(這被讀入「數據」直接參數訪問不起作用,在C中使用printf

char buf[1<<5]; 
strncpy(buf, data, sizeof(buf)); 
buf[sizeof(buf)-1]='\0'; 
fprintf(stderr, buf); 

變量),我得到的輸出: 00000020.b7fd7560.08048b09.00000019.78383025

據我所知,每個十六進制數字彈出堆棧,「78383025」來自緩衝區本身。所以有4個字--16個字節 - 在我開始緩衝之前我必須彈出。

當我給出參數`perl -e 'print "\x2a\xf9\xff\xbf%08x.%08x.%08x.%08x_%s_";'`時,%s部分打印位於內存地址0xbffff92a的字符串。

現在,我想這樣做,使用直接參數訪問。如果我給程序提供參數`perl -e 'print "\x2a\xf9\xff\xbf%16$s";'`,我應該期望程序執行與上面相同的操作。但是所有程序打印都是緩衝區開始處的四個字符。那麼,什麼產生?我使用DPA錯誤的語法? 我使用的是Ubuntu 9.04,32位的方式。

下面是一些編譯代碼,不能保證雖然產生相同的結果:

#include <stdio.h> 

void run(const char* data) { 
    char buf[1<<5]; 
    strncpy(buf, data, sizeof(buf)); 
    buf[sizeof(buf) - 1] = '\0'; 
    fprintf(stderr, buf); 
} 

int main(int argc, char* argv[]) { 
    run(argv[1]); 
    return 0; 
} 
+0

我假設你的意思'的perl -e '打印 「\ X 2 A \ xf9 \ XFF \ XBF%,16 $的」;''(注意'''字是'print'之前)?這是一個錯字嗎? –

+0

您能否發佈重現問題的最小可編譯代碼?現在很難理解它。 –

+0

對不起,我在這個問題上犯了一個錯字。 –

回答

4

%16$s指格式字符串之後的16個參數,並告訴printf把它解釋爲一個char*和顯示它作爲一個字符串。

你似乎在獲取字符串之前用它作爲跳過16個字節的手段,這不完全是一回事。

既然你想要的5個參數,嘗試更多的東西像這樣的格式字符串:由於您使用的perl -e 'print "...";'傳遞數據

"\x2a\xf9\xff\xbf%5$s" 

,你將不得不逃離$字符。 IE瀏覽器。 :

./a.out `perl -e 'print "\x2a\xf9\xff\xbf%5\\\$s";'` 
+0

我實際上已經嘗試了從%1 $ s到%24 $ s的所有內容,而這些內容都沒有從內存中打印出任何東西。 –

+0

但我認爲你說得對,它應該是%5 $ s,因爲如果你不給printf任何參數,它可能只是將棧上的數據作爲單詞來處理。所以第五個字是我的地址0xbffff92a。 –

+0

更新了我的答案,以反映您傳遞格式字符串的方式......您需要正確地轉義'$'字符。 –