VirtualBox Slirp NAT Packet Heap Exploitation
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
TL;DR
- Το VirtualBox διαθέτει ένα έντονα τροποποιημένο fork του Slirp, όπου οι packet buffers (mbufs) βρίσκονται σε έναν προσαρμοσμένο zone allocator με inline metadata και function-pointer callbacks (
pfFini,pfDtor). - Ένας guest μπορεί να επανεγγράψει το αξιόπιστο
m->m_lenμε μήκος κεφαλίδας IP που ελέγχεται από τον επιτιθέμενο, το οποίο καταστρέφει όλους τους επακόλουθους ελέγχους ορίων και παρέχει τόσο infoleak όσο και overwrite primitives. - Καταχρηστικά χρησιμοποιώντας UDP πακέτα με checksum
0και υπερμεγέθεςip_len, ο guest μπορεί να εξάγει τα mbuf tails και τα metadata των γειτονικών chunks για να μάθει τις διευθύνσεις του heap και της zone. - Η παροχή επιμελώς κατασκευασμένων IP options αναγκάζει το
ip_stripoptions()να κάνειmemcpy()υπερβολική ποσότητα δεδομένων επιτόπου, επιτρέποντας στον επιτιθέμενο να επαναγράψει τηνstruct itemκεφαλίδα της επόμενης mbuf και να δείξει το πεδίοzoneσε πλήρως ελεγχόμενα δεδομένα. - Η απελευθέρωση της κατεστραμμένης mbuf ενεργοποιεί το
zone->pfFini()με επιχειρήματα που παρέχονται από τον επιτιθέμενο· δείχνοντάς το προςmemcpy@pltαυτό δίνει ένα αυθαίρετο copy/write primitive που μπορεί να κατευθυνθεί προς GOT entries ή άλλα control δεδομένα μέσα στο non-PIE VirtualBox binary.
Packet allocator anatomy
VirtualBox allocates every ingress Ethernet frame from a per-interface zone named zone_clust. Each 0x800-byte data chunk is preceded by an inline header:
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
};
Όταν ένα mbuf απελευθερώνεται, η στοίβα κλήσεων m_freem -> ... -> slirp_uma_free() εμπιστεύεται την ενσωματωμένη κεφαλίδα:
uma_zfree_arg()επανυπολογίζειitem = (struct item *)mem - 1και θα έπρεπε να επικυρώνειitem->zone, αλλά τοAssert()δεν περιλαμβάνεται στις release builds.slirp_uma_free()φορτώνειzone = item->zoneκαι εκτελεί χωρίς όρουςzone->pfFini(zone->pData, data_ptr, zone->size)ακολουθούμενο απόzone->pfDtor(...).
Επομένως, οποιοδήποτε write-what-where στην κεφαλίδα του mbuf μεταφράζεται σε έναν ελεγχόμενο indirect call κατά το free().
Infoleak via m->m_len override
Στην αρχή του ip_input() η VirtualBox πρόσθεσε:
if (m->m_len != RT_N2H_U16(ip->ip_len))
m->m_len = RT_N2H_U16(ip->ip_len);
Because the assignment happens before verifying the IP header, a guest can advertise any length up to 0xffff. The rest of the stack (ICMP, UDP, fragmentation handlers, etc.) assumes m->m_len is trustworthy and uses it to decide how many bytes to copy off the mbuf.
Use UDP packets with checksum 0 (meaning “no checksum”). The NAT fast-path forwards m->m_len bytes without inspecting payload integrity, so inflating ip_len causes Slirp to read past the real buffer and return heap residues to the guest or to a cooperating external helper beyond the NAT. Because the chunk size is 2048 bytes, the leak can include:
- The next mbuf’s inline
struct item, revealing the freelist order and the realzonepointer. - Heap cookies such as
magicfields, helping to craft valid-looking headers when performing corruptions later.
Επανεγγραφή των επικεφαλίδων γειτονικών chunks με IP options
Το ίδιο ψευδές μήκος μπορεί να μετατραπεί σε primitive εγγραφής αναγκάζοντας το πακέτο να περάσει από ip_stripoptions() (προκαλείται όταν το IP header έχει options και το payload είναι UDP/TCP). Ο helper υπολογίζει ένα μήκος αντιγραφής από το m->m_len και μετά καλεί memcpy() για να μετακινήσει το transport header πάνω από τα stripped options:
- Προμηθεύστε ένα μεγάλο
ip_lenώστε το υπολογιζόμενο μήκος μετακίνησης να επεκταθεί πέρα από το τρέχον mbuf. - Συμπεριλάβετε έναν μικρό αριθμό IP options ώστε το Slirp να μπει στη διαδρομή stripping.
- Όταν τρέξει το
memcpy(), θα διαβάσει από το επόμενο mbuf και θα γράψει πάνω στο payload και το inline header του τρέχοντος mbuf, διαφθείρονταςmagic,zone,ref_count, κ.λπ.
Επειδή ο allocator κρατά τα πακέτα από την ίδια interface συνεχή στη freelist, αυτό το overflow πλήττει με ντετερμινιστικό τρόπο το επόμενο chunk μετά από μέτριο heap grooming.
Forge uma_zone_t για hijack του pfFini
Μόλις το διπλανό struct item είναι επιρρεπές σε φθορά, το exploit προχωρά ως εξής:
- Χρησιμοποιήστε leaked heap διευθύνσεις για να χτίσετε μια ψεύτικη δομή
uma_zoneμέσα σε ένα mbuf πλήρως ελεγχόμενο από τον guest. Συμπληρώστε:pfFiniμε την PLT είσοδο τουmemcpy().pDataμε τον επιθυμητό δείκτη προορισμού (π.χ. GOT entry, vtable slot, function pointer array).sizeμε τον αριθμό των byte προς αντιγραφή.- Προαιρετικά:
pfDtorως δεύτερο στάδιο κλήσης (π.χ. για να καλεί το νεογραμμένο function pointer).
- Επανεγγράψτε το πεδίο
zoneτου στοχευόμενου mbuf με τον pointer προς την ψεύτικη δομή· ρυθμίστε τους δείκτεςlistώστε η bookkeeping της freelist να παραμένει αρκετά συνεπής για να αποφευχθούν crashes. - Free το mbuf. Το
slirp_uma_free()τώρα εκτελείmemcpy(dest=pData, src=item_data, n=size)ενώ το mbuf εξακολουθεί να περιέχει δεδομένα ελεγχόμενα από τον guest, δίνοντας ένα arbitrary write.
Επειδή το Linux VirtualBox binary είναι non-PIE, οι PLT διευθύνσεις για memcpy και system είναι σταθερές και μπορούν να χρησιμοποιηθούν απευθείας. Ο guest μπορεί επίσης να τοποθετήσει strings όπως /bin/sh μέσα σε άλλο mbuf που παραμένει referenced όταν εκτελείται η hijacked κλήση.
Grooming του heap μέσω fragmentation
Η per-interface zone του Slirp έχει βάθος 3072 chunks και αρχικά carve-άρεται ως ένα συνεκτικό array του οποίου η freelist διασχίζεται από διευθύνσεις με υψηλότερη προς χαμηλότερη. Μπορεί να επιτευχθεί ντετερμινιστική γειτνίαση μέσω:
- Flooding του NAT με πολλά
IP_MFfragments σταθερού μεγέθους ώστε ο κώδικας reassembly να κάνει predictable allocations σε ακολουθίες mbuf. - Recycling συγκεκριμένων chunks στέλνοντας fragments που λήγουν (time out), αναγκάζοντας frees πίσω στη freelist σε LIFO σειρά.
- Χρησιμοποίηση της γνώσης του freelist walk για να τοποθετήσετε το μελλοντικό victim mbuf αμέσως μετά το mbuf που θα μεταφέρει το IP options overflow.
Αυτό το grooming διασφαλίζει ότι το overflow χτυπά το στοχευμένο struct item και ότι η ψεύτικη uma_zone παραμένει εντός ορίων του leak primitive.
Από arbitrary write σε εκτέλεση κώδικα στον host
Με το memcpy-on-free primitive:
- Αντιγράψτε ένα attacker-controlled
/bin/shstring και buffer εντολών σε ένα σταθερό mbuf. - Χρησιμοποιήστε το primitive για να επανεγγράψετε ένα GOT entry ή ένα indirect callsite (π.χ. έναν function pointer μέσα στο NAT device state) με την PLT είσοδο του
system(). - Ενεργοποιήστε την επανεγγραμμένη κλήση. Επειδή ο VirtualBox τρέχει τη NAT device μέσα στη διεργασία του host, το payload εκτελείται με τα προνόμια του χρήστη που τρέχει τον VirtualBox, επιτρέποντας guest-to-host escape.
Εναλλακτικά payloads περιλαμβάνουν το φύτεμα μιας μικρής ROP αλυσίδας στη μνήμη heap και την αντιγραφή της διεύθυνσής της σε ένα συχνά κληθέν callback, ή την αναστοχαστική στόχευση των pfFini/pfDtor οι ίδιοι προς chained gadgets για επαναλαμβανόμενες εγγραφές.
References
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


