Solución Ropemporium Badchars
Desafío Ropemporium Badchars
En este reto de Ropemporium, nos encontramos con la presencia de badchars, que son caracteres de bajo nivel que podrían causar la terminación del programa y complicar el control del flujo del mismo según nuestras necesidades, algo común en el desarrollo de exploits.
El enunciado sugiere que para evitar los badchars, podemos utilizar herramientas como ropper para encontrar gadgets que no contengan estos caracteres. La identificación de los badchars se realizará ejecutando el programa, según indica el enunciado. Además, se nos informa que este desafío es similar al anterior, write4, pero con la dificultad adicional de manejar badchars en la función print_file().
Se nos plantean dos enfoques para resolver el desafío: la primera opción consiste en proporcionar direcciones y funcionalidad evitando por completo los badchars, mientras que la segunda opción es utilizar gadgets para modificar el contenido del string en memoria.
Para este análisis, optaremos por utilizar pwndbg en lugar de radare, ya que nos parece más adecuado en este contexto. Al abrir pwndbg y ejecutar inf func para visualizar las funciones, identificamos una llamada a usefulGadgets.
Análisis de la Función usefulGadgets
Al inspeccionar la función usefulGadgets mediante el desensamblador (disas), describiremos la funcionalidad de las instrucciones presentes en el código:
Instrucciones:
1. xor BYTE PTR [r15], r14b
- La instrucción
xorrealiza una operación de exclusión OR (XOR) bit a bit entre los operandos. BYTE PTR [r15]se refiere a la dirección de memoria almacenada en el registror15, yr14bes el registro de 8 bitsr14.- Se realiza una operación XOR entre el byte almacenado en la dirección de memoria apuntada por
r15y el contenido der14b.
2. ret
- La instrucción
retse utiliza para realizar un retorno de función. La dirección de retorno se carga desde la pila y el control se transfiere a esa dirección.
3. add BYTE PTR [r15], r14b
- La instrucción
addsuma los valores de los operandos. - Se suma el byte almacenado en la dirección de memoria apuntada por
r15con el contenido der14b.
4. ret
- La instrucción
retrealiza un retorno de función.
5. sub BYTE PTR [r15], r14b
- La instrucción
subrealiza una operación de resta. - Resta el contenido de
r14bdel byte almacenado en la dirección de memoria apuntada porr15.
6. ret
- La instrucción
retrealiza un retorno de función.
7. mov QWORD PTR [r13+0x0], r12
- La instrucción
movcopia el contenido del registror12a la dirección de memoria calculada comor13+0x0(8 bytes). QWORD PTRindica que se está moviendo un cuádruple palabra (8 bytes) de datos.
8. ret
- La instrucción
retrealiza un retorno de función.
9. nop DWORD PTR [rax+0x0]
- La instrucción
nop(no operation) no realiza ninguna operación y se utiliza para llenar espacio o como marcador de posición. DWORD PTR [rax+0x0]indica que se está aplicando a un doble palabra (4 bytes), pero debido a que es unnop, no tiene efecto real en los datos.
Búsqueda de Badchars
Los badchars identificados son: x, g, a, . (en hexadecimal: 0x78, 0x67, 0x61, 0x2E).
Se ejecutará ropper con un filtro para buscar gadgets sin estos badchars:
El enunciado sugiere el uso de XOR para sortear los badchars. Utilizaremos un gadget que permite cargar datos y aplicaremos una operación XOR con clave 2 en Python, utilizando la librería pwn:
1
string = xor(b"flag.txt", 2)
Vale recopilacion que tenemos hasta ahora,
1
2
3
4
5
6
7
8
from pwn import process, xor, p64, log
shell = process("./badchars")
offset = 40
junk = b"A" * offset
string = xor(b"flag.txt", 2)
Configuración y Preparación
En esta parte, se realiza la configuración inicial del proceso y se definen las variables necesarias, incluyendo el string cifrado, la dirección de la sección BSS y la dirección de la función print_file.
En la imagen, se muestra la dirección de memoria de la función print_file obtenida mediante radare.
1
2
3
4
5
6
7
8
9
10
11
12
from pwn import process, xor, p64, log
shell = process("./badchars")
offset = 40
junk = b"A" * offset
# Cifrado XOR del string "flag.txt" con clave 2
string = xor(b"flag.txt", 2)
# Dirección de la función print_file obtenida con radare
print_file = p64(0x400510)
Gadgets Necesarios
Los gadgets necesarios para realizar operaciones XOR y otras instrucciones esenciales en el exploit. 
Dirección de la Sección BSS
Nos faltaría ahora la dirección de memoria donde podremos escribir. Utilizaremos radare y el comando iS para obtener esta dirección. 




