By @hextupid
Descripcion:
Iniciamos ejecutando el binario de manera normal. Podemos ver que nos muestra un mensaje en binario (01100100 01101001 01110000 01110101 01110100), el cual traducido a ASCII dice “diput”. Esto no nos aporta nada.
Lo malo es que al intentarlo, obtendremos una flag falsa. De nuevo siendo troll.
Descripcion:
Hay un servicio corriendo en el servidor del Banco, no sabemos que hace pero
nuestro contacto interno encontro el binario que se ejecuta,
desafortunadamente no pudo conseguir el codigo fuente. Hazle ingenieria inversa, y trata de encontrar una vulnerabilidad que nos de
una shell remota! Aquí los detalles de conexión: > IP: 70.37.x.x Port: 1560
Iniciamos ejecutando el binario de manera normal. Podemos ver que nos muestra un mensaje en binario (01100100 01101001 01110000 01110101 01110100), el cual traducido a ASCII dice “diput”. Esto no nos aporta nada.
Adicional al mensaje anterior, el programa
solicita que ingresemos una CLABE para buscar. Si ingresamos una cadena
inválida, obtendremos el mensaje “:’v”.
Si revisamos los mecanismos de protección
habilitados, veremos que no cuenta con algunos de ellos. Esto nos será útil más
tarde.
Comenzando
con la ingeniería inversa, podemos ver que existen algunas funciones interesantes
como:
De esas
funciones, vemos que fake es falsa y solo sirve para despistar. Parece que se
trata de un reto troll.
Observamos
que si ingresamos la cadena “_ITM_deregisterTMCloneTable”,
podremos saltar a la función “get_flag”
automáticamente.
Lo malo es que al intentarlo, obtendremos una flag falsa. De nuevo siendo troll.
Las
siguientes funciones que podrían resultar interesantes, son System y System_old,
mismas que son muy similares pero cada una abre un archivo diferente, por lo
que podemos asumir que alguno de los dos se trata de la flag verdadera.
Para llegar a System, debemos buscar alguna
función que nos lleve a ella, o forzar el retorno de otra función a través de
un ataque de buffer overflow.
Analizando la función f_flush vemos que ésta
nos lleva a System después de cumplir (o inclumplir) algunas condiciones.
Por ejemplo, se observa que f_flush lleva a
cabo dos comparaciones con el carácter 0x69 (i), en caso de ser válida la
comparación, se lleva a cabo una segunda comparación con el caracter 0x64 (d).
En caso de ser válidas ambas comparaciones, llegaremos a la función “System”.
El problema que vemos ahora, es cómo podemos
primero llegar a f_flush.
Revisando la función “diput”, vemos que se
lleva a cabo una comparación más de una de sus variables, si es diferente de
“:”, entonces nos mostrará un mensaje falso de stack smashing detected:
recordemos que esta protección no está habilitada realmente. Después de este
mensaje, llegaremos a f_flush.
Para esto
necesitamos evitar que el registro al, sea diferente al caracter 0x3A (“:”).
Vemos que,
en tiempo de ejecución, enviando solo 4 bytes, este valor se mantiene intacto.
Probablemente es momento de intentar un
overflow, considerando que el contexto de la función es de 0x30 bytes, podemos
intentar enviar esa cantidad de “A”.
Y vemos que
funciona, conseguimos sobrescribir el valor:
OPCIÓN 1:
Después de encontrar la posición exacta del
carácter (45), solo necesitamos enviar un carácter DISTINTO a “:” para poder
llegar a f_flush.
Este pequeño exploit nos podría servir para
eso:
python -c 'print "A"*44 + "B" + "A" +
"id"'
Una vez
estando en f_flush, necesitamos una vez más encontrar la posición de los
caracteres que nos permitirán llegar a System. Recordemos dicha logica:
Así que una vez más, sin perder el buffer
anterior y de la misma manera que encontramos la posición exacta del carácter,
encontraremos la posición de los dos nuevos caracteres (47 y 48).
El
siguiente exploit nos podrá llevar a System.
python -c 'print "A"*44 + "B" + "A" +
"id"'
Como vemos, esta no es la flag y parece que
solo es otro distractor, puesto que el mensaje impreso SIMULA ser la salida del
comando “id” de bash, pero recordemos que la función “System” imprimía un
archivo, así que, de nuevo es falso.
SIN EMBARGO, vemos que la ejecución del
programa termina con un Segmentation
fault (core dumped) lo cual nos indica que estamos intentando acceder a un
espacio de memoria al cuál no podemos. En pocas palabras, podríamos intentar
saltar arbitrariamente a cualquier parte del programa. Esto nos resulta
sumamente útil, puesto que no hay ninguna función que llame a System_old.
De esta forma, solo hace falta encontrar la
posición del return, y esto se puede hacer fácilmente incrementando el tamaño
del buffer hasta lograr sobrescribir la posición donde se almacena la dirección
de return de alguna función en el stack. En este caso utilizaremos el return de
diput:
python -c 'print
"A"*44 + "B" + "A" + "id" +
"C"*8 + "\xef\xbe\xad\xde"'
Una vez
conseguido esto, es trivial el salto a System_old ejecutando el siguiente exploit:
python -c 'print "A"*44 +
"B" + "A" + "id" + "C"*8 +
"\xbf\x13\x40"'
Y vemos que
esta es la verdadera bandera!!!
OPCIÓN 2:
Mantenemos íntegro el carácter “:” para evitar
caer en el mensaje de stack smashing detected. Esto se logra reintroduciendo en
el buffer el carácter en la posición correcta (45).
Después solo es necesario incrementar el tamaño
del buffer hasta poder sobrescribir el return de la función. Esto se logra con
11 caracteres más después del carácter “:”
python -c 'print "A"*44 + ":" + "C"*11 +
"\xbf\x13\x40"'
De esta
forma se obtiene la flag mas directamente! Sin pasar por la función System ni
f_flush.
Versión
elegante del exploit:
from pwn import * context.log_level="debug" # win @ 40080a p = process("./CLABEFinder") p.sendline("A"*44 + ":" + "B"*11 + p32(0x4013BF)) p.interactive()
Comments
Post a Comment