ksmbd Attack Surface & SMB2/SMB3 Protocol Fuzzing (syzkaller)
Reading time: 9 minutes
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
Overview
यह पृष्ठ syzkaller का उपयोग करके Linux in-kernel SMB server (ksmbd) को एक्सरसाइज़ और फज़ करने के व्यावहारिक तरीके संक्षेप में बताता है। यह configuration के माध्यम से प्रोटोकॉल attack surface को बढ़ाने, SMB2 ऑपरेशनों को chain करने में सक्षम stateful harness बनाने, grammar-valid PDUs जनरेट करने, कमजोर-कवर्ड किए गए कोड पाथ्स पर mutations को bias करने, और syzkaller की सुविधाओं जैसे focus_areas और ANYBLOB का लाभ उठाने पर केंद्रित है। जबकि मूल रिसर्च विशिष्ट CVEs को सूचीबद्ध करती है, यहाँ हम पुन:उपयोग योग्य methodology और ऐसे concrete स्निपेट्स पर जोर देते हैं जिन्हें आप अपने सेटअप में अनुकूलित कर सकते हैं।
Target scope: SMB2/SMB3 over TCP. Kerberos और RDMA जानबूझकर आउट-ऑफ-स्कोप हैं ताकि harness सरल रहे।
Expand ksmbd Attack Surface via Configuration
डिफ़ॉल्ट, minimal ksmbd सेटअप सर्वर के बड़े हिस्सों को untested छोड़ देता है। सर्वर को अतिरिक्त parsers/handlers के माध्यम से ड्राइव करने और गहरे कोड पाथ्स तक पहुँचने के लिए निम्नलिखित सुविधाएँ सक्षम करें:
- Global-level
- Durable handles
- Server multi-channel
- SMB2 leases
- Per-share-level
- Oplocks (on by default)
- VFS objects
इनको सक्षम करने से निम्न मॉड्यूलों में execution बढ़ती है:
- smb2pdu.c (command parsing/dispatch)
- ndr.c (NDR encode/decode)
- oplock.c (oplock request/break)
- smbacl.c (ACL parsing/enforcement)
- vfs.c (VFS ops)
- vfs_cache.c (lookup cache)
Notes
- सटीक विकल्प आपके distro के ksmbd userspace (ksmbd-tools) पर निर्भर करते हैं। /etc/ksmbd/ksmbd.conf और per-share sections की समीक्षा करें ताकि durable handles, leases, oplocks और VFS objects सक्षम किए जा सकें।
- Multi-channel और durable handles state machines और lifetimes को बदलते हैं, जो concurrency में अक्सर UAF/refcount/OOB बग्स को surface करते हैं।
Authentication and Rate-Limiting Adjustments for Fuzzing
SMB3 को एक valid session चाहिए। harnesses में Kerberos लागू करना जटिलता बढ़ाता है, इसलिए fuzzing के लिए NTLM/guest को प्राथमिकता दें:
- guest access की अनुमति दें और map to guest = bad user सेट करें ताकि unknown users GUEST पर fallback करें।
- NTLMv2 स्वीकार करें (यदि disabled है तो policy patch करें)। यह handshake को सरल रखता है जबकि SMB3 कोड पाथ्स को एक्सरसाइज़ करता है।
- experimentation करते समय strict credit checks को patch कर दें (CVE-2024-50285 के बाद simultaneous-op crediting ज्यादा सख्त हुआ)। अन्यथा, rate-limits fuzzed sequences को बहुत जल्दी reject कर सकते हैं।
- high-throughput fuzzing के दौरान जल्दी rejections से बचने के लिए max connections बढ़ाएँ (उदा., 65536)।
Caution: ये शिथिलताएँ केवल fuzzing की सुविधा के लिए हैं। production में इन settings के साथ तैनात न करें।
Stateful Harness: Extract Resources and Chain Requests
SMB stateful है: कई requests prior responses द्वारा लौटाए गए identifiers पर निर्भर होते हैं (SessionId, TreeID, FileID pairs)। आपका harness responses को parse करके उन्हीं प्रोग्राम के भीतर IDs को reuse करना चाहिए ताकि गहरे handlers तक पहुँचा जा सके (उदा., smb2_create → smb2_ioctl → smb2_close)।
Example snippet to process a response buffer (skipping the +4B NetBIOS PDU length) and cache IDs:
// process response. does not contain +4B PDU length
void process_buffer(int msg_no, const char *buffer, size_t received) {
uint16_t cmd_rsp = u16((const uint8_t *)(buffer + CMD_OFFSET));
switch (cmd_rsp) {
case SMB2_TREE_CONNECT:
if (received >= TREE_ID_OFFSET + sizeof(uint32_t))
tree_id = u32((const uint8_t *)(buffer + TREE_ID_OFFSET));
break;
case SMB2_SESS_SETUP:
// first session setup response carries session_id
if (msg_no == 0x01 && received >= SESSION_ID_OFFSET + sizeof(uint64_t))
session_id = u64((const uint8_t *)(buffer + SESSION_ID_OFFSET));
break;
case SMB2_CREATE:
if (received >= CREATE_VFID_OFFSET + sizeof(uint64_t)) {
persistent_file_id = u64((const uint8_t *)(buffer + CREATE_PFID_OFFSET));
volatile_file_id = u64((const uint8_t *)(buffer + CREATE_VFID_OFFSET));
}
break;
default:
break;
}
}
टिप्स
- Keep one fuzzer process sharing authentication/state: better stability and coverage with ksmbd’s global/session tables. syzkaller still injects concurrency by marking ops async, rerun internally.
- Syzkaller’s experimental reset_acc_state can reset global state but may introduce heavy slowdown. Prefer stability and focus fuzzing instead.
व्याकरण-आधारित SMB2 जनरेशन (Valid PDUs)
Microsoft Open Specifications SMB2 structures को एक fuzzer grammar में अनुवादित करें ताकि आपका generator संरचनात्मक रूप से valid PDUs उत्पन्न करे, जो व्यवस्थित रूप से dispatchers और IOCTL handlers तक पहुँचें।
उदाहरण (SMB2 IOCTL request):
smb2_ioctl_req {
Header_Prefix SMB2Header_Prefix
Command const[0xb, int16]
Header_Suffix SMB2Header_Suffix
StructureSize const[57, int16]
Reserved const[0, int16]
CtlCode union_control_codes
PersistentFileId const[0x4, int64]
VolatileFileId const[0x0, int64]
InputOffset offsetof[Input, int32]
InputCount bytesize[Input, int32]
MaxInputResponse const[65536, int32]
OutputOffset offsetof[Output, int32]
OutputCount len[Output, int32]
MaxOutputResponse const[65536, int32]
Flags int32[0:1]
Reserved2 const[0, int32]
Input array[int8]
Output array[int8]
} [packed]
यह शैली correct structure sizes/offsets को मजबूर करती है और blind mutation की तुलना में coverage को नाटकीय रूप से बेहतर बनाती है।
Directed Fuzzing के साथ focus_areas
syzkaller के experimental focus_areas का उपयोग उन specific functions/files को overweight करने के लिए करें जिनकी वर्तमान में कमजोर coverage है। उदाहरण JSON:
{
"focus_areas": [
{"filter": {"functions": ["smb_check_perm_dacl"]}, "weight": 20.0},
{"filter": {"files": ["^fs/smb/server/"]}, "weight": 2.0},
{"weight": 1.0}
]
}
यह valid ACLs बनाने में मदद करता है जो smbacl.c में arithmetic/overflow paths को ट्रिगर करते हैं। उदाहरण के लिए, एक malicious Security Descriptor जिसमें oversized dacloffset हो, वह integer-overflow को reproduce करता है।
रिप्रोड्यूसर बिल्डर (minimal Python):
def build_sd():
import struct
sd = bytearray(0x14)
sd[0x00] = 0x00; sd[0x01] = 0x00
struct.pack_into('<H', sd, 0x02, 0x0001)
struct.pack_into('<I', sd, 0x04, 0x78)
struct.pack_into('<I', sd, 0x08, 0x00)
struct.pack_into('<I', sd, 0x0C, 0x10000)
struct.pack_into('<I', sd, 0x10, 0xFFFFFFFF) # dacloffset
while len(sd) < 0x78:
sd += b'A'
sd += b"\x01\x01\x00\x00\x00\x00\x00\x00" # minimal DACL
sd += b"\xCC" * 64
return bytes(sd)
ANYBLOB के साथ कवरेज की सीमाएँ तोड़ना
syzkaller’s anyTypes (ANYBLOB/ANYRES) जटिल संरचनाओं को blobs में समेटने की अनुमति देते हैं जो जेनरिक रूप से बदलती हैं। सार्वजनिक SMB pcaps से एक नया corpus तैयार करें और payloads को syzkaller programs में बदलें जो आपके pseudo-syscall (e.g., syz_ksmbd_send_req) को कॉल करते हैं:
# Extract SMB payloads to JSON
# tshark -r smb2_dac_sample.pcap -Y "smb || smb2" -T json -e tcp.payload > packets.json
import json, os
os.makedirs("corpus", exist_ok=True)
with open("packets.json") as f:
data = json.load(f)
# adjust indexing to your tshark JSON structure
packets = [e["_source"]["layers"]["tcp.payload"] for e in data]
for i, pkt in enumerate(packets):
pdu = pkt[0]
pdu_size = len(pdu) // 2 # hex string length → bytes
with open(f"corpus/packet_{i:03d}.txt", "w") as f:
f.write(
f"syz_ksmbd_send_req(&(&(0x7f0000000340))=ANY=[@ANYBLOB=\"{pdu}\"], {hex(pdu_size)}, 0x0, 0x0)"
)
यह खोज को तुरंत आरंभ कर देता है और कुछ प्रतिशत कवरिज बढ़ाते हुए तुरंत UAFs (उदा., ksmbd_sessions_deregister में) को ट्रिगर कर सकता है।
Sanitizers: KASAN से आगे
- KASAN heap bugs (UAF/OOB) के लिए प्राथमिक डिटेक्टर बना रहता है।
- KCSAN अक्सर इस target में false positives या low-severity data races देता है।
- UBSAN/KUBSAN उन declared-bounds गलतियों को पकड़ सकता है जिन्हें array-index semantics के कारण KASAN छोड़ देता है। उदाहरण:
id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
struct smb_sid {
__u8 revision; __u8 num_subauth; __u8 authority[NUM_AUTHS];
__le32 sub_auth[SID_MAX_SUB_AUTHORITIES]; /* sub_auth[num_subauth] */
} __attribute__((packed));
Setting num_subauth = 0 सेट करने से struct के अंदर sub_auth[-1] का OOB read ट्रिगर होता है, जिसे UBSAN’s declared-bounds checks ने पकड़ा।
थ्रूपुट और समानांतरता नोट्स
- एक single fuzzer process (shared auth/state) आम तौर पर ksmbd के लिए काफी अधिक स्थिर होता है और syzkaller के internal async executor की वजह से फिर भी races/UAFs उभरते हैं।
- multiple VMs के साथ, कुल मिलाकर आप अभी भी सैकड़ों SMB commands/second मार सकते हैं। Function-level coverage लगभग ~60% of fs/smb/server और ~70% of smb2pdu.c तक पहुँचने योग्य है, हालांकि state-transition coverage ऐसे metrics द्वारा कम दिखती है।
व्यावहारिक चेकलिस्ट
- ksmbd में durable handles, leases, multi-channel, oplocks, और VFS objects सक्षम करें।
- guest और map-to-guest की अनुमति दें; NTLMv2 स्वीकार करें। fuzzer स्थिरता के लिए credit limits हटाएँ और max connections बढ़ाएँ।
- एक stateful harness बनाएं जो SessionId/TreeID/FileIDs को cache करे और create → ioctl → close को chain करे।
- structural validity बनाए रखने के लिए SMB2 PDUs के लिए एक grammar का उपयोग करें।
- कमजोर कवरेज वाले functions पर अधिक वजन देने के लिए focus_areas का उपयोग करें (e.g., smbacl.c paths like smb_check_perm_dacl)।
- plateaus तोड़ने के लिए real pcaps से ANYBLOB के साथ seed करें; reuse के लिए seeds को syz-db से pack करें।
- KASAN + UBSAN के साथ चलाएँ; UBSAN declared-bounds reports को सावधानी से triage करें।
संदर्भ
- Doyensec – ksmbd Fuzzing (Part 2): https://blog.doyensec.com/2025/09/02/ksmbd-2.html
- syzkaller: https://github.com/google/syzkaller
- ANYBLOB/anyTypes (commit 9fe8aa4): https://github.com/google/syzkaller/commit/9fe8aa4
- Async executor change (commit fd8caa5): https://github.com/google/syzkaller/commit/fd8caa5
- syz-db: https://github.com/google/syzkaller/tree/master/tools/syz-db
- KASAN: https://docs.kernel.org/dev-tools/kasan.html
- UBSAN/KUBSAN: https://docs.kernel.org/dev-tools/ubsan.html
- KCSAN: https://docs.kernel.org/dev-tools/kcsan.html
- Microsoft Open Specifications (SMB): https://learn.microsoft.com/openspecs/
- Wireshark Sample Captures: https://wiki.wireshark.org/SampleCaptures
- बैकग्राउंड रीडिंग: pwning.tech “Tickling ksmbd: fuzzing SMB in the Linux kernel”; Dongliang Mu’s syzkaller notes
tip
AWS हैकिंग सीखें और अभ्यास करें:
HackTricks Training AWS Red Team Expert (ARTE)
GCP हैकिंग सीखें और अभ्यास करें:
HackTricks Training GCP Red Team Expert (GRTE)
Azure हैकिंग सीखें और अभ्यास करें:
HackTricks Training Azure Red Team Expert (AzRTE)
HackTricks का समर्थन करें
- सदस्यता योजनाओं की जांच करें!
- हमारे 💬 Discord समूह या टेलीग्राम समूह में शामिल हों या हमें Twitter 🐦 @hacktricks_live** पर फॉलो करें।**
- हैकिंग ट्रिक्स साझा करें और HackTricks और HackTricks Cloud गिटहब रिपोजिटरी में PRs सबमिट करें।
HackTricks