2

我最近在用“shellcoder's handbook”一书做一些非常棒的堆栈练习。
但是当我尝试在我的 Ubuntu11.04 上测试一些代码时,我总是会遇到段错误。
情况如下:

起初我写了 exit_shellcode.s (只是简单的 exit(0) 函数):

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

然后我得到十六进制代码:

0x000001b8 0x0000bb00 0x80cd0000

之后我制作了 wack.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-stack-boundary=2 -ggdb -fno-stack-protector -o wack 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.

shellcode 数组

(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

在一些 si 之后出现段错误,我无法理解。

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

你能帮我么?

4

1 回答 1

4

你做的一切都是正确的;您的问题是shellcode放置在.dataELF 部分中,并且在现代系统.data中被分配并放置在不可执行的页面中。试试这个来清除 NX 标志:

vmuser@ubuntu:~$ sudo apt-get update
vmuser@ubuntu:~$ sudo apt-get install execstack
vmuser@ubuntu:~$ execstack -s ./wack
vmuser@ubuntu:~$ ./wack
vmuser@ubuntu:~$ echo $?

execstack是查询和修改ELF二进制文件的可执行堆栈标志的工具)

为了进一步了解现代操作系统中的各种保护机制,我建议您从这里开始,也许可以阅读 Mariano Graziano 和 Andrea Cugliari 的论文“ Smashing the stack in 2010 ”。

于 2012-04-12T19:10:41.913 回答