AVILX
REVERSING WRITEUP · HACK THE BOX · 2026
Behind the Scenes
Fragmentación de strings en .rodata — Anti-análisis estático
| Plataforma | Hack The Box |
| Categoría | Reversing |
| Dificultad | Very Easy |
| Analista | Jesús Ávila (Avilx) |
| Fecha | 10 de Octubre 2026 |
| Portafolio | avilx.dev |
Documentación de aprendizaje en reversing | Entorno controlado
Información del Binario
| Campo | Valor |
|---|---|
| Nombre | behindthescenes |
| Tipo | ELF 64-bit LSB pie executable |
| Arquitectura | x86-64 |
| Enlazado | dynamically linked |
| Stripped | not stripped |
| BuildID | e60ae4c886619b869178148afd12d0a5428bfe18 |
| Stack Canary | Canary Found |
| NX | Enabled |
| PIE | PIE Enabled |
| RELRO | Full RELRO |
Este binario tiene las cuatro protecciones principales activas: canary, NX, PIE y Full RELRO. Al ser not stripped, los símbolos de funciones permanecen visibles en
objdump y GDB. Esto no es relevante para la solución, pero es parte del flujo estándar de reconocimiento. Entre los símbolos aparece segill_sigaction, lo que indica que el binario instala un signal handler — probablemente para dificultar el debugging dinámico con GDB.Reconocimiento
Análisis inicial
strings
$ strings -a ./behindthescenes | grep -v "^_Z\|GLIBC\|\.so\|\."
strncmp
strlen
sigemptyset
sigaction
> HTB{%s}
segill_sigaction
main
El comando
strings no reveló ningún password. Sí apareció el formato de salida > HTB{%s}, lo que confirma que el binario construye la flag con printf a partir de lo que ingresemos. También aparecen sigemptyset y sigaction, funciones para instalar signal handlers — una técnica común para complicar el análisis dinámico. La ausencia del password en strings es intencional.Ejecución inicial
$ ./behindthescenes
./challenge <password>
El binario espera un argumento posicional. No hay prompt interactivo; el password se pasa directamente en la línea de comandos como
./behindthescenes <password>.Inspección de .rodata
Al no aparecer el password con strings, el siguiente paso fue inspeccionar directamente la sección .rodata en hexadecimal:
$ objdump -s -j .rodata ./behindthescenes
Contents of section .rodata:
2000 01000200 2e2f6368 616c6c65 6e676520 ...../challenge
2010 3c706173 73776f72 643e0049 747a005f <password>.Itz._
2020 306e004c 795f0055 4432003e 20485442 0n.Ly_.UD2.> HTB
2030 7b25737d 0a00 {%s}..
La clave para leer este dump está en entender la columna ASCII del lado derecho. En C, todo string termina con el byte 0x00. Ese byte no tiene representación imprimible, por lo que objdump lo muestra como un punto . en la columna derecha. Cada punto es un delimitador entre un string y el siguiente.
Leyendo la columna ASCII con los puntos como separadores:
| Offset | String | Observación |
|---|---|---|
0x2008 | ./challenge <password> | Mensaje de uso |
0x2018 | Itz | Fragmento 1 |
El password está partido en cuatro strings separados en
.rodata. Concatenados en el orden en que aparecen en memoria producen: Itz_0nLy_UD2. El binario los referencia por dirección individual y los une en runtime, de modo que ningún análisis estático superficial revela la credencial completa.Solución
Password reconstruido
PASSWORD ENCONTRADO
$ ./behindthescenes Itz_0nLy_UD2
> HTB{Itz_0nLy_UD2}
La hipótesis de concatenación en orden de aparición en
.rodata fue correcta. El binario respondió con la flag completa.Por qué funciona esta técnica
La fragmentación de strings en .rodata es una técnica de anti-análisis estático. El compilador almacena cada fragmento como un literal independiente, referenciado por su dirección. El código los concatena en memoria durante la ejecución, pero ninguno de los fragmentos individuales parece una credencial a simple vista.
Desde el punto de vista del analista:
-
stringsbusca secuencias de caracteres imprimibles de longitud mínima. Al estar fragmentado, ninguna pieza alcanza la longitud necesaria para parecer un password completo ni para activar una firma de detección. -
Herramientas de análisis antivirus basadas en firmas de strings también resultan inefectivas contra esta técnica.
-
En malware real, esta fragmentación se combina frecuentemente con XOR, ROT o construcción dinámica en heap para hacerla aún más opaca.
Un análisis dinámico con
ltrace o GDB hubiera revelado la concatenación en runtime. El nombre del challenge — Behind the Scenes — hace referencia exactamente a esto: lo relevante no está en la superficie del binario sino detrás del análisis superficial. La ruta estática fue más formativa porque obligó a leer el hex dump manualmente.Reflexión Final
Qué salió bien
Cuando strings no devolvió ningún password, el paso siguiente fue directo: inspeccionar .rodata con objdump -s. El razonamiento fue correcto — si el password no aparece como string completo, probablemente está fragmentado o codificado. En este caso estaba fragmentado.
La lectura del hex dump también funcionó bien una vez que quedó claro el papel del byte 0x00 como delimitador. Los puntos en la columna ASCII son exactamente eso: terminadores null de strings C.
Qué costó más
La sintaxis básica de bash para pasar argumentos posicionales a un ejecutable. Se confundió el operador de redirección > con los delimitadores < > del mensaje de uso del binario. No es un error de reversing sino de shell, pero en un flujo real cuesta tiempo.
Lecciones
-
Cuando
stringsno devuelve credenciales,objdump -s -j .rodataes el siguiente paso natural. -
Los puntos en la columna ASCII del hex dump son bytes
0x00: delimitadores de strings en C. Leer esa columna de izquierda a derecha es suficiente para reconstruir los fragmentos. -
La fragmentación de strings en
.rodataes una técnica de evasion real. Reconocerla en este challenge es base para identificarla en muestras de malware. -
El análisis dinámico (
ltrace,GDB) hubiera resuelto esto más rápido, pero la ruta estática fue más formativa.
Tiempo total
| Fase | Tiempo |
|---|---|
| Reconocimiento con strings y checksec | 5 minutos |
| Inspección de .rodata con objdump | 10 minutos |
| Verificación y ejecución | 2 minutos |
| Total | 20 minutos |