WWW2Exec - GOT/PLT
Reading time: 6 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
GOT : Table d'offset global
La Table d'offset global (GOT) est un mécanisme utilisé dans les binaires liés dynamiquement pour gérer les adresses des fonctions externes. Étant donné que ces adresses ne sont pas connues avant l'exécution (en raison du lien dynamique), la GOT fournit un moyen de mettre à jour dynamiquement les adresses de ces symboles externes une fois qu'elles sont résolues.
Chaque entrée dans la GOT correspond à un symbole dans les bibliothèques externes que le binaire peut appeler. Lorsqu'une fonction est appelée pour la première fois, son adresse réelle est résolue par le lieur dynamique et stockée dans la GOT. Les appels suivants à la même fonction utilisent l'adresse stockée dans la GOT, évitant ainsi le surcoût de la résolution de l'adresse à nouveau.
PLT : Table de liaison de procédure
La Table de liaison de procédure (PLT) fonctionne en étroite collaboration avec la GOT et sert de trampoline pour gérer les appels aux fonctions externes. Lorsqu'un binaire appelle une fonction externe pour la première fois, le contrôle est transféré à une entrée dans la PLT associée à cette fonction. Cette entrée PLT est responsable d'invoquer le lieur dynamique pour résoudre l'adresse de la fonction si elle n'a pas déjà été résolue. Après que l'adresse soit résolue, elle est stockée dans la GOT.
Par conséquent, les entrées de la GOT sont utilisées directement une fois que l'adresse d'une fonction ou d'une variable externe est résolue. Les entrées de la PLT sont utilisées pour faciliter la résolution initiale de ces adresses via le lieur dynamique.
Obtenir l'exécution
Vérifier la GOT
Obtenez l'adresse de la table GOT avec : objdump -s -j .got ./exec
Observez comment après le chargement de l'exécutable dans GEF, vous pouvez voir les fonctions qui se trouvent dans la GOT : gef➤ x/20x 0xADDR_GOT
En utilisant GEF, vous pouvez démarrer une session de débogage et exécuter got
pour voir la table got :
GOT2Exec
Dans un binaire, la GOT contient les adresses des fonctions ou de la section PLT qui chargera l'adresse de la fonction. L'objectif de cette écriture arbitraire est de remplacer une entrée de la GOT d'une fonction qui sera exécutée plus tard avec l'adresse de la PLT de la fonction system
par exemple.
Idéalement, vous allez remplacer la GOT d'une fonction qui est appelée avec des paramètres contrôlés par vous (vous pourrez ainsi contrôler les paramètres envoyés à la fonction système).
Si system
n'est pas utilisé par le binaire, la fonction système n'aura pas d'entrée dans la PLT. Dans ce scénario, vous devrez d'abord divulguer l'adresse de la fonction system
puis écraser la GOT pour pointer vers cette adresse.
Vous pouvez voir les adresses PLT avec objdump -j .plt -d ./vuln_binary
Entrées GOT de libc
La GOT de libc est généralement compilée avec RELRO partiel, ce qui en fait une bonne cible pour cela, supposant qu'il est possible de déterminer son adresse (ASLR).
Les fonctions courantes de la libc vont appeler d'autres fonctions internes dont la GOT pourrait être écrasée afin d'obtenir une exécution de code.
Trouvez plus d'informations sur cette technique ici.
Free2system
Dans les exploitations de tas CTF, il est courant de pouvoir contrôler le contenu des chunks et à un moment donné même écraser la table GOT. Un simple truc pour obtenir RCE si les gadgets ne sont pas disponibles est d'écraser l'adresse GOT de free
pour pointer vers system
et d'écrire dans un chunk "/bin/sh"
. De cette façon, lorsque ce chunk est libéré, il exécutera system("/bin/sh")
.
Strlen2system
Une autre technique courante consiste à écraser l'adresse GOT de strlen
pour pointer vers system
, donc si cette fonction est appelée avec une entrée utilisateur, il est possible de passer la chaîne "/bin/sh"
et d'obtenir un shell.
De plus, si puts
est utilisé avec une entrée utilisateur, il est possible d'écraser l'adresse GOT de strlen
pour pointer vers system
et de passer la chaîne "/bin/sh"
pour obtenir un shell car puts
appellera strlen
avec l'entrée utilisateur.
One Gadget
Abuser de la GOT depuis le tas
Une façon courante d'obtenir RCE à partir d'une vulnérabilité de tas est d'abuser d'un fastbin afin qu'il soit possible d'ajouter la partie de la table GOT dans le fast bin, de sorte que chaque fois que ce chunk est alloué, il sera possible de remplacer le pointeur d'une fonction, généralement free
.
Ensuite, en pointant free
vers system
et en libérant un chunk où était écrit /bin/sh\x00
, cela exécutera un shell.
Il est possible de trouver un exemple ici.
Protections
La protection Full RELRO est destinée à protéger contre ce type de technique en résolvant toutes les adresses des fonctions lorsque le binaire est démarré et en rendant la table GOT en lecture seule après cela :
Références
- https://ir0nstone.gitbook.io/notes/types/stack/got-overwrite/exploiting-a-got-overwrite
- https://ir0nstone.gitbook.io/notes/types/stack/one-gadgets-and-malloc-hook
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.