VirtualBox Slirp NAT Packet Heap Exploitation
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)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
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 PR au HackTricks et HackTricks Cloud dépôts github.
TL;DR
- VirtualBox distribue un fork fortement modifié de Slirp dont les packet buffers (mbufs) résident dans un allocateur de zones personnalisé avec des métadonnées inline et des callbacks par pointeur de fonction (
pfFini,pfDtor). - Un invité peut réécrire le
m->m_lende confiance avec une longueur d’en-tête IP contrôlée par l’attaquant, ce qui annule tous les contrôles de limites ultérieurs et fournit à la fois des primitives d’infoleak et d’overwrite. - En abusant de paquets UDP avec checksum
0et unip_lensurdimensionné, le guest peut exfiltrer les mbuf tails et les métadonnées des chunks voisins pour apprendre les adresses du heap et de la zone. - Fournir des options IP spécialement fabriquées force
ip_stripoptions()àmemcpy()trop de données en place, de sorte que l’attaquant peut écraser l’en-têtestruct itemdu mbuf suivant et orienter son champzonevers des données entièrement contrôlées. - La libération du mbuf corrompu déclenche
zone->pfFini()avec des arguments fournis par l’attaquant ; le pointer versmemcpy@pltdonne une primitive de copie/écriture arbitraire qui peut être dirigée vers des entrées GOT ou d’autres données de contrôle à l’intérieur du binaire VirtualBox non-PIE.
Packet allocator anatomy
VirtualBox alloue chaque trame Ethernet entrante depuis une zone par interface nommée zone_clust. Chaque chunk de données de 0x800 octets est précédé d’un en-tête inline:
struct item {
uint32_t magic; // 0xdead0001
void *zone; // uma_zone_t pointer with callbacks
uint32_t ref_count;
LIST_ENTRY(item) list; // freelist / used list links
};
Quand un mbuf est libéré la pile d’appels m_freem -> ... -> slirp_uma_free() fait confiance à l’en-tête inline :
uma_zfree_arg()recalculatesitem = (struct item *)mem - 1et devrait valideritem->zone, maisAssert()est compilé hors des builds release.slirp_uma_free()litzone = item->zoneet exécute sans conditionzone->pfFini(zone->pData, data_ptr, zone->size)suivi dezone->pfDtor(...).
Donc, tout write-what-where dans l’en-tête du mbuf se traduit par un appel indirect contrôlé pendant free().
Infoleak via m->m_len override
Au début de ip_input() VirtualBox a ajouté:
if (m->m_len != RT_N2H_U16(ip->ip_len))
m->m_len = RT_N2H_U16(ip->ip_len);
Parce que l’affectation a lieu avant la vérification de l’en-tête IP, un invité peut annoncer n’importe quelle longueur jusqu’à 0xffff. Le reste de la pile (ICMP, UDP, gestionnaires de fragmentation, etc.) suppose que m->m_len est fiable et l’utilise pour décider combien d’octets copier depuis le mbuf.
Utilisez des paquets UDP avec checksum 0 (signifiant “no checksum”). Le fast-path NAT transmet m->m_len octets sans vérifier l’intégrité du payload, donc gonfler ip_len fait que Slirp lit au-delà du véritable tampon et renvoie des résidus du heap vers l’invité ou vers un helper externe coopérant au-delà du NAT. Parce que la taille du chunk est de 2048 octets, le leak peut inclure :
- Le
struct iteminline du mbuf suivant, révélant l’ordre de la freelist et le pointeur réelzone. - Des cookies du heap tels que les champs
magic, aidant à fabriquer des en-têtes plausibles lors de corruptions ultérieures.
Overwriting neighbouring chunk headers with IP options
La même longueur falsifiée peut être transformée en primitive d’overwrite en forçant le paquet à passer par ip_stripoptions() (déclenché lorsque l’en-tête IP contient des options et que le payload est UDP/TCP). Le helper calcule une longueur de copie à partir de m->m_len puis appelle memcpy() pour décaler l’en-tête transport par-dessus les options supprimées :
- Fournir un
ip_lenlong de sorte que la longueur de déplacement calculée dépasse le mbuf courant. - Inclure un petit nombre d’options IP pour que Slirp entre dans le chemin de stripping.
- Quand
memcpy()s’exécute, il lit depuis le mbuf suivant et écrit par-dessus le payload du mbuf courant et l’en-tête inline, corrompantmagic,zone,ref_count, etc.
Parce que l’allocator garde les paquets de la même interface contigus sur la freelist, cet overflow atteint de manière déterministe le chunk suivant après un grooming modéré du heap.
Forging uma_zone_t to hijack pfFini
Une fois que le struct item adjacent est corruptible, l’exploit procède comme suit :
- Utiliser les adresses heap leakées pour construire une fausse structure
uma_zoneà l’intérieur d’un mbuf entièrement contrôlé par l’invité. Remplir :pfFiniavec l’entrée PLT dememcpy().pDataavec le pointeur de destination souhaité (par ex. entrée GOT, slot de vtable, tableau de pointeurs de fonction).sizeavec le nombre d’octets à copier.- Optionnel :
pfDtorcomme appel de second stade (par ex. pour invoquer le pointeur de fonction nouvellement écrit).
- Écraser le champ
zonedu mbuf cible avec le pointeur vers la fausse structure ; ajuster les pointeurslistpour que la tenue de la freelist reste suffisamment cohérente afin d’éviter des plantages. - Libérer le mbuf.
slirp_uma_free()exécute maintenantmemcpy(dest=pData, src=item_data, n=size)alors que le mbuf contient encore des données contrôlées par l’invité, aboutissant à une écriture arbitraire.
Puisque le binaire VirtualBox sous Linux n’est pas PIE, les adresses PLT de memcpy et system sont fixes et peuvent être utilisées directement. L’invité peut aussi stocker des chaînes comme /bin/sh dans un autre mbuf qui reste référencé lorsque l’appel détourné s’exécute.
Heap grooming via fragmentation
La zone par interface de Slirp contient 3072 chunks et est initialement découpée comme un tableau contigu dont la freelist est parcourue des adresses hautes vers le bas. Une adjacency déterministe peut être obtenue en :
- Inonder le NAT avec de nombreux fragments
IP_MFde taille constante afin que le code de réassemblage alloue des séquences d’mbuf prévisibles. - Recycler des chunks spécifiques en envoyant des fragments qui expirent, forçant des frees retournant dans la freelist en ordre LIFO.
- Utiliser la connaissance du parcours de la freelist pour placer le mbuf victime futur juste après le mbuf qui portera l’overflow des options IP.
Ce grooming garantit que l’overflow atteint le struct item ciblé et que la fausse uma_zone reste dans les limites de la primitive de leak.
From arbitrary write to host code execution
Avec la primitive memcpy-on-free :
- Copier une chaîne
/bin/shcontrôlée par l’attaquant et le buffer de commande dans un mbuf stable. - Utiliser la primitive pour écraser une entrée GOT ou un callsite indirect (par ex. un pointeur de fonction dans l’état du device NAT) avec l’entrée PLT de
system(). - Déclencher l’appel écrasé. Parce que VirtualBox exécute le device NAT à l’intérieur du processus hôte, le payload s’exécute avec les privilèges de l’utilisateur lançant VirtualBox, permettant une fuite du guest vers l’hôte.
Les payloads alternatifs incluent planter une mini ROP chain dans la mémoire heap et copier son adresse dans un callback fréquemment invoqué, ou repointer pfFini/pfDtor eux-mêmes vers des gadgets chaînés pour des écritures répétées.
Références
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)
Apprenez et pratiquez le hacking Azure :
HackTricks Training Azure Red Team Expert (AzRTE)
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 PR au HackTricks et HackTricks Cloud dépôts github.
HackTricks

