ksmbd streams_xattr OOB write → local LPE (CVE-2025-37947)
Tip
Μάθε & εξασκήσου στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξασκήσου στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθε & εξασκήσου στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Περιηγήσου στον πλήρη κατάλογο HackTricks Training για τα assessment tracks (ARTA/GRTA/AzRTA) και στο Linux Hacking Expert (LHE).
Υποστήριξε το HackTricks
- Δες τα subscription plans!
- Γίνε μέλος της 💬 Discord group, της telegram group, ακολούθησε το @hacktricks_live στο X/Twitter, ή δες τη LinkedIn page και το YouTube channel.
- Μοιράσου hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Αυτή η σελίδα τεκμηριώνει ένα deterministic out-of-bounds write στο ksmbd streams handling που επιτρέπει ένα reliable Linux kernel privilege escalation στο Ubuntu 22.04 LTS (5.15.0-153-generic), παρακάμπτοντας KASLR, SMEP, και SMAP χρησιμοποιώντας standard kernel heap primitives (msg_msg + pipe_buffer).
- Επηρεαζόμενο component: fs/ksmbd/vfs.c — ksmbd_vfs_stream_write()
- Primitive: page-overflow OOB write πέρα από ένα 0x10000-byte kvmalloc() buffer
- Preconditions: ksmbd running με ένα authenticated, writable share using vfs streams_xattr
Example smb.conf
[share]
path = /share
vfs objects = streams_xattr
writeable = yes
Root cause (allocation clamped, memcpy at unclamped offset)
- Η συνάρτηση υπολογίζει
size = *pos + count, περιορίζει τοsizeστοXATTR_SIZE_MAX(0x10000) όταν ξεπερνιέται, και επανυπολογίζειcount = (*pos + count) - 0x10000, αλλά εξακολουθεί να κάνειmemcpy(&stream_buf[*pos], buf, count)μέσα σε buffer 0x10000 bytes. Αν*pos ≥ 0x10000ο δείκτης προορισμού είναι ήδη έξω από την allocation, παράγοντας OOB writecountbytes. - Το
streams_xattrαποθηκεύει SMB alternate data streams μέσα σε POSIX extended attributes, οπότε το όριο 0x10000 προκύπτει από το Linux single-xattr size limit και όχι από κάποιο SMB protocol field. Αυτό κάνει το bug πρακτικό μόνο όταν το share ενεργοποιεί ρητάvfs objects = streams_xattrκαι το filesystem υποστηρίζει xattrs.
Why the write offset matters
- Το vulnerable path δεν είναι απλώς “write more than 64KiB”. Το missing check ήταν ότι το
*posδεν validated against the current stream length (v_len) πριν εκτελεστεί η append/copy logic. - Το upstream διόρθωσε αυτό απορρίπτοντας writes όπου
*pos >= v_lenμε-EINVAL. Pre-fix, ένας attacker μπορούσε να επαναχρησιμοποιήσει ένα valid authenticated handle σε ένα named stream και να στείλει ένα raw SMB2 WRITE του οποίου τοfile_offsetήδη δείχνει στο τέλος ή πέρα από το τέλος του υπάρχοντος stream, κάτι που μετατρέπει το post-clampmemcpy()σε deterministic page overflow. - Το public PoC το δείχνει αυτό authenticating with
libsmb2, opening a stream path such as1337:, extractingSessionId/TreeId/FileId, and then sending a handcrafted SMB2 WRITE withfile_offset = 0x10018and a smallLength.
Vulnerable function snippet (ksmbd_vfs_stream_write)
```c // https://elixir.bootlin.com/linux/v5.15/source/fs/ksmbd/vfs.c#L411 static int ksmbd_vfs_stream_write(struct ksmbd_file *fp, char *buf, loff_t *pos, size_t count) { char *stream_buf = NULL, *wbuf; size_t size; ... size = *pos + count; if (size > XATTR_SIZE_MAX) { // [1] clamp allocation, but... size = XATTR_SIZE_MAX; count = (*pos + count) - XATTR_SIZE_MAX; // [1.1] ...recompute count } wbuf = kvmalloc(size, GFP_KERNEL | __GFP_ZERO); // [2] alloc 0x10000 stream_buf = wbuf; memcpy(&stream_buf[*pos], buf, count); // [3] OOB when *pos >= 0x10000 ... kvfree(stream_buf); return err; } ```Κατεύθυνση offset και μήκος OOB
- Παράδειγμα: ορίστε file offset (pos) σε 0x10018 και το αρχικό length (count) σε 8. Μετά το clamping, count’ = (0x10018 + 8) - 0x10000 = 0x20, αλλά το memcpy γράφει 32 bytes ξεκινώντας από stream_buf[0x10018], δηλαδή 0x18 bytes πέρα από το 16-page allocation.
Triggering the bug via SMB streams write
- Χρησιμοποιήστε την ίδια authenticated SMB connection για να ανοίξετε ένα file στο share και εκτελέστε ένα write σε ένα named stream (streams_xattr). Ορίστε file_offset ≥ 0x10000 με μικρό length για να δημιουργήσετε ένα deterministic OOB write ελεγχόμενου μεγέθους.
- Το libsmb2 μπορεί να χρησιμοποιηθεί για authentication και για να κατασκευάσει τέτοια writes over SMB2/3.
- Στην πράξη, η επαναχρησιμοποίηση της negotiated SMB session είναι βολική επειδή το exploit χρειάζεται μόνο να διορθώσει λίγα dynamic fields στο WRITE request (
TreeId,SessionId,FileId) και στη συνέχεια μπορεί να μεταδώσει το malformed packet απευθείας στο ίδιο socket.
Minimal reachability (concept)
// Pseudocode: send SMB streams write with pos=0x0000010018ULL, len=8
smb2_session_login(...);
smb2_open("\\\\host\\share\\file:stream", ...);
smb2_pwrite(fd, payload, 8, 0x0000010018ULL); // yields 32-byte OOB
Συμπεριφορά του allocator και γιατί απαιτείται page shaping
- Το kvmalloc(0x10000, GFP_KERNEL|__GFP_ZERO) ζητά μια allocation order-4 (16 συνεχόμενες pages) από τον buddy allocator όταν το size > KMALLOC_MAX_CACHE_SIZE. Αυτό δεν είναι SLUB cache object.
- Το memcpy συμβαίνει αμέσως μετά το allocation· το post-allocation spraying είναι αναποτελεσματικό. Πρέπει να προ-groom το φυσικό memory ώστε ένας επιλεγμένος target να βρίσκεται ακριβώς μετά το allocated 16-page block.
- Στο Ubuntu, το GFP_KERNEL συχνά αντλεί από τον Unmovable migrate type στο zone Normal. Εξάντλησε τα order-3 και order-4 freelists για να αναγκάσεις τον allocator να σπάσει ένα order-5 block σε ένα γειτονικό order-4 + order-3 pair, και μετά τοποθέτησε ένα order-3 slab (kmalloc-cg-4k) ακριβώς μετά το stream buffer.
Πρακτική στρατηγική page shaping
- Κάνε spray ~1000–2000 msg_msg objects των ~4096 bytes (ταιριάζει στο kmalloc-cg-4k) για να γεμίσεις order-3 slabs.
- Λάβε κάποια messages για να ανοίξεις holes και να ενθαρρύνεις adjacency.
- Ενεργοποίησε το ksmbd OOB επανειλημμένα μέχρι το order-4 stream buffer να προσγειωθεί ακριβώς πριν από ένα msg_msg slab. Χρησιμοποίησε eBPF tracing για να επιβεβαιώσεις addresses και alignment αν είναι διαθέσιμο.
Χρήσιμη παρατηρησιμότητα
# Check per-order freelists and migrate types
sudo cat /proc/pagetypeinfo | sed -n '/Node 0, zone Normal/,/Node/p'
# Example tracer (see reference repo) to log kvmalloc addresses/sizes
sudo ./bpf-tracer.sh
Τι να παρακολουθείς κατά το tuning
kvmalloc_node(0x10000)επιβεβαιώνει πότε το ευάλωτο stream write καταναλώνει πραγματικά μια allocation order-4.load_msg/kretprobe:load_msgσου επιτρέπει να εκτιμήσεις πόσεςmsg_msgsegallocations είναι attached σε κάθε sprayed message, κάτι που είναι χρήσιμο όταν κάνεις tuning τα primary/secondary message sizes για συγκεκριμένο kernel build.- Αν το exploit portαριστεί σε διαφορετικό distro/kernel, έλεγξε ξανά cache names, inline
msg_msgpayload sizes, offsets τουanon_pipe_buf_ops, και gadget addresses αντί να υποθέτεις ότι οι constants του Ubuntu 22.04 LTS5.15.0-153-genericεξακολουθούν να ταιριάζουν.
Σχέδιο exploitation (msg_msg + pipe_buffer), προσαρμοσμένο από το CVE-2021-22555
- Spraye πολλά System V msg_msg primary/secondary messages (4KiB-sized για να χωρέσουν στο kmalloc-cg-4k).
- Trigger το ksmbd OOB για να corrupt το next pointer ενός primary message έτσι ώστε δύο primaries να μοιράζονται ένα secondary.
- Ανίχνευσε το corrupted pair tagάροντας queues και κάνοντας scan με msgrcv(MSG_COPY) για να βρεις mismatched tags.
- Κάνε free το πραγματικό secondary για να δημιουργήσεις ένα UAF; reclaim it με controlled data μέσω UNIX sockets (craft ένα fake msg_msg).
- Leak kernel heap pointers abuse-άροντας το m_ts over-read στο copy_msg για να πάρεις mlist.next/mlist.prev (SMAP bypass).
- Με ένα sk_buff spray, ξαναχτίσε ένα συνεπές fake msg_msg με valid links και κάν’ το free κανονικά για να σταθεροποιήσεις την κατάσταση.
- Reclaim το UAF με struct pipe_buffer objects; leak το anon_pipe_buf_ops για να υπολογίσεις kernel base (defeat KASLR).
- Spray ένα fake pipe_buf_operations με release που δείχνει σε ένα stack pivot/ROP gadget; close pipes για να εκτελεστεί και να αποκτήσεις root.
Bypasses και notes
- KASLR: leak το anon_pipe_buf_ops, υπολόγισε base (kbase_addr) και gadget addresses.
- SMEP/SMAP: εκτέλεσε ROP σε kernel context μέσω της ροής pipe_buf_operations->release; απόφυγε userspace derefs μέχρι μετά το disable/prepare_kernel_cred/commit_creds chain.
- Hardened usercopy: δεν ισχύει για αυτό το page overflow primitive; οι corruption targets είναι non-usercopy fields.
Reliability
- Υψηλό μόλις επιτευχθεί adjacency; περιστασιακά misses ή panics (<10%). Το tuning στα spray/free counts βελτιώνει τη σταθερότητα. Το overwrite δύο LSBs ενός pointer για να προκληθούν συγκεκριμένες collisions αναφέρθηκε ως αποτελεσματικό (π.χ. γράψε pattern 0x0000_0000_0000_0500 στο overlap).
Key parameters to tune
- Number of msg_msg sprays and hole pattern
- OOB offset (pos) and resulting OOB length (count’)
- Number of UNIX socket, sk_buff, and pipe_buffer sprays during each stage
Mitigations and reachability
- Fix: clamp both allocation and destination/length or bound memcpy against the allocated size; upstream patches track as CVE-2025-37947.
- Remote exploitation would additionally require a reliable infoleak and remote heap grooming; this write-up focuses on local LPE.
See also
Ksmbd Attack Surface And Fuzzing Syzkaller
References PoC and tooling
- libsmb2 for SMB auth and streams writes
- eBPF tracer script to log kvmalloc addresses and histogram allocations (e.g., grep 4048 out-4096.txt)
- Minimal reachability PoC and full local exploit are publicly available (see References)
References
- ksmbd - Exploiting CVE-2025-37947 (3/3) — Doyensec
- Linux upstream fix:
ksmbd: prevent out-of-bounds stream writes by validating *pos - KSMBD-CVE-2025-37947 PoC repository
Tip
Μάθε & εξασκήσου στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθε & εξασκήσου στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθε & εξασκήσου στο Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Περιηγήσου στον πλήρη κατάλογο HackTricks Training για τα assessment tracks (ARTA/GRTA/AzRTA) και στο Linux Hacking Expert (LHE).
Υποστήριξε το HackTricks
- Δες τα subscription plans!
- Γίνε μέλος της 💬 Discord group, της telegram group, ακολούθησε το @hacktricks_live στο X/Twitter, ή δες τη LinkedIn page και το YouTube channel.
- Μοιράσου hacking tricks υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


