elhacker.net cabecera Bienvenido(a), Visitante. Por favor Ingresar o Registrarse
¿Perdiste tu email de activación?.
 
Inicio Ayuda Buscar Ingresar Registrarse
25 Mayo 2012, 17:01  


Tema destacado: Recuerda que debes registrarte en el foro para poder participar (preguntar y responder)

+  Foro de elhacker.net
|-+  Seguridad Informática
| |-+  Bugs y Exploits (Moderador: berz3k)
| | |-+  Segmentation fault al cambiar dirección de retorno
0 Usuarios y 1 Visitante están viendo este tema.
Páginas: [1] Ir Abajo Respuesta Imprimir
Autor Tema: Segmentation fault al cambiar dirección de retorno  (Leído 1,769 veces)
Nork

Desconectado Desconectado

Mensajes: 195



Ver Perfil
Segmentation fault al cambiar dirección de retorno
« en: 4 Febrero 2010, 00:05 »

Buenas!,
Pues tengo un problema al intentar cambiar la dirección de retorno de la pila en un  buffer overflow. El código que tengo es éste:

Código
void function(int a, int b, int c) {
       char buffer1[5];
       char buffer2[10];
       int *ret;
 
       ret = buffer1 + 12;
       (*ret) += 7;
}
 
void main() {
       int x;
       x = 0;
       function(1,2,3);
       x = 1;
       printf("%d\n", x);
}

Por si a alguien le suena es del artículo smashing the stack for fun and profit. El código que muestra el gdb en ASM es el siguiente:

Citar
Dump of assembler code for function main:
0x080483e2 <main+0>:    lea    0x4(%esp),%ecx
0x080483e6 <main+4>:    and    $0xfffffff0,%esp
0x080483e9 <main+7>:    pushl  -0x4(%ecx)
0x080483ec <main+10>:   push   %ebp
0x080483ed <main+11>:   mov    %esp,%ebp
0x080483ef <main+13>:   push   %ecx
0x080483f0 <main+14>:   sub    $0x24,%esp
0x080483f3 <main+17>:   movl   $0x0,-0x8(%ebp)
0x080483fa <main+24>:   movl   $0x3,0x8(%esp)
0x08048402 <main+32>:   movl   $0x2,0x4(%esp)
0x0804840a <main+40>:   movl   $0x1,(%esp)
0x08048411 <main+47>:   call   0x80483c4 <function>
0x08048416 <main+52>:   movl   $0x1,-0x8(%ebp)
0x0804841d <main+59>:   mov    -0x8(%ebp),%eax
0x08048420 <main+62>:   mov    %eax,0x4(%esp)
0x08048424 <main+66>:   movl   $0x8048500,(%esp)
0x0804842b <main+73>:   call   0x80482f8 <printf@plt>
0x08048430 <main+78>:   add    $0x24,%esp
0x08048433 <main+81>:   pop    %ecx
0x08048434 <main+82>:   pop    %ebp
0x08048435 <main+83>:   lea    -0x4(%ecx),%esp
0x08048438 <main+86>:   ret
End of assembler dump.

Lo que quiero conseguir es que se muestre el valor de la variable x como 0, es decir, que se salte la línea de código donde le asigna a la x el 1.

Bien, se por el código que ret tiene que apuntar a buffer1 más 12 ya que son los 8 bytes de buffer1 + 4bytes del anterior EBP.

El problema viene cuando le sumo al valor de retorno la cantidad oportuna para que me salte a 0x0804841d y no a 0x08048416. Si no me equivoco el incremento (o diferencia) sería 7, pero dejándolo así me salta el segmentation fault... por lo que el + 12 estaría bien (consigo modificar el valor de retorno) pero no consigo saber cuanto le tengo que sumar =/

Alguien tiene alguna idea??

P.D: Compilo con el parámetro -fno-stack-protector para deshabilitar la protección.

Gracias!  ;)
En línea

C' Est La Vie
E.P.I.


Desconectado Desconectado

Mensajes: 346


elprogramadorinformatico [E.P.I.]


Ver Perfil WWW
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #1 en: 4 Febrero 2010, 07:34 »

Eso no tiene que ir en programación... ?
En línea

La verdad nos hará libres
Nork

Desconectado Desconectado

Mensajes: 195



Ver Perfil
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #2 en: 4 Febrero 2010, 08:18 »

Eso no tiene que ir en programación... ?

Hombre no es una cuestión de programación... en todo caso en bugs y exploits. No sé la verdad es que no lo tenía claro y me decidí en postearlo aquí. Si eso que lo cambien no hay problema.
En línea

C' Est La Vie
AlbertoBSD
Estudiante y
Colaborador
***
Desconectado Desconectado

Mensajes: 1.955


Anonymous & Paranoid


Ver Perfil WWW
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #3 en: 4 Febrero 2010, 08:43 »

Si debería de ir en bugs y exploits, sin embargo sigo sin entender lo que quieres hacer.

De las 3 variables que se le mandan a la función, ninguna interviene en el código de la misma función, ademas el buffer al momende de ejecucion debe de tener basura sin inicializar.

Parece que tienes una idea algo confusa de lo que quieres hacer.

El ret debería de apuntar al ultimo EBP Salvado + 4 bytes

Deja lo pruebo y ahorita te digo que es lo que debes de modificar.



Mover el tema a bugs y exploits
En línea

Bien Super Divertido
@wifigdlmx
ghastlyX
Colaborador
***
Desconectado Desconectado

Mensajes: 1.894



Ver Perfil
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #4 en: 4 Febrero 2010, 11:33 »

Con el código que has puesto a mi también me da un Segmentation fault. Sin embargo, si coges el código y lo compilas con:
Código:
gcc -S -o code.s code.c

Te generará code.s. Si ahora miras el código de la función en code.s, verás algo como esto:
Código:
ghastlyx@Ahtec:~$ gcc -S -o code.s code.c
code.c: In function ‘f’:
code.c:6: warning: assignment from incompatible pointer type
code.c: In function ‘main’:
code.c:15: warning: incompatible implicit declaration of built-in function ‘printf’
code.c:10: warning: return type of ‘main’ is not ‘int’
ghastlyx@Ahtec:~$ head code.s
        .file   "code.c"
        .text
.globl f
        .type   f, @function
f:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $32, %esp
        leal    -9(%ebp), %eax
        addl    $12, %eax
En el leal puedes ver que la dirección de buffer1 es -9(%ebp), de forma que el incremento será 9 + 4.

Ahora, compilando normal y abriendo el gdb sale lo siguiente:
Código:
ghastlyx@Ahtec:~$ gcc code.c
code.c: In function ‘f’:
code.c:6: warning: assignment from incompatible pointer type
code.c: In function ‘main’:
code.c:15: warning: incompatible implicit declaration of built-in function ‘printf’
code.c:10: warning: return type of ‘main’ is not ‘int’
ghastlyx@Ahtec:~$ gdb a.out
GNU gdb 6.8-debian
Copyright (C) 2008 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 "i486-linux-gnu"...
(gdb) disas main
Dump of assembler code for function main:
0x080483c2 <main+0>:    lea    0x4(%esp),%ecx
0x080483c6 <main+4>:    and    $0xfffffff0,%esp
0x080483c9 <main+7>:    pushl  -0x4(%ecx)
0x080483cc <main+10>:   push   %ebp
0x080483cd <main+11>:   mov    %esp,%ebp
0x080483cf <main+13>:   push   %ecx
0x080483d0 <main+14>:   sub    $0x24,%esp
0x080483d3 <main+17>: movl   $0x0,-0x8(%ebp)
0x080483da <main+24>: movl   $0x3,0x8(%esp)
0x080483e2 <main+32>: movl   $0x2,0x4(%esp)
0x080483ea <main+40>: movl   $0x1,(%esp)
0x080483f1 <main+47>: call   0x80483a4 <f>
0x080483f6 <main+52>: movl   $0x1,-0x8(%ebp)
0x080483fd <main+59>: mov    -0x8(%ebp),%eax
0x08048400 <main+62>: mov    %eax,0x4(%esp)
0x08048404 <main+66>: movl   $0x80484e0,(%esp)
0x0804840b <main+73>: call   0x80482d8 <printf@plt>
0x08048410 <main+78>: add    $0x24,%esp
0x08048413 <main+81>: pop    %ecx
0x08048414 <main+82>: pop    %ebp
0x08048415 <main+83>: lea    -0x4(%ecx),%esp
0x08048418 <main+86>: ret 
Se puede ver que main+52 es donde retorna en caso normal y como queremos ir hasta después del x = 1, en este caso hay que ir a main+59, por lo que el segundo incremento es 7.

Editando el código y compilando:
Código:
ghastlyx@Ahtec:~$ cat code.c
void f(int a, int b, int c) {
        char buffer1[5];
        char buffer2[10];
        int *ret;
 
        ret = buffer1 + 13;
        (*ret) += 7;
}
 
void main() {
        int x;
        x = 0;
        f(1,2,3);
        x = 1;
        printf("%d\n", x);
}

ghastlyx@Ahtec:~$ gcc code.c
code.c: In function ‘f’:
code.c:6: warning: assignment from incompatible pointer type
code.c: In function ‘main’:
code.c:15: warning: incompatible implicit declaration of built-in function ‘printf’
code.c:10: warning: return type of ‘main’ is not ‘int’
ghastlyx@Ahtec:~$ ./a.out
0

Un saludo de ghastlyX ;)

PD: He renombrado la función a f como se puede ver en el código.
En línea
Nork

Desconectado Desconectado

Mensajes: 195



Ver Perfil
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #5 en: 4 Febrero 2010, 15:22 »

De las 3 variables que se le mandan a la función, ninguna interviene en el código de la misma función, ademas el buffer al momende de ejecucion debe de tener basura sin inicializar.

Parece que tienes una idea algo confusa de lo que quieres hacer.

El código no es mio es de un artículo que comenté arriba. Igualmente es un código que es simplemente como prueba de concepto más que nada.

@ghastlyX

Gracias! Se me había pasado crear el archivo .s y mirar el código ahí... Lo que hacía era de memoria sumar las variables. Esto es algo que no entiendo, si tenemos esto:

12 bytes   [buffer2]
8 bytes     [buffer1]
4 bytes     [@EBPret]

Si el puntero ret apunta a buffer1 viéndolo de esta manera serían 12bytes y no 13, no?? De donde sale el byte que falta? O talvez no se puede calcular de esta manera?

Otra cuestión:

Citar
        subl    $32, %esp

Entiéndo que el 32 sale de los 4 parámetros que se le pasa a la funcion (4x3) + los 20 bytes de los buffers, no? De ser así el puntero int ret, no ocupa memoria?

Gracias!  ;)
En línea

C' Est La Vie
ghastlyX
Colaborador
***
Desconectado Desconectado

Mensajes: 1.894



Ver Perfil
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #6 en: 4 Febrero 2010, 15:48 »

Citar
Gracias! Se me había pasado crear el archivo .s y mirar el código ahí... Lo que hacía era de memoria sumar las variables. Esto es algo que no entiendo, si tenemos esto:

12 bytes   [buffer2]
8 bytes     [buffer1]
4 bytes     [@EBPret]

Si el puntero ret apunta a buffer1 viéndolo de esta manera serían 12bytes y no 13, no?? De donde sale el byte que falta? O talvez no se puede calcular de esta manera?

Otra cuestión:

Citar
        subl    $32, %esp

Entiéndo que el 32 sale de los 4 parámetros que se le pasa a la funcion (4x3) + los 20 bytes de los buffers, no? De ser así el puntero int ret, no ocupa memoria?

Mira, si cambias un poco la función y la dejas así:
Código:
void f(int a, int b, int c) {
        char buffer1[5];
        char buffer2[10];
        int *ret;
ret = buffer2;
        ret = buffer1 + 13;
a = 5;
b = 7;
c = 9;
        (*ret) += 7;
}

El .s queda de la siguiente forma:
Código:
f:
pushl %ebp
movl %esp, %ebp
subl $32, %esp
leal -19(%ebp), %eax
movl %eax, -4(%ebp)
leal -9(%ebp), %eax
addl $13, %eax
movl %eax, -4(%ebp)
movl $5, 8(%ebp)
movl $7, 12(%ebp)
movl $9, 16(%ebp)
movl -4(%ebp), %eax
movl (%eax), %eax
leal 7(%eax), %edx
movl -4(%ebp), %eax
movl %edx, (%eax)
leave
ret
Aquí puedes ver como queda exactamente el bloque de activación de la función. Tenemos

|  buffer2  | -19(%EBP)
|  buffer1  | -9(%EBP)
|  ret         | -4(%EBP)
|  EBP ant| %EBP
|  @Ret    |  4(%EBP)
|      a       |  8(%EBP)
|      b       |  12(%EBP)
|      c       |  16(%EBP)

Un saludo de ghastlyX ;)
En línea
Nork

Desconectado Desconectado

Mensajes: 195



Ver Perfil
Re: Segmentation fault al cambiar dirección de retorno
« Respuesta #7 en: 4 Febrero 2010, 16:18 »

Vale, gracias ghastlyX  ;)
En línea

C' Est La Vie
Páginas: [1] Ir Arriba Respuesta Imprimir 

Ir a:  

Mensajes similares
Asunto Iniciado por Respuestas Vistas Último mensaje
Segmentation fault (core dumped)
Programación C/C++
neveldine 3 120 Último mensaje 3 Mayo 2012, 17:03
por neveldine
Powered by SMF 1.1.16 | SMF © 2006-2008, Simple Machines