Post

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.

Pwndbg Badchars

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 xor realiza 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 registro r15, y r14b es el registro de 8 bits r14.
  • Se realiza una operación XOR entre el byte almacenado en la dirección de memoria apuntada por r15 y el contenido de r14b.

2. ret

  • La instrucción ret se 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 add suma los valores de los operandos.
  • Se suma el byte almacenado en la dirección de memoria apuntada por r15 con el contenido de r14b.

4. ret

  • La instrucción ret realiza un retorno de función.

5. sub BYTE PTR [r15], r14b

  • La instrucción sub realiza una operación de resta.
  • Resta el contenido de r14b del byte almacenado en la dirección de memoria apuntada por r15.

6. ret

  • La instrucción ret realiza un retorno de función.

7. mov QWORD PTR [r13+0x0], r12

  • La instrucción mov copia el contenido del registro r12 a la dirección de memoria calculada como r13+0x0 (8 bytes).
  • QWORD PTR indica que se está moviendo un cuádruple palabra (8 bytes) de datos.

8. ret

  • La instrucción ret realiza 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 un nop, no tiene efecto real en los datos.

Disassembly de usefulGadgets

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:

Gadgets sin 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.

Print File Address

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.

Exploit

This post is licensed under CC BY 4.0 by the author.