May 15 2008
HackIt Nivel 10: reverse engineering
Tras seguir las pistas dadas en los anteriores posts sobre el HackIt Nivel 9 (léanse también los comentarios), llegamos al fatídico nivel 10. Aquí nos quedamos cuando sonó el ¡gong! del GAME OVER ;-) A primera vista la cosa no pinta muy bien, dado que tras descargar el zip y descomprimirlo, vemos que efectivamente se trata del juego Breakout, por lo que dice el “enunciado” de la pista y por las librerías gráficas que carga:
[juanan@localhost game]$ ldd go
linux-gate.so.1 => (0×00110000)
libXpm.so.4 => /usr/lib/libXpm.so.4 (0×02216000)
libX11.so.6 => /usr/lib/libX11.so.6 (0×00a6e000)
libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0×061ea000)
libm.so.6 => /lib/libm.so.6 (0×004bb000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0×002aa000)
libc.so.6 => /lib/libc.so.6 (0×00360000)
libxcb-xlib.so.0 => /usr/lib/libxcb-xlib.so.0 (0×00bcc000)
libxcb.so.1 => /usr/lib/libxcb.so.1 (0×00bae000)
libdl.so.2 => /lib/libdl.so.2 (0×004e6000)
/lib/ld-linux.so.2 (0×00341000)
libXau.so.6 => /usr/lib/libXau.so.6 (0×00639000)
libXdmcp.so.6 => /usr/lib/libXdmcp.so.6 (0×0063e000)
pero, si analizamos el tipo de fichero:
[juanan@localhost game]$ file go
go: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.6.8, dynamically linked (uses shared libs), corrupted section header size
vemos que es un fichero ejecutable ELF para Linux, y ¡ojo al parche!, las cabeceras están manipuladas (corrupted section header size) :-O Me temo que a GDB no le gustará nada de nada…
[juanan@localhost game]$ gdb go
GNU gdb Red Hat Linux (6.6-45.fc8rh)
(no debugging symbols found)
Pues vaya… no hay tabla de símbolos, así que ¿cómo indicar los puntos de ruptura? ¿cómo depurar el programa? Os dejo con el reto, y os animo a proponer vías de solución en los comentarios. Yo voy a por un café y cumplimentar papeleos de la universidad…
Hmm, no es mucha ayuda pero, con un vistazo rapido usando strace, vemos que intenta leer del archivo “license.txt” del mismo directorio:
brk(0) = 0×977a000
brk(0×979b000) = 0×979b000
open(”license.txt”, O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0664, st_size=22, …}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb8
Ademas de eso si usamos el comando “strings” podemos mirar los strings en cleartext del ejecutable, entre los resultados curiosos tenemos este output:
error: wrong license number
error: license file not found!
error closing license file!
license.txt
p@Pong
pong
Failed to open display
Asi pues, escribiendo ‘p@Pong’ y ‘pong’ en el archivo license, el ejecutable hace un read() mas que la anterior ocasion en el output de strace:
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb8015000
read(3, “p@Pong\npong\n”, 4096) = 12
read(3, “”, 4096) = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 1), …}) = 0
Esto a lo mejor sirve de pista a alguien, si consigo algo mas de tiempo, se puede probar a desensamblar en IDA o algo.
Este es otro en el que me he encallado. (con lo fácil que es el nivel 11!).
LIDA da el error: ERROR: 08048F50 not found in address range!
He conseguido depurar con ald y rastrearlo pero por ahora sin demasiado éxito
No sé, quizás habría que abordarlo de otra forma …
Usando objdump se puede saber la dirección de entrada del código:
$ objdump -x go
Se obtiene la dirección de entrada 0×08048f50 (que coindice con la que a Xabier LIDA le da como error)
Ahora se puede establecer en el gdb el primer punto de ruptura en esa dirección:
(gdb) break *0×08048f50