Search code examples
cbuffer-overflowshellcodestack-smash

Can't figure out a smashing stack segment fault


I am doing some smashing stack practice recently with the book "shellcoder's handbook".
But when I try to test some code on my Ubuntu11.04 I always get a segment fault.
Here's the situation:

At first I write exit_shellcode.s (just the simple exit(0) function):

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

then I get the hex code:

0x000001b8 0x0000bb00 0x80cd0000

After that I make the 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();
}

compile: gcc -mpreferred-stack-boundary=2 -ggdb -fno-stack-protector -o wack wack.c

But segment fault received when I run it.

Here's gdb result:

(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.

The shellcode array

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

In f, the ebp and 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

After some si, ret=0x0804a010, which is the address of shellcode array.

(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

Segment fault after some si, which I can't understand.

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

Can you please help me?


Solution

  • You have done everything correctly; your issue is that shellcode is placed in the .data ELF section, and in modern systems .data are allocated and placed in non-executable pages. Try this to clear the NX flag:

    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 is a tool to query and modify the executable stack flag of ELF binaries)

    To further understand the various protection mechanisms in modern OSs, I'd suggest you start here and perhaps read Mariano Graziano and Andrea Cugliari's paper "Smashing the stack in 2010".