2014-02-08 48 views
1

我有一個程序,看起來像這樣32位Intel棧幀格式串漏洞

測試程序:

#include <stdio.h> 

void foo(char *input) 
{ 
    char buffer[64]; 
    strncpy(buffer, input, sizeof(buffer)); 
    printf(buffer); 
} 

int main(int argc, char **argv) 
{ 
    foo(argv[1]); 
} 

我編譯我的程序與所有堆棧相關的保護關閉。

GCC fmthck.c -w -m32 -O0 -ggdb -std = C99 -static -D_FORTIFY_SOURCE = 0 -fno餡餅-Wno格式-Wno格式的安全-fno堆疊保護器-z norelro -z execstack -o黑客

須藤的sysctl -w kernel.randomize_va_space = 0

然後我公司供應的編譯後的程序使用以下參數:

./hacks「AAAA%p %p%p%p%p%p%p%p%p%p%p「

而且我得到的輸出看起來像這樣

AAAA 0xffffd3cb 0x40的0x8048d3c 0x41414141 0x2e702520 0x252e7025 0x70252e70 0x2e70252e 0x252e7025 0x70252e70

我知道,在HEX A = 0×41。所以我猜測緩衝區的起始地址對應於第4%p。 我只是想知道它周圍的東西是什麼意思。我被給了一個看起來像這樣的堆棧圖。我知道,0x8048d3c對應於返回地址,但有些東西不排隊

高的內存地址

  • 輸入參數
  • 返回地址
  • 保存的幀指針
  • 局部變量
  • 保存的寄存器

低內存地址

有人請詳細說明發生了什麼事情,因爲我這樣做?

回答

2

如果使用選項-S編譯程序,編譯器將生成可檢查的程序集輸出。在你的情況下,相關生成的代碼是:

foo: 
    pushl %ebp 
    movl %esp, %ebp 
    subl $88, %esp 
    movl $64, 8(%esp) 
    movl 8(%ebp), %eax 
    movl %eax, 4(%esp) 
    leal -72(%ebp), %eax 
    movl %eax, (%esp) 
    call strncpy 
    leal -72(%ebp), %eax 
    movl %eax, (%esp) 
    call printf 

你的輸出是

AAAA 0xffffd3cb 0x40 0x8048d3c 0x41414141 0x2e702520 0x252e7025 0x70252e70 0x2e70252e 0x252e7025 0x70252e70 

其中有被解釋爲在printf調用的時刻一塊系統堆棧。輸出的含義是:

AAAA  == string from argument printed by printf 
0xffffd3cb == garbage left from previous function invocation, in fact the input argument argv[1] previously sent to `strncpy` 
0x40  == garbage left from previous function invocation, in fact it is the constant 64 previously sent to strncpy 
0x8048d3c == ??? I don't know why gcc left this unused space. 
0x41414141 0x2e70252 ... is the content of local variable `buffer` which contains the string "AAAA %p %p %p %p %p %p %p %p %p %p". 

函數的返回地址以及保存的基指針超出了您的輸出。