Que fait arbitrary-write-to-rce ?
Playbook pour transformer une écriture arbitraire en exécution de code (RCE). À utiliser lorsque vous disposez d'une primitive d'écriture arbitraire (exploitation du tas, chaîne de format, écriture hors limites) et devez la convertir en exécution de code en ciblant GOT, hooks, _IO_FILE vtable, exit_funcs, TLS_dtor_list, modprobe_path, .fini_array ou les vtables C++.
Vue d'ensemble
Ce playbook fournit une méthodologie structurée pour exploiter une vulnérabilité d'écriture arbitraire. Il suppose que vous avez déjà identifié une primitive d'écriture arbitraire et que vous cherchez à obtenir une exécution de code.
Prérequis
- Une primitive d'écriture arbitraire (ex :
write(adresse, valeur)) - Connaître l'architecture cible (x86, x64, ARM, etc.)
- Comprendre les protections de l'exécutable (ASLR, NX, PIE, RELRO, Stack Canaries)
- Avoir un environnement de débogage (GDB, pwntools, etc.)
Cibles principales
| Cible | Condition | Facilité | Remarques |
|---|---|---|---|
| GOT | RELRO partiel | Élevée | Classique, surcharge de fonctions résolues |
Hooks (e.g. __free_hook, __malloc_hook) | GLIBC < 2.34 | Élevée | Préféré pour libc |
_IO_FILE vtable | Fichier maîtrisé | Moyenne | Exploitation via _IO_str_overflow ou _IO_wstr_overflow |
exit_funcs | GLIBC | Moyenne | Appelé lors de exit() ou retour de main |
TLS_dtor_list | GLIBC | Moyenne | Exécution lors de __call_tls_dtors |
modprobe_path | Linux kernel | Faible | Nécessite modprobe_path accessible |
.fini_array | Exécutable | Faible | Appelé lors de la terminaison du programme |
| C++ vtable | Objet C++ | Variable | Surcharge de la vtable d'un objet existant |
Méthodologie générale
- Cartographie des cibles : Déterminez les cibles disponibles (adresses, protections, versions).
- Calcul des décalages : Calculez les offsets nécessaires pour chaque cible potentielle.
- Construction de la charge utile : Écrivez les valeurs souhaitées aux adresses cibles en utilisant votre primitive.
- Déclenchement : Provoquez l'exécution du code via le mécanisme ciblé (appel de fonction, exception, etc.).
- Vérification : Validez que l'exécution de code a réussi (shell, lecture de fichier, etc.).
Exemple de code (Python avec pwntools)
from pwn import *
# Connexion ou processus local
p = process('./vuln')
# Adresses (à adapter)
free_hook = 0x7f1234567890
system_addr = 0x7f0987654321
# Écriture arbitraire sur free_hook
write_arbitrary(free_hook, system_addr)
# Déclenchement via free
trigger_free()
# Interaction
p.interactive()
Dépannage
- Segfault : Vérifiez l'alignement des adresses, la présence de canaris, ou les protections exécutables de la mémoire.
- Pas d'exécution : Assurez-vous que la cible est bien déréférencée et que la valeur écrite est correcte (adresse de la fonction shell).
- RELRO complet : Utilisez une autre technique (hooks, vtable, etc.).