2012-04-19 12 views
0

嗨我想寫一個溢出漏洞利用我已經建立的一個簡單的程序。貝婁是我寫的C程序。重寫EBP棧返回值

#include <unistd.h> 
#include <string.h> 
#include <stdio.h> 

char *string_in = "Did not work"; 

int test(char *this){ 
char sum_buf[6]; 
strncpy(sum_buf,this,24); 
return 0; 
} 

void hello(){ 
printf("hello man"); 
string_in = "If this triggered, it means our shell code is working\n"; 
return; 
} 

int main(int argc, void **argv){ 

test("\x00\x40\x06\x02"); 
printf("My string is %s",string_in); 
return 0; 

} 

基本上發生的事情是該字符串是假設在一個覆蓋EBP具有0x00400602的價值,這是我的hello()函數的返回地址進行讀取。我知道這是自函數hello以來objdump -d test_stack.o的地址值。從對象轉儲,我可以告訴大家,RSP已提前20個字節,如圖波紋管

00000000004005b4 <test>: 
    4005b4: 55      push %rbp 
    4005b5: 48 89 e5    mov %rsp,%rbp 
    4005b8: 48 83 ec 20    sub $0x20,%rsp 
    4005bc: 48 89 7d e8    mov %rdi,-0x18(%rbp) 
    4005c0: 64 48 8b 04 25 28 00 mov %fs:0x28,%rax 
    4005c7: 00 00 
    4005c9: 48 89 45 f8    mov %rax,-0x8(%rbp) 
    4005cd: 31 c0     xor %eax,%eax 
    4005cf: 48 8b 4d e8    mov -0x18(%rbp),%rcx 
    4005d3: 48 8d 45 f0    lea -0x10(%rbp),%rax 
    4005d7: ba 18 00 00 00   mov $0x18,%edx 
    4005dc: 48 89 ce    mov %rcx,%rsi 
    4005df: 48 89 c7    mov %rax,%rdi 
    4005e2: e8 a9 fe ff ff   callq 400490 <[email protected]> 
    4005e7: b8 00 00 00 00   mov $0x0,%eax 
    4005ec: 48 8b 55 f8    mov -0x8(%rbp),%rdx 
    4005f0: 64 48 33 14 25 28 00 xor %fs:0x28,%rdx 
    4005f7: 00 00 
    4005f9: 74 05     je  400600 <test+0x4c> 
    4005fb: e8 a0 fe ff ff   callq 4004a0 <[email protected]> 
    400600: c9      leaveq 
    400601: c3      retq 

0000000000400602 <hello>: 
    400602: 55      push %rbp 
    400603: 48 89 e5    mov %rsp,%rbp 
    400606: b8 6d 07 40 00   mov $0x40076d,%eax 
    40060b: 48 89 c7    mov %rax,%rdi 
    40060e: b8 00 00 00 00   mov $0x0,%eax 
    400613: e8 98 fe ff ff   callq 4004b0 <[email protected]> 
    400618: 48 c7 05 0d 0a 20 00 movq $0x400778,0x200a0d(%rip)  # 

由於子$ 20,%RSP我知道我需要寫ATLEAST 20個字節......但我不知道我還需要寫多少才能到達我的rbp。它可能來自我的calq's,我需要寫8或我的字節,因爲有2個電話。雖然我真的不知道我需要寫多少。

我編譯我的程序是這樣的...

gcc -g stack.c -o test_stack.o 
execstack -s test_stack.o 

由於我使用Ubuntu 11,我的內核版本爲3.0.17一樣,所以我知道我的ASLR默認是開啓的。我可能需要關閉它,但我不知道該怎麼做。另外我正在運行一個i386:x86_64。我可以告訴我的堆棧在運行過程中的樣子嗎?我怎樣才能使這個工作,我怎麼找到我需要寫多少?

感謝您的幫助

+0

我看到的一個問題是,您沒有使用足夠的字節作爲函數的地址。你需要32位:'\ x00 \ x40 \ x06 \ x01'。另外,我認爲你可能需要顛倒這些字節的順序,因爲x86在內存中將0x00400601存儲爲0x01,0x06,0x40,0x00。最後,我不知道我的建議是否會有所幫助。它的類型取決於gcc創建棧幀的方式。您最好在調試器中單步執行,以便您可以看到發生了什麼。 – 2012-04-19 22:16:33

+0

你的權利,我忘了輸入最後一個字節。謝謝,我會看看這是否有效。 – 2012-04-19 22:42:48

+0

大聲笑,現在我沒有得到一個stackoverflow錯誤。棒極了!但不管出於什麼原因它不是printf()。 – 2012-04-19 22:53:28

回答

0

那麼第一個問題是,我過了關棧上-fno-堆棧保護標誌保護。一旦我做到了,覆蓋我的緩衝區變得更容易。第二個問題是,即使字符串被讀取並以小端存儲,操作碼和操作數似乎也被解釋爲大端。我不明白爲什麼會這樣。最後,我不想覆蓋EBP堆棧框架......這是我函數的返回地址。這意味着,我不需要寫24字節,而是需要有效地覆蓋32個字節。我終於得到了該計劃的工作!