ksmbd streams_xattr OOB write → local LPE (CVE-2025-37947)
Tip
Impara e pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord, al gruppo telegram, segui @hacktricks_live su X/Twitter, oppure controlla la pagina LinkedIn e il canale YouTube.
- Condividi hacking tricks inviando PR ai repository github HackTricks e HackTricks Cloud.
Questa pagina documenta una deterministica out-of-bounds write in ksmbd streams handling che consente una reliable Linux kernel privilege escalation su Ubuntu 22.04 LTS (5.15.0-153-generic), bypassando KASLR, SMEP e SMAP usando standard kernel heap primitives (msg_msg + pipe_buffer).
- Componente interessato: fs/ksmbd/vfs.c — ksmbd_vfs_stream_write()
- Primitive: page-overflow OOB write oltre un buffer kvmalloc() da 0x10000 byte
- Preconditions: ksmbd in esecuzione con una share autenticata e scrivibile che usa vfs streams_xattr
Esempio smb.conf
[share]
path = /share
vfs objects = streams_xattr
writeable = yes
Root cause (allocation clamped, memcpy at unclamped offset)
- La funzione calcola size = *pos + count, limita size a XATTR_SIZE_MAX (0x10000) quando viene superato, e ricalcola count = (*pos + count) - 0x10000, ma esegue comunque memcpy(&stream_buf[*pos], buf, count) dentro un buffer da 0x10000 byte. Se *pos ≥ 0x10000 il puntatore di destinazione è già fuori dall’allocazione, producendo una OOB write di count byte.
streams_xattrmemorizza gli SMB alternate data streams dentro gli extended attributes POSIX, quindi il limite 0x10000 deriva dal limite Linux della dimensione di un singolo xattr e non da un campo del protocollo SMB. Questo rende il bug pratico solo quando la share abilita esplicitamentevfs objects = streams_xattre il filesystem supporta xattrs.
Why the write offset matters
- Il percorso vulnerabile non è solo “scrivere più di 64KiB”. Il controllo mancante era che
*posnon venisse validato rispetto alla lunghezza corrente dello stream (v_len) prima che venisse eseguita la logica di append/copy. - Upstream ha corretto questo rifiutando le scritture in cui
*pos >= v_lencon-EINVAL. Prima della correzione, un attacker poteva riutilizzare un handle autenticato valido verso uno stream nominato e inviare una raw SMB2 WRITE il cuifile_offsetpunta già alla fine o oltre la fine dello stream esistente, trasformando lamemcpy()post-clamp in un overflow di pagina deterministico. - Il PoC pubblico dimostra questo autenticandosi con
libsmb2, aprendo un percorso di stream come1337:, estraendoSessionId/TreeId/FileId, e poi inviando una SMB2 WRITE costruita manualmente confile_offset = 0x10018e unLengthridotto.
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 steering and OOB length
- Esempio: imposta l’offset del file (pos) a 0x10018 e la lunghezza originale (count) a 8. Dopo il clamping, count’ = (0x10018 + 8) - 0x10000 = 0x20, ma memcpy scrive 32 byte a partire da stream_buf[0x10018], cioè 0x18 byte oltre l’allocazione di 16 pagine.
Triggering the bug via SMB streams write
- Usa la stessa connessione SMB autenticata per aprire un file sullo share e inviare una write a uno stream nominato (streams_xattr). Imposta file_offset ≥ 0x10000 con una lunghezza piccola per generare una OOB write deterministica di dimensione controllabile.
- libsmb2 può essere usato per autenticarsi e creare tali write su SMB2/3.
- In pratica, riutilizzare la sessione SMB negoziata è comodo perché l’exploit deve solo patchare alcuni campi dinamici nella richiesta WRITE (
TreeId,SessionId,FileId) e può quindi trasmettere direttamente il pacchetto malformato sullo stesso 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
Comportamento dell’allocator e perché è richiesta la page shaping
- kvmalloc(0x10000, GFP_KERNEL|__GFP_ZERO) richiede un’allocazione order-4 (16 pagine contigue) dal buddy allocator quando la size > KMALLOC_MAX_CACHE_SIZE. Questo non è un oggetto della SLUB cache.
- memcpy avviene immediatamente dopo l’allocazione; lo spraying post-allocazione è inefficace. Devi pre-groomare la memoria fisica in modo che un target scelto si trovi immediatamente dopo il blocco allocato di 16 pagine.
- Su Ubuntu, GFP_KERNEL spesso prende dall’Unmovable migrate type in zone Normal. Esaurisci le freelist order-3 e order-4 per forzare l’allocator a dividere un blocco order-5 in una coppia adiacente order-4 + order-3, poi parcheggia uno slab order-3 (kmalloc-cg-4k) direttamente dopo il buffer dello stream.
Strategia pratica di page shaping
- Spamma ~1000–2000 oggetti msg_msg di ~4096 byte (si adatta a kmalloc-cg-4k) per popolare gli slab order-3.
- Ricevi alcuni messaggi per creare buchi e favorire l’adiacenza.
- Triggera ripetutamente il ksmbd OOB finché il buffer dello stream order-4 non si posiziona immediatamente prima di uno slab msg_msg. Usa eBPF tracing per confermare address e alignment, se disponibile.
Osservabilità utile
# 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
Cosa tracciare durante il tuning
kvmalloc_node(0x10000)conferma quando la vulnerable stream write consuma effettivamente un’allocazione order-4.load_msg/kretprobe:load_msgti permette di stimare quante allocazionimsg_msgsegsono collegate a ciascun messaggio sprayed, il che è utile quando si tunano le dimensioni dei messaggi primary/secondary per uno specifico kernel build.- Se l’exploit viene portato su una distro/kernel diversi, ricontrolla i nomi delle cache, le dimensioni inline del payload
msg_msg, gli offset dianon_pipe_buf_opse gli indirizzi dei gadget invece di assumere che le costanti Ubuntu 22.04 LTS5.15.0-153-genericsiano ancora valide.
Piano di exploitation (msg_msg + pipe_buffer), adattato da CVE-2021-22555
- Spray molti messaggi System V
msg_msgprimary/secondary (dimensione 4KiB per adattarsi akmalloc-cg-4k). - Trigger ksmbd OOB per corrompere il next pointer di un messaggio primary in modo che due primaries condividano un secondary.
- Rileva la coppia corrotta taggando le code e scansionando con
msgrcv(MSG_COPY)per trovare tag non corrispondenti. - Libera il vero secondary per creare una UAF; reclamalo con dati controllati tramite UNIX sockets (craft di un fake
msg_msg). - Leak dei puntatori della kernel heap abusando del m_ts over-read in
copy_msgper otteneremlist.next/mlist.prev(SMAP bypass). - Con uno spray di
sk_buff, ricostruisci un coerente fakemsg_msgcon link validi e liberalo normalmente per stabilizzare lo stato. - Reclaim della UAF con oggetti
struct pipe_buffer; leak dianon_pipe_buf_opsper calcolare la kernel base (defeat KASLR). - Spray di un fake
pipe_buf_operationsconreleaseche punta a un stack pivot/ROP gadget; chiudi i pipes per eseguire e ottenere root.
Bypasses and notes
- KASLR: leak
anon_pipe_buf_ops, calcola la base (kbase_addr) e gli indirizzi dei gadget. - SMEP/SMAP: esegui ROP in kernel context tramite il flusso
pipe_buf_operations->release; evita deref verso userspace fino a dopo la catenadisable/prepare_kernel_cred/commit_creds. - Hardened usercopy: non applicabile a questo primitive di page overflow; i target della corruption sono campi non-usercopy.
Reliability
- Alta una volta ottenuta l’adjacency; occasionali miss o panic (<10%). Tuning dei conteggi di spray/free migliora la stabilità. È stato riportato come efficace sovrascrivere i due LSB di un puntatore per indurre collisioni specifiche (ad es. scrivere il pattern
0x0000_0000_0000_0500nell’overlap).
Key parameters to tune
- Numero di spray
msg_msge pattern dei hole - OOB offset (pos) e conseguente lunghezza OOB (count’)
- Numero di spray UNIX socket,
sk_buffepipe_bufferdurante ogni stage
Mitigations and reachability
- Fix: clamp sia allocation sia destination/length oppure limita
memcpyrispetto alla dimensione allocata; le patch upstream tracciano il problema come CVE-2025-37947. - L’exploitation remota richiederebbe inoltre un infoleak affidabile e un remote heap grooming; questa write-up si concentra su LPE locale.
See also
Ksmbd Attack Surface And Fuzzing Syzkaller
References PoC and tooling
- libsmb2 per SMB auth e streams writes
- script tracer eBPF per loggare gli indirizzi
kvmalloce creare un istogramma delle allocazioni (ad es.grep 4048 out-4096.txt) - Un PoC minimo di reachability e l’exploit locale completo sono pubblicamente disponibili (vedi 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
Impara e pratica AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica Az Hacking:HackTricks Training Azure Red Team Expert (AzRTE)
Sfoglia il catalogo completo di HackTricks Training per i percorsi di assessment (ARTA/GRTA/AzRTA) e Linux Hacking Expert (LHE).
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al 💬 gruppo Discord, al gruppo telegram, segui @hacktricks_live su X/Twitter, oppure controlla la pagina LinkedIn e il canale YouTube.
- Condividi hacking tricks inviando PR ai repository github HackTricks e HackTricks Cloud.


