nimrod
05.03.2007, 17:16
Moin
beim Durcharbeiten von diesem (http://tty64.org/doc/smackthestack.txt) Paper bin ich auf folgendes gestoszen, was ich mir nicht erklaeren kann:
Ausgegangen wird von folgendem Programm:
/*
* vuln.c, Standard strcpy() buffer overflow within a function
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int foobar(int x, char *str) {
char buf[256];
strcpy(buf, str);
return x;
}
int main(int argc, char **argv) {
foobar(64, argv[1]);
return 1;
}
Uebersetzt habe ich es mit gcc-3.4.6 (std. Paket von Gentoo). Kernel ist 2.6.18 (Gentoo gepatcht) und mein Prozessor n amd athlon thunderbird c.
Meine gdb Session (auf das Wichtigste gekuerzt):
(bho@phuq:~/foobar)% gdb vuln2_1
GNU gdb 6.6
[...]
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disas foobar
Dump of assembler code for function foobar:
0x08048394 <foobar+0>: push %ebp
[...]
0x080483b5 <foobar+33>: leave
0x080483b6 <foobar+34>: ret
End of assembler dump.
(gdb) b *foobar+34
Breakpoint 1 at 0x80483b6
(gdb) set args abc
(gdb) r
Starting program: /home/bho/vortex/vuln2_1 abc
Failed to read a valid object file image from memory.
Breakpoint 1, 0x080483b6 in foobar ()
(gdb) disas __do_global_ctors_aux
Dump of assembler code for function __do_global_ctors_aux:
0x08048480 <__do_global_ctors_aux+0>: push %ebp
[...]
0x080484a0 <__do_global_ctors_aux+32>: pop %ebx
0x080484a1 <__do_global_ctors_aux+33>: pop %ebp
0x080484a2 <__do_global_ctors_aux+34>: ret
0x080484a3 <__do_global_ctors_aux+35>: nop
End of assembler dump.
(gdb) x/a $esp
0xbfcc763c: 0x80483eb <main+52>
(gdb) set *0xbfcc763c = __do_global_ctors_aux+33
(gdb) x/a $esp+4
0xbfcc7640: 0x40
(gdb) x/a $esp+8
0xbfcc7644: 0xbfcc93dd
(gdb) nexti
0x080484a1 in __do_global_ctors_aux ()
(gdb) nexti
Cannot access memory at address 0x44
(gdb) print (void *)$ebp
$1 = (void *) 0x40
(gdb) print (void *)$esp
$2 = (void *) 0xbfcc7644
So, was passiert da?
Ich setz den Top of Stack auf die Adresse __do_global_ctors_aux+33.
ret holt sich die jetzt vom Stack und setzt %eip drauf. %esp ist jetzt also %esp+4. Soweit alles wie erwartet.
Das pop %ebp sorgt dafuer, dass %ebp = 0x40 ist.
Und dann wird's komisch. Wenn mich nicht alles taeuscht, sollte sich das ret jetzt ganz brav (%esp) vom Stack holen und da hin Springen (gut, da steht jetzt abc (argv[1]), aber es koennte der Shellcode sein..).
Stattdessen kommt der Fehler 'Cannot access memory at address 0x44', was ich mir nur so erklaeren kann, dass er versucht nach %ebp+4 zu springen, was natuerlich totaler Schwachsinn ist. Oder?
Ich geh mal davon aus, dass ich irgendwo nen boesen Denkfehler habe. Waer nett, wenn mich jemand in die richtige Richtung stoszen koennte ;)
Grusz Bho
ps: Ich war mir mit dem Forum nicht sicher. Wenns besser nach 'Systemnahe Programmierung' passt bitte verschieben.
pps: Uebersetzt habe ich das Programm mit 'gcc -o vuln vuln.c'. Die Binary habe ich angehaengt (die .txt Endung darf ignoriert werden ;))
beim Durcharbeiten von diesem (http://tty64.org/doc/smackthestack.txt) Paper bin ich auf folgendes gestoszen, was ich mir nicht erklaeren kann:
Ausgegangen wird von folgendem Programm:
/*
* vuln.c, Standard strcpy() buffer overflow within a function
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int foobar(int x, char *str) {
char buf[256];
strcpy(buf, str);
return x;
}
int main(int argc, char **argv) {
foobar(64, argv[1]);
return 1;
}
Uebersetzt habe ich es mit gcc-3.4.6 (std. Paket von Gentoo). Kernel ist 2.6.18 (Gentoo gepatcht) und mein Prozessor n amd athlon thunderbird c.
Meine gdb Session (auf das Wichtigste gekuerzt):
(bho@phuq:~/foobar)% gdb vuln2_1
GNU gdb 6.6
[...]
This GDB was configured as "i686-pc-linux-gnu"...
Using host libthread_db library "/lib/libthread_db.so.1".
(gdb) disas foobar
Dump of assembler code for function foobar:
0x08048394 <foobar+0>: push %ebp
[...]
0x080483b5 <foobar+33>: leave
0x080483b6 <foobar+34>: ret
End of assembler dump.
(gdb) b *foobar+34
Breakpoint 1 at 0x80483b6
(gdb) set args abc
(gdb) r
Starting program: /home/bho/vortex/vuln2_1 abc
Failed to read a valid object file image from memory.
Breakpoint 1, 0x080483b6 in foobar ()
(gdb) disas __do_global_ctors_aux
Dump of assembler code for function __do_global_ctors_aux:
0x08048480 <__do_global_ctors_aux+0>: push %ebp
[...]
0x080484a0 <__do_global_ctors_aux+32>: pop %ebx
0x080484a1 <__do_global_ctors_aux+33>: pop %ebp
0x080484a2 <__do_global_ctors_aux+34>: ret
0x080484a3 <__do_global_ctors_aux+35>: nop
End of assembler dump.
(gdb) x/a $esp
0xbfcc763c: 0x80483eb <main+52>
(gdb) set *0xbfcc763c = __do_global_ctors_aux+33
(gdb) x/a $esp+4
0xbfcc7640: 0x40
(gdb) x/a $esp+8
0xbfcc7644: 0xbfcc93dd
(gdb) nexti
0x080484a1 in __do_global_ctors_aux ()
(gdb) nexti
Cannot access memory at address 0x44
(gdb) print (void *)$ebp
$1 = (void *) 0x40
(gdb) print (void *)$esp
$2 = (void *) 0xbfcc7644
So, was passiert da?
Ich setz den Top of Stack auf die Adresse __do_global_ctors_aux+33.
ret holt sich die jetzt vom Stack und setzt %eip drauf. %esp ist jetzt also %esp+4. Soweit alles wie erwartet.
Das pop %ebp sorgt dafuer, dass %ebp = 0x40 ist.
Und dann wird's komisch. Wenn mich nicht alles taeuscht, sollte sich das ret jetzt ganz brav (%esp) vom Stack holen und da hin Springen (gut, da steht jetzt abc (argv[1]), aber es koennte der Shellcode sein..).
Stattdessen kommt der Fehler 'Cannot access memory at address 0x44', was ich mir nur so erklaeren kann, dass er versucht nach %ebp+4 zu springen, was natuerlich totaler Schwachsinn ist. Oder?
Ich geh mal davon aus, dass ich irgendwo nen boesen Denkfehler habe. Waer nett, wenn mich jemand in die richtige Richtung stoszen koennte ;)
Grusz Bho
ps: Ich war mir mit dem Forum nicht sicher. Wenns besser nach 'Systemnahe Programmierung' passt bitte verschieben.
pps: Uebersetzt habe ich das Programm mit 'gcc -o vuln vuln.c'. Die Binary habe ich angehaengt (die .txt Endung darf ignoriert werden ;))