ksmbd streams_xattr OOB write → local LPE (CVE-2025-37947)
Reading time: 7 minutes
tip
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
Ukurasa huu unaelezea deterministic out-of-bounds write katika kushughulikia streams za ksmbd ambayo inaruhusu reliable Linux kernel privilege escalation kwenye Ubuntu 22.04 LTS (5.15.0-153-generic), ikivuka KASLR, SMEP, na SMAP kwa kutumia standard kernel heap primitives (msg_msg + pipe_buffer).
- Sehemu iliyohusishwa: fs/ksmbd/vfs.c — ksmbd_vfs_stream_write()
- Primitive: page-overflow OOB write past a 0x10000-byte kvmalloc() buffer
- Masharti ya awali: ksmbd ikifanya kazi na share iliyothibitishwa na inayoweza kuandikwa ikitumia vfs streams_xattr
Mfano smb.conf
[share]
path = /share
vfs objects = streams_xattr
writeable = yes
Sababu ya msingi (allocation clamped, memcpy at unclamped offset)
- Kazi inahesabu size = *pos + count, inabana size hadi XATTR_SIZE_MAX (0x10000) inapozidi, na inahesabu tena count = (*pos + count) - 0x10000, lakini bado inafanya memcpy(&stream_buf[*pos], buf, count) ndani ya 0x10000-byte buffer. Ikiwa *pos ≥ 0x10000 pointer ya lengo tayari iko nje ya allocation, ikisababisha OOB write ya count bytes.
Kipande cha function iliyo dhaifu (ksmbd_vfs_stream_write)
// 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
- Mfano: weka file offset (pos) kwa 0x10018 na original length (count) kuwa 8. After clamping, count' = (0x10018 + 8) - 0x10000 = 0x20, lakini memcpy inaandika 32 bytes ikianza kwenye stream_buf[0x10018], yaani, 0x18 bytes zaidi ya ugawaji wa kurasa 16.
Triggering the bug via SMB streams write
- Tumia muunganisho wa SMB uliothibitishwa ule ule kufungua file kwenye share na kutuma write kwa named stream (streams_xattr). Weka file_offset ≥ 0x10000 kwa length ndogo ili kuzalisha deterministic OOB write ya ukubwa unaoweza kudhibiti.
- libsmb2 inaweza kutumika kuthibitisha na kutengeneza writes kama hizo juu ya SMB2/3.
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 behavior and why page shaping is required
- kvmalloc(0x10000, GFP_KERNEL|__GFP_ZERO) requests an order-4 (16 contiguous pages) allocation from the buddy allocator when size > KMALLOC_MAX_CACHE_SIZE. This is not a SLUB cache object.
- memcpy occurs immediately after allocation; post-allocation spraying is ineffective. Lazima utayarisha kumbukumbu ya kimwili kabla (pre-groom) ili lengo ulilochagua liwe mara moja baada ya block ya kurasa 16 iliyopewa.
- On Ubuntu, GFP_KERNEL often pulls from the Unmovable migrate type in zone Normal. Tala order-3 na order-4 freelists hadi zichoke (exhaust) ili kulazimisha allocator kugawa block ya order-5 kuwa jozi jirani ya order-4 + order-3, kisha park slab ya order-3 (kmalloc-cg-4k) moja kwa moja baada ya stream buffer.
Practical page shaping strategy
- Spray ~1000–2000 msg_msg objects of ~4096 bytes (fits kmalloc-cg-4k) to populate order-3 slabs.
- Pokea baadhi ya messages ili punch holes na kuhimiza adjacency.
- Trigger the ksmbd OOB repeatedly until the order-4 stream buffer lands immediately before a msg_msg slab. Tumia eBPF tracing kuthibitisha addresses na alignment ikiwa zinapatikana.
Useful observability
# 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
Mpango wa eksploit (msg_msg + pipe_buffer), umeadaptishwa kutoka CVE-2021-22555
- Spray many System V msg_msg primary/secondary messages (4KiB-sized to fit kmalloc-cg-4k).
- Sababisha ksmbd OOB ili kuharibu pointer ya next ya primary message ili primaries mbili zishirikiane secondary moja.
- Tambua jozi iliyoharibika kwa kutegea queues na kusaka kwa msgrcv(MSG_COPY) ili kupata tags zisizolingana.
- Telekeza secondary halisi ili kuunda UAF; inyang'anye tena kwa data iliyodhibitiwa kupitia UNIX sockets (tengeneza fake msg_msg).
- Leak kernel heap pointers kwa kutumia m_ts over-read katika copy_msg ili kupata mlist.next/mlist.prev (SMAP bypass).
- Kwa sk_buff spray, jenga upya fake msg_msg inayofanana yenye viungo halali na uiweke free kawaida ili kuimarisha hali.
- Inyang'anaye tena UAF kwa object za struct pipe_buffer; leak anon_pipe_buf_ops ili kuhesabu kernel base (kushinda KASLR).
- Spray fake pipe_buf_operations iliyokuwa na release ikielekeza kwenye stack pivot/ROP gadget; funga pipes ili kutekeleza na kupata root.
Bypasses na vidokezo
- KASLR: leak anon_pipe_buf_ops, hesabu base (kbase_addr) na anwani za gadget.
- SMEP/SMAP: execute ROP katika muktadha wa kernel kupitia pipe_buf_operations->release flow; epuka userspace derefs hadi baada ya disable/prepare_kernel_cred/commit_creds chain.
- Hardened usercopy: haitumiki kwa primitive hii ya page overflow; uharibifu unalenga fields zisizo-usercopy.
Uaminifu
- Juu mara tu adjacency inafikiwa; upotofu au panics mara chache (<10%). Kurekebisha idadi za spray/free kunaboresha utulivu. Kuandika mbili LSBs za pointer kusababisha collisions maalum iliripotiwa kuwa yenye ufanisi (mfano, andika muundo 0x0000_0000_0000_0500 kwenye overlap).
Vigezo muhimu vya kurekebisha
- 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
Marekebisho na ufikikaji
- Rekebisho: zuia allocation na destination/length au funga memcpy dhidi ya ukubwa ulioteuliwa; patches za upstream zinafuatiliwa kama CVE-2025-37947.
- Eksploit ya mbali ingehitaji pia infoleak ya kuaminika na remote heap grooming; maelezo haya yanazingatia LPE ya ndani.
Marejeo PoC na zana
- 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)
Marejeo
- ksmbd - Exploiting CVE-2025-37947 (3/3) — Doyensec
- libsmb2
- KSMBD-CVE-2025-37947: proof-of-concept.c
- KSMBD-CVE-2025-37947: CVE-2025-37947.c (full exploit)
- bpf-tracer.sh
tip
Jifunze na fanya mazoezi ya AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Jifunze na fanya mazoezi ya GCP Hacking:
HackTricks Training GCP Red Team Expert (GRTE)
Jifunze na fanya mazoezi ya Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Support HackTricks
- Angalia mpango wa usajili!
- Jiunge na 💬 kikundi cha Discord au kikundi cha telegram au tufuatilie kwenye Twitter 🐦 @hacktricks_live.
- Shiriki mbinu za hacking kwa kuwasilisha PRs kwa HackTricks na HackTricks Cloud repos za github.
HackTricks