Foro de elhacker.net

Seguridad Informática => Bugs y Exploits => Mensaje iniciado por: Vaagish en 2 Septiembre 2015, 23:45 pm



Título: Dudas con Integer Overflow
Publicado por: Vaagish en 2 Septiembre 2015, 23:45 pm
Hola chicos!

Estoy lidiando con un programa que tiene un fallo de integer overflow y no soy precisamente un 'experto' en estos temas del reversing.. u.u

Me estoy basando en este texto para aprender sobre el asunto: http://phrack.org/issues/60/10.html

Por lo que entiendo en este code (que esta muy bien explicado):

Código
  1.    /* width1.c - exploiting a trivial widthness bug */
  2.    #include <stdio.h>
  3.    #include <string.h>
  4.  
  5.    int main(int argc, char *argv[]){
  6.            unsigned short s;
  7.            int i;
  8.            char buf[80];
  9.  
  10.            if(argc < 3){
  11.                    return -1;
  12.            }
  13.  
  14.            i = atoi(argv[1]);
  15.            s = i;
  16.  
  17.            if(s >= 80){            /* [w1] */
  18.                    printf("Oh no you don't!\n");
  19.                    return -1;
  20.            }
  21.  
  22.            printf("s = %d\n", s);
  23.  
  24.            memcpy(buf, argv[2], i);
  25.            buf[i] = '\0';
  26.            printf("%s\n", buf);
  27.  
  28.            return 0;
  29.    }

El problema esta cuando se le pasa como argumento a ese programa un numero mayor que 65535, ya que luego se va a tratar como un "unsigned short",, aca el disassembly:

Código
  1. CPU Disasm
  2. Address   Hex dump                  Command                                  Comments
  3. 009012B8  |.  FF73 04               PUSH DWORD PTR DS:[EBX+4]                ; /Arg1 = ASCII "65536"
  4. 009012BB  |.  FF15 B8309000         CALL DWORD PTR DS:[<&MSVCR120.atoi>]     ; \MSVCR120.atoi
  5. 009012C1  |.  8BF8                  MOV EDI,EAX
  6. 009012C3  |.  83C4 04               ADD ESP,4
  7. 009012C6  |.  66:83FF 50            CMP DI,50
  8. 009012CA  |.  72 17                 JB SHORT 009012E3
  9. 009012CC  |.  68 8C319000           PUSH OFFSET 0090318C     ; "Oh no youdon't!"
  10. 009012D1  |.  FF15 B4309000         CALL DWORD PTR DS:[<&MSVCR120.printf>]
  11. 009012D7  |.  83C4 04               ADD ESP,4
  12. 009012DA  |.  83C8 FF               OR EAX,FFFFFFFF
  13. 009012DD  |.  5F                    POP EDI
  14. 009012DE  |.  5B                    POP EBX
  15. 009012DF  |.  8BE5                  MOV ESP,EBP
  16. 009012E1  |.  5D                    POP EBP
  17. 009012E2  |.  C3                    RETN
  18. 009012E3  |>  0FB7C7                MOVZX EAX,DI
  19. 009012E6  |.  50                    PUSH EAX
  20. 009012E7  |.  68 A0319000           PUSH OFFSET 009031A0    ; ASCII "s = %d"
  21. 009012EC  |.  FF15 B4309000         CALL DWORD PTR DS:[<&MSVCR120.printf>]

Bueno, a mi entender el mayor problema es la linea 7. Comparar el valor 10000 con 50 (hexadecimal), el programa se saltea el " if (s >= 80) " y luego falla en memcpy, mas precisamente aca:

Código
  1. CPU Disasm
  2. Address   Hex dump                   Command                                            Comments
  3. 58D2F608  />  F3:A5                  REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]

Se copia de esi a edi un valor muy grande y su respectiva violacion de segmento.

En el texto aclara esto:

Citar
Integer overflows are not like most common bug classes.  They do not allow
direct overwriting of memory or direct execution flow control, but are much
more subtle.  The root of the problem lies in the fact that there is no way
for a process to check the result of a computation after it has happened,
so there may be a discrepancy between the stored result and the correct
result.  Because of this, most integer overflows are not actually
exploitable.  Even so, in certain cases it is possible to force a crucial
variable to contain an erroneous value, and this can lead to problems later
in the code.

Y tambien aclara esto:

Citar
The length argument is taken from the command line and held in the integer
i.  When this value is transferred into the short integer s, it is
truncated if the value is too great to fit into s (i.e. if the value is
greater than 65535).  Because of this, it is possible to bypass the bounds
check at [w1] and overflow the buffer.  After this, standard stack smashing
techniques can be used to exploit the process.

Cuando yo pruebo el programa que estoy tratando de arreglar, a veces logro ejecutar los tipicos '41414141' y otras veces no, o sea.. el programa falla en direcciones diferentes todas las veces, tiene remedio eso? Puedo forzar la direccion donde quiero que falle??

1 - Yo me quedo con la duda de como es posible que sin saber el resultado final del buffer igual sea posible ejecutar codigo arbitrario.. dice que con metodos estandar se puede, pero yo no encuentro forma..

2 - Asi que no siempre es explotable esta situacion?

Gracias por leer todo eso!! Saludos!!!


Título: Re: Dudas con Integer Overflow
Publicado por: Vaagish en 7 Septiembre 2015, 19:56 pm
Entonces?? Nadie?  :-\


Título: Re: Dudas con Integer Overflow
Publicado por: someRandomCode en 8 Septiembre 2015, 03:42 am
Se me ocurre que el problema esta en el memcpy de argv[2] pero realmente estoy tambien bastante verde en el tema de reversing..


Título: Re: Dudas con Integer Overflow
Publicado por: .:UND3R:. en 8 Septiembre 2015, 05:18 am
Que SO estás usando, con qué parámetros compilaste el programa?, me encantaría ayudarte pero no dispongo de mucho tiempo, creo haber estudiado algo de Integer Overflow, saludos.


Título: Re: Dudas con Integer Overflow
Publicado por: Vaagish en 8 Septiembre 2015, 07:20 am
Hi!  :D

Gracias por responder chicos! Les cuento hasta donde entiendo..

Citar
Se me ocurre que el problema esta en el memcpy de argv[2] pero realmente estoy tambien bastante verde en el tema de reversing..

En realidad entiendo porque falla el programa, digamos que tiene un "mal diseño",, y me explico mejor:

1 - i es integer y se obtiene desde la consola (argv[1])
2 - si el valor introducido es (por ejemplo) 65536,, cuando se hace i = atoi(argv[1]); i vale 10000
3 - cuando se pone en s el valor de i, s solo puede guardar los ultimos 4 valores (0000), por lo cual la condicion de la linea 17 es salteada.
4 - Luego se copia a buf, pero con el valor de i que es mucho mayor,, y.. buffer overflow.

Citar
Que SO estás usando, con qué parámetros compilaste el programa?, me encantaría ayudarte pero no dispongo de mucho tiempo, creo haber estudiado algo de Integer Overflow, saludos.

Estoy desde windows, lo compile en visual studio 2013 con la seguridad desactivada..

Lo que yo quisiera saber es si este tipo de situacion es explotable,, si existe una forma de controlar el fallo y poder ejecutar codigo arbitrario.. a memcpy se le pasa un valor grande para copiar (10000) y el buffer (buf) se desborda porque solo tiene 80,, pero como se puede llegar a "sacar ventaja" del buffer overflow es lo que me esta intrigando mucho  :laugh:

Entiendo que el "shellcode" tendria que ser pasado por argv[2].  :rolleyes:

Saludos!!! Gracias!

PD: Este codigo es un ejemplo de integer overflow, el fallo que yo busco esta en otro programa, pero es comparable uno con otro. No es que precise arreglar ese codigo, ni es mio.. digo por las dudas..


Título: Re: Dudas con Integer Overflow
Publicado por: MCKSys Argentina en 8 Septiembre 2015, 18:42 pm
Hola!

Hasta donde entiendo, el integer overflow de este caso, lo usas para escribir más cantidad de heap con tu data, que la prevista.

En lo único que veo a ésto útil, es si dentro de la parte de heap que has pisado, hay algún puntero a función, que sea usado por el código siguiente (o que puedas triguerear sin que se rompa el proggie).

Creo que es la única forma de explotar este tipo de cosas...

Saludos!

PD: Si es por prevenir este tipo de cosas: Ten en cuenta que todos los martes salen parches de M$, y varias veces son integer overflow. Eso te dice que es difícil (no imposible) detectarlos. Un ejemplo (https://twitter.com/NicoEconomou/status/639890807391191041) de hace 4 días...  :xD


Título: Re: Dudas con Integer Overflow
Publicado por: Vaagish en 8 Septiembre 2015, 20:23 pm
Hi!!

Citar
Hasta donde entiendo, el integer overflow de este caso, lo usas para escribir más cantidad de heap con tu data, que la prevista.

Exacto!

Citar
En lo único que veo a ésto útil, es si dentro de la parte de heap que has pisado, hay algún puntero a función, que sea usado por el código siguiente (o que puedas triguerear sin que se rompa el proggie).

Ok, algo entendi.. ¿pero que ventaja tendria si he pisado el puntero a funcion? No se que es triguerear,, algo como juntar trigo? xD

Bueno, ya igual me voy haciendo la idea que esta muy complejo esto.. y que un integer overflow a veces y solo a veces es explotable, digamos.. si se alinean los planetas..

Citar
Si es por prevenir este tipo de cosas: Ten en cuenta que todos los martes salen parches de M$

Dudo que vuelva a buscar un integer overflow en mi vida xD

Gracias!! Saludos!!


Título: Re: Dudas con Integer Overflow
Publicado por: MCKSys Argentina en 8 Septiembre 2015, 21:55 pm
Ok, algo entendi.. ¿pero que ventaja tendria si he pisado el puntero a funcion? No se que es triguerear,, algo como juntar trigo? xD

triguerear es desencadenar/provocar. Es la adaptación de la palabra inglesa trigger. Sería lo que se necesita hacer para que la vulnerabilidad "se dispare".

Admito que no es lo mejor, pero cuando hablamos sobre cosas referentes a la informática, muchas veces debemos mezclar inglés con castellano sólo por el hecho de que nos entiendan. Aunque éste no sea el caso  :P

Ejemplos: montículo en vez de heap, pila en vez de stack, etc. Algunas cosas no suenan bien si se traducen...

Saludos!


Título: Re: Dudas con Integer Overflow
Publicado por: Vaagish en 8 Septiembre 2015, 22:46 pm
Citar
muchas veces debemos mezclar inglés con castellano sólo por el hecho de que nos entiendan.

Comparto, es solo que no estoy tan familiarizado con la jerga de ingeniería inversa xD

Justo cuando entre a responder, el foro me propuso (ahi en mensajes similares) que vea el siguiente tema:

http://foro.elhacker.net/desafios_wargames/desafioreto_para_avanzados_explotacion_por_integer_overflow-t15164.0.html

Extraña coincidencia de la vida, el programa es bastante parecido a ese que puse de ejemplo,, y al parecer el reto es meter un shellcode! Asi que voy a ver si tiene solucion (que supongo que si, claro) para aprender sobre el tema.

Muchas gracias a todos! A seguir aprendiendo :)

EDITADO:

Parece que en el enlace que puse, Rojodos y p5il0cyb3 entran en duelo a muerte y no me termina de quedar claro si sirve o si no,, pero sigue siendo informacion util.


Título: Re: Dudas con Integer Overflow
Publicado por: MCKSys Argentina en 8 Septiembre 2015, 23:28 pm
Hasta donde entiendo, el integer overflow de este caso, lo usas para escribir más cantidad de heap con tu data, que la prevista.

Creo que entendí mal. Mirando el código, veo que el buffer es local, por lo que estará en el stack. Luego, al desbordarlo podrías pisar el return address y saltar a tu código; o bien, pisar el SEH chain y ROPear.

Aunque, bueno, habría que compilar y mirar con un dbg para sacar bien una solución; pero la 989898 es mayor...  :P

Saludos!



Título: Re: Dudas con Integer Overflow
Publicado por: Vaagish en 8 Septiembre 2015, 23:59 pm
Citar
Mirando el código, veo que el buffer es local, por lo que estará en el stack.

Es verdad. En el ejemplo dado es local,, yo tampoco me habia dado cuenta porque en el programa que depuro no es local, lo cual me deja en jaque, porque no va a ser lo mismo.. igualmente el tema de integer overflow es interesante tanto en el heap como en el stack.

Citar
Luego, al desbordarlo podrías pisar el return address y saltar a tu código; o bien, pisar el SEH chain y ROPear.

Bueno, ahi es donde empieza el juego.. Lo que yo no veo es la logica.. memcpy va a terminar copiando hasta donde sea necesario para que se de el integer overflow.

Es decir, la meta es desbordar el buffer, pero hay que tener en cuenta que el valor ingresado no puede ser "cualquiera", sino el valor justo para que tambien se saltee la condicion (la que trata de controlar que no se desborde, justamente). Eso nos deja con muy poco margen para operar.

Esto que trato de aclarar es lo mismo para este ejemplo que para casi cualquier integer overflow que luego provoque un buffer overflow:

Si ponemos un valor muy grande con la intencion de desbordar un integer, no vamos a poder controlar luego hasta donde va a pisar memcpy. Probablemente va a pisar la funcion, el return address y todo lo que se tope en su camino hasta el final del stack ¬¬

Me equivoco? Los integer overflows que dan paso a buffer overflow, son casi imposibles de explotar?

Saludos!!!

PD: Ademas, si desbordamos el buffer tiene que ser por muy poco, (por obvias razones), lo cual nos deja con mucho menos margen aun!  :rolleyes:  :silbar:


Título: Re: Dudas con Integer Overflow
Publicado por: dRak0 en 10 Septiembre 2015, 01:29 am
¿Este tema no va en Bugs y Exploits?


Título: Re: Dudas con Integer Overflow
Publicado por: MCKSys Argentina en 10 Septiembre 2015, 04:46 am
¿Este tema no va en Bugs y Exploits?

Es cierto! jejeje.. No me había percatado de eso..

Moviendo a Bugs y Exploits...


Título: Re: Dudas con Integer Overflow
Publicado por: Vaagish en 10 Septiembre 2015, 06:41 am
Upss sorry.. sigue en Bugs y Exploits entonces.. si encuentro algo del tema lo pongo ahi.

Saludos!