2012-04-12 37 views
2

最近我正在用「shellcoder's handbook」一書進行一些粉碎堆棧實踐。
但是,當我嘗試在我的Ubuntu11.04上測試一些代碼時,我總是遇到段錯誤。
這裏的情況:找不到一個粉碎的堆棧段錯誤

起初我寫exit_shellcode.s(只是簡單的出口(0)函數):

.section .text 
.globl _start 
_start: 
movl $1, %eax 
movl $0, %ebx 
int $0x80 <br> 

然後我得到的十六進制代碼:

0x000001b8 0x0000bb00 0x80cd0000 

後我製造怪物:c:

char shellcode[] = "\xb8\x01\x00\x00\x00\xbb\x00\x00\x00\x00\xcd\x80"; 
void f(void) 
{ 
    int *ret; 
    ret = (int *)&ret + 2; 
    (* ret) = (int)shellcode; 
} 

void main (void) 
{ 
    f(); 
} 

編譯:GCC -mpreferred堆疊邊界= 2 -ggdb -fno堆疊保護器-o怪人wack.c

但是接收的段故障時我運行它。

這裏的gdb的結果:

(gdb) disas main 
Dump of assembler code for function main: 
    0x080483af <+0>: push %ebp 
    0x080483b0 <+1>: mov %esp,%ebp 
    0x080483b2 <+3>: call 0x8048394 <f> 
    0x080483b7 <+8>: pop %ebp 
    0x080483b8 <+9>: ret 
End of assembler dump. 

(gdb) disas f 
Dump of assembler code for function f: 
    0x08048394 <+0>: push %ebp 
    0x08048395 <+1>: mov %esp,%ebp 
    0x08048397 <+3>: sub $0x4,%esp 
    0x0804839a <+6>: lea -0x4(%ebp),%eax 
    0x0804839d <+9>: add $0x8,%eax 
    0x080483a0 <+12>: mov %eax,-0x4(%ebp) 
    0x080483a3 <+15>: mov -0x4(%ebp),%eax 
    0x080483a6 <+18>: mov $0x804a010,%edx 
    0x080483ab <+23>: mov %edx,(%eax) 
    0x080483ad <+25>: leave 
    0x080483ae <+26>: ret 
End of assembler dump. 

殼碼陣列

(gdb) x/20x 0x804a010 
0x804a010 <shellcode>: 0x000001b8 0x0000bb00 0x80cd0000 0x00000000 

在F中,EBP和RET = 0x080483b7

(gdb) x/20x $ebp 
0xbffff2c0: 0xbffff2c8 0x080483b7 0xbffff348 0x00145e37 
0xbffff2d0: 0x00000001 0xbffff374 0xbffff37c 0x0012e414 
0xbffff2e0: 0xffffffff 0x0012cff4 0x08048215 0x00000001 
0xbffff2f0: 0xbffff330 0x0011da51 0x0012dad0 0xb7fffb48 
0xbffff300: 0x00000001 0x0028cff4 0x00000000 0x00000000 

一些SI後,RET = 0x0804a010,其是shellcode數組的地址。

(gdb) x/20x $ebp 
0xbffff2c0: 0xbffff2c8 0x0804a010 0xbffff348 0x00145e37 
0xbffff2d0: 0x00000001 0xbffff374 0xbffff37c 0x0012e414 
0xbffff2e0: 0xffffffff 0x0012cff4 0x08048215 0x00000001 
0xbffff2f0: 0xbffff330 0x0011da51 0x0012dad0 0xb7fffb48 
0xbffff300: 0x00000001 0x0028cff4 0x00000000 0x00000000 

一段時間後的段故障,我不明白。

Program received signal SIGSEGV, Segmentation fault. 
0x080483ae in f() at wack.c:8 

你能幫我嗎?

+0

試圖重現您的問題 - shellcode看起來不錯,我使用gcc 4.4.5(Debian 4.4.5-8)在Debian 6.0.3上編譯了您使用的選項,在我的情況下,一切正常。你是否嘗試編譯並在另一臺機器上運行它? – Rob 2012-04-12 18:17:24

+0

我懷疑這是如此簡單,但如果使用'int * ret = malloc(sizeof(int))'(或任何你需要的大小)會發生什麼。 – twain249 2012-04-12 18:22:46

+0

不,我只是使用Ubuntu 11.04。@ Rob – KUN 2012-04-12 18:24:14

回答

4

你已經正確地做了一切;你的問題是shellcode被放置在.data ELF部分,而現代系統.data被分配並放置在不可執行的頁面中。試試這個清除NX標誌:

[email protected]:~$ sudo apt-get update 
[email protected]:~$ sudo apt-get install execstack 
[email protected]:~$ execstack -s ./wack 
[email protected]:~$ ./wack 
[email protected]:~$ echo $? 

execstack是查詢和修改ELF二進制文件的可執行堆棧標誌的工具)

爲了進一步瞭解各種保護機制在現代操作系統,我建議你開始here,也許閱讀Mariano Graziano和Andrea Cugliari的論文「Smashing the stack in 2010」。

+0

非常感謝!@Michael Foukarakis – KUN 2012-04-13 01:31:53