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)
assessment tracks (ARTA/GRTA/AzRTA) और Linux Hacking Expert (LHE) के लिए full HackTricks Training catalog ब्राउज़ करें।
HackTricks का समर्थन करें
- subscription plans देखें!
- जुड़ें 💬 Discord group, telegram group, follow करें @hacktricks_live X/Twitter पर, या LinkedIn page और YouTube channel देखें।
- HackTricks](https://github.com/carlospolop/hacktricks) और HackTricks Cloud github repos में PRs सबमिट करके hacking tricks साझा करें।
यह पेज ksmbd streams handling में एक deterministic out-of-bounds write को दस्तावेज़ करता है, जो Ubuntu 22.04 LTS (5.15.0-153-generic) पर reliable Linux kernel privilege escalation सक्षम बनाता है, और standard kernel heap primitives (msg_msg + pipe_buffer) का उपयोग करके KASLR, SMEP, और SMAP को bypass करता है।
- प्रभावित component: fs/ksmbd/vfs.c — ksmbd_vfs_stream_write()
- Primitive: 0x10000-byte kvmalloc() buffer के बाद page-overflow OOB write
- Preconditions: ksmbd authenticated, writable share के साथ running हो, जिसमें vfs streams_xattr उपयोग हो
Example smb.conf
[share]
path = /share
vfs objects = streams_xattr
writeable = yes
Root cause (allocation clamped, memcpy at unclamped offset)
- The function computes size = *pos + count, clamps size to XATTR_SIZE_MAX (0x10000) when exceeded, and recomputes count = (*pos + count) - 0x10000, but still performs memcpy(&stream_buf[*pos], buf, count) into a 0x10000-byte buffer. If *pos ≥ 0x10000 the destination pointer is already outside the allocation, producing an OOB write of count bytes.
streams_xattrPOSIX extended attributes के अंदर SMB alternate data streams store करता है, इसलिए 0x10000 ceiling Linux single-xattr size limit से आता है, न कि किसी SMB protocol field से। इससे bug व्यावहारिक रूप से सिर्फ तब होता है जब share explicitlyvfs objects = streams_xattrenable करता है और filesystem xattrs support करता है।
Why the write offset matters
- Vulnerable path सिर्फ “64KiB से ज़्यादा write” नहीं है। Missing check यह था कि append/copy logic चलने से पहले
*posको current stream length (v_len) के against validate नहीं किया गया था। - Upstream ने इसे
*pos >= v_lenहोने पर-EINVALदेकर reject करके fix किया। Pre-fix, attacker एक valid authenticated handle to a named stream reuse कर सकता था और एक raw SMB2 WRITE भेज सकता था जिसकाfile_offsetपहले से existing stream के end पर या उससे आगे point करता हो, जिससे post-clampmemcpy()deterministic page overflow बन जाता था। - Public PoC इसे
libsmb2से authenticate करके,1337:जैसे stream path को open करके,SessionId/TreeId/FileIdनिकालकर, और फिरfile_offset = 0x10018तथा छोटेLengthके साथ handcrafted SMB2 WRITE भेजकर दिखाता है।
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
- Example: set file offset (pos) to 0x10018 and original length (count) to 8. After clamping, count’ = (0x10018 + 8) - 0x10000 = 0x20, but memcpy writes 32 bytes starting at stream_buf[0x10018], i.e., 0x18 bytes beyond the 16-page allocation.
Triggering the bug via SMB streams write
- Use the same authenticated SMB connection to open a file on the share and issue a write to a named stream (streams_xattr). Set file_offset ≥ 0x10000 with a small length to generate a deterministic OOB write of controllable size.
- libsmb2 can be used to authenticate and craft such writes over SMB2/3.
- In practice, reusing the negotiated SMB session is convenient because the exploit only needs to patch a few dynamic fields in the WRITE request (
TreeId,SessionId,FileId) and can then transmit the malformed packet directly on the same 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) size > KMALLOC_MAX_CACHE_SIZE होने पर buddy allocator से order-4 (16 contiguous pages) allocation request करता है। यह SLUB cache object नहीं है।
- memcpy allocation के तुरंत बाद होता है; post-allocation spraying अप्रभावी है। आपको पहले से physical memory को groom करना होगा ताकि कोई चुना हुआ target allocated 16-page block के तुरंत बाद स्थित हो।
- Ubuntu पर, GFP_KERNEL अक्सर zone Normal में Unmovable migrate type से pull करता है। order-3 और order-4 freelists को exhaust करें ताकि allocator order-5 block को split करके adjacent order-4 + order-3 pair बनाए, फिर एक order-3 slab (kmalloc-cg-4k) को stream buffer के ठीक बाद park करें।
Practical page shaping strategy
- लगभग 1000–2000 msg_msg objects of ~4096 bytes (fits kmalloc-cg-4k) spray करें ताकि order-3 slabs populate हों।
- कुछ messages receive करें ताकि holes बनें और adjacency encourage हो।
- ksmbd OOB को बार-बार trigger करें जब तक order-4 stream buffer किसी msg_msg slab के ठीक पहले land न करे। यदि available हो, तो addresses और alignment confirm करने के लिए eBPF tracing का उपयोग करें।
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
ट्यूनिंग करते समय क्या ट्रेस करें
kvmalloc_node(0x10000)तब पुष्टि करता है जब vulnerable stream write वास्तव में order-4 allocation को consume करता है।load_msg/kretprobe:load_msgआपको यह अनुमान लगाने देता है कि हर sprayed message से कितनेmsg_msgsegallocations जुड़े हैं, जो किसी specific kernel build के लिए primary/secondary message sizes ट्यून करते समय उपयोगी है।- अगर exploit को किसी अलग distro/kernel पर port किया जाता है, तो Ubuntu 22.04 LTS
5.15.0-153-genericconstants अभी भी match करते हैं, ऐसा मानने के बजाय cache names, inlinemsg_msgpayload sizes,anon_pipe_buf_opsoffsets, और gadget addresses फिर से check करें।
Exploitation plan (msg_msg + pipe_buffer), adapted from CVE-2021-22555
- बहुत सारे System V
msg_msgprimary/secondary messages spray करें (kmalloc-cg-4k में fit होने के लिए 4KiB-sized)। - ksmbd OOB trigger करके primary message के next pointer को corrupt करें ताकि दो primaries एक secondary share करें।
- queues को tag करके और
msgrcv(MSG_COPY)से scan करके corrupted pair detect करें ताकि mismatched tags मिलें। - real secondary को free करके UAF बनाएं; controlled data के साथ UNIX sockets के जरिए इसे reclaim करें (एक fake
msg_msgcraft करें)। copy_msgमेंm_tsover-read का abuse करके kernel heap pointers leak करें ताकिmlist.next/mlist.prevमिलें (SMAP bypass)।- एक
sk_buffspray के साथ, valid links वाला consistent fakemsg_msgफिर से बनाएं और state को stabilize करने के लिए इसे normally free करें। struct pipe_bufferobjects के साथ UAF reclaim करें; kernel base compute करने के लिएanon_pipe_buf_opsleak करें (KASLR defeat)।releaseको stack pivot/ROP gadget की ओर point करने वाले fakepipe_buf_operationsspray करें; execute करके root पाने के लिए pipes close करें।
Bypasses and notes
- KASLR:
anon_pipe_buf_opsleak करें, base (kbase_addr) और gadget addresses compute करें। - SMEP/SMAP:
pipe_buf_operations->releaseflow के जरिए kernel context में ROP execute करें;disable/prepare_kernel_cred/commit_credschain के बाद तक userspace derefs से बचें। - Hardened usercopy: यह page overflow primitive पर लागू नहीं होता; corruption targets non-usercopy fields हैं।
Reliability
- adjacency achieve होने के बाद high; occasional misses या panics (<10%)। spray/free counts ट्यून करने से stability improve होती है। specific collisions induce करने के लिए pointer के दो LSBs overwrite करना effective बताया गया है (जैसे overlap में
0x0000_0000_0000_0500pattern write करना)।
Key parameters to tune
msg_msgsprays की संख्या और hole pattern- OOB offset (
pos) और resulting OOB length (count') - हर stage के दौरान UNIX socket,
sk_buff, औरpipe_buffersprays की संख्या
Mitigations and reachability
- Fix: allocation और destination/length दोनों clamp करें या allocated size के खिलाफ
memcpyको bound करें; upstream patches इसे CVE-2025-37947 के रूप में track करते हैं। - Remote exploitation के लिए additionally एक reliable infoleak और remote heap grooming की आवश्यकता होगी; यह write-up local LPE पर focus करता है।
See also
Ksmbd Attack Surface And Fuzzing Syzkaller
References PoC and tooling
- SMB auth और streams writes के लिए
libsmb2 kvmallocaddresses log करने और allocations histogram करने के लिए eBPF tracer script (e.g.,grep 4048 out-4096.txt)- Minimal reachability PoC और full local exploit 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)
assessment tracks (ARTA/GRTA/AzRTA) और Linux Hacking Expert (LHE) के लिए full HackTricks Training catalog ब्राउज़ करें।
HackTricks का समर्थन करें
- subscription plans देखें!
- जुड़ें 💬 Discord group, telegram group, follow करें @hacktricks_live X/Twitter पर, या LinkedIn page और YouTube channel देखें।
- HackTricks](https://github.com/carlospolop/hacktricks) और HackTricks Cloud github repos में PRs सबमिट करके hacking tricks साझा करें।


