Para depurar en radare, vamos a preparar un poco el entorno. Sabemos que el binario pide un input y muestra por pantalla ciertos outputs. Para poder usar el debugger en estos casos suelo preparar un fichero con el input a pasarle al binario (le llamaré payload) y abrir otra terminal donde poder ver el output. Si usamos screen o tmux, podremos hacerlo en la misma ventana: Ctrl+a+|
para hacer split vertical. Ctrl+a+tab
para colocarnos en la sección derecha. Ctrl+a+c
para crear una nueva región. Ctrl+a+:
y tecleamos resize 40
para redimensionar la región. Tecleamos ahora tty
para ver el identificador de terminal y lo apuntamos (/dev/pts/3, por ejemplo). Ctrl+a+tab
para colocarnos en la sección izquierda. Editamos foo.rr2 con la configuración indicada:
stdio=/dev/pts/3
stdin=./payload
En payload metemos el input inicial, por ejemplo ABCDEFGHIJK.
![](https://ikasten.io/wp-content/uploads/2020/05/image-13-1024x448.png)
Todo listo para comenzar a darle calor al debugger:
r2 -e dbg.profile=foo.rr2 -d cracked
Recuerda, aaa
para analizar flags, strings, funciones… Le costará un rato. Ahora V
(visual mode), p
(modo desensamblado) , p
(igual, pero viendo registros y pila).
:db main
breakpoint en el main (intro)
_
(buscar referencias), Good
(sabemos por los strings que pondrá Good job). Intro
. x
. radare nos situará sobre el código que comprueba nuestro input.
![](https://ikasten.io/wp-content/uploads/2020/05/image-14-1024x648.png)
Podemos poner otro breakpoint al comienzo de esta sección (con F2 ponemos breakpoints en modo visual, sin tener que teclear «db 0xdirección») y otro tras el segundo strcat. Tecleamos :dc
para saltar de breakpoint a breakpoint, analizando registros.
![](https://ikasten.io/wp-content/uploads/2020/05/image-15-1024x648.png)
Tenemos un bucle que itera sobre el input y realiza las siguientes operaciones:
input = [0x41, 0x42, 0x43, ..., 0x49] # el input que le pasamos
IV = 0x50
flag = ""
for i in range(len(input)):
if i == 0:
flag += chr(IV ^ input[i])
else:
flag += chr(input[i - 1] ^ input[i])
El resultado final lo compara con esta cadena de bytes:
![](https://ikasten.io/wp-content/uploads/2020/05/image-16-1024x648.png)
Así que hay que invertir el algoritmo.
sol = [0x1b, 0x52, 0x3f, 0x5e, 0x29, 0x4c, 0x3a, 0x55, 0x33, 0x5f, 0x3e, 0x59]
idx = 0
left = 0x50
newFileBytes = []
for i in range(0,len(sol)):
right = sol[idx]
sig = left ^ right
print(sig)
newFileBytes.append(sig)
left = sol[idx]
idx = idx + 1
newFile = open("flag.txt", "wb")
newFileByteArray = bytearray(newFileBytes)
newFile.write(newFileByteArray)
Y obtendremos la clave en flag.txt 🙂