ksmbd आक्रमण सतह & SMB2/SMB3 प्रोटोकॉल 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 का समर्थन करें

अवलोकन

यह पृष्ठ syzkaller का उपयोग करके Linux in-kernel SMB server (ksmbd) को टेस्ट और fuzz करने की व्यावहारिक तकनीकों का सार प्रस्तुत करता है। यह configuration के माध्यम से प्रोटोकॉल आक्रमण सतह को बढ़ाने, stateful harness बनाने जो SMB2 operations को chain कर सके, grammar-valid PDUs जनरेट करने, weakly-covered code paths में mutations को bias करने, और syzkaller की सुविधाओं जैसे focus_areas और ANYBLOB का उपयोग करने पर केंद्रित है। जबकि मौलिक रिसर्च में specific CVEs सूचीबद्ध हैं, यहाँ हम पुन: उपयोग योग्य methodology और concrete snippets पर जोर देते हैं जिन्हें आप अपने setups के लिए अनुकूलित कर सकते हैं।

लक्षित दायरा: SMB2/SMB3 over TCP. Kerberos और RDMA जानबूझकर दायरे से बाहर रखे गए हैं ताकि harness सरल रहे।


Configuration के माध्यम से ksmbd आक्रमण सतह बढ़ाएँ

डिफ़ॉल्ट रूप से, एक न्यूनतम ksmbd सेटअप सर्वर के बड़े हिस्सों को अटेस्टेड छोड़ देता है। अतिरिक्त parsers/handlers के माध्यम से सर्वर को चलाने और गहरे कोड पाथ्स तक पहुँचने के लिए निम्नलिखित सुविधाएँ सक्षम करें:

  • Global-level
  • Durable handles
  • Server multi-channel
  • SMB2 leases
  • Per-share-level
  • Oplocks (on by default)
  • VFS objects

इनको सक्षम करने से निम्नलिखित मॉड्यूल्स में निष्पादन बढ़ता है:

  • 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)

नोट्स

  • सटीक विकल्प आपके distro’s 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 बग्स को उजागर करते हैं।

Fuzzing के लिए Authentication और Rate-Limiting समायोजन

SMB3 को एक valid session चाहिए। harnesses में Kerberos लागू करने से जटिलता बढ़ती है, इसलिए fuzzing के लिए NTLM/guest पसंद करें:

  • Allow guest access और map to guest = bad user सेट करें ताकि unknown users GUEST पर fallback कर जाएँ।
  • NTLMv2 को स्वीकार करें (अगर disabled हो तो policy patch करें)। इससे handshake सरल रहता है जबकि SMB3 code paths का परीक्षण होता है।
  • experimentation के दौरान strict credit checks को patch out करें (post-hardening के बाद CVE-2024-50285 ने simultaneous-op crediting को कड़ा किया)। अन्यथा, rate-limits fuzzed sequences को बहुत जल्दी reject कर सकते हैं।
  • max connections बढ़ाएँ (उदा., 65536) ताकि high-throughput fuzzing के दौरान प्रारंभिक rejections से बचा जा सके।

सावधानी: ये ढील केवल fuzzing को सुविधाजनक बनाने के लिए हैं। इन सेटिंग्स के साथ production में deploy न करें।


Stateful Harness: Resources निकालना और Requests को Chain करना

SMB stateful है: कई requests उन identifiers पर निर्भर करते हैं जो prior responses से लौटते हैं (SessionId, TreeID, FileID pairs)। आपका harness responses को parse करे और उसी प्रोग्राम के भीतर IDs को reuse करे ताकि गहरे handlers तक पहुँचा जा सके (उदा., smb2_create → smb2_ioctl → smb2_close)।

एक उदाहरण snippet जो response buffer को process करता है (+4B NetBIOS PDU length छोड़ते हुए) और IDs को cache करता है:

c
// 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;
}
}

टिप्स

  • एक ही fuzzer process रखें जो authentication/state साझा करे: ksmbd की global/session tables के साथ बेहतर स्थिरता और कवरेज मिलता है। syzkaller फिर भी ops को async के रूप में मार्क करके concurrency इंजेक्ट करता है, और internally rerun करता है।
  • Syzkaller के experimental reset_acc_state global state को reset कर सकता है लेकिन यह भारी slowdown ला सकता है। स्थिरता को प्राथमिकता दें और fuzzing पर ध्यान केंद्रित करें।

व्याकरण-चालित SMB2 Generation (Valid PDUs)

Microsoft Open Specifications में दिए गए SMB2 संरचनाओं को एक fuzzer grammar में अनुवादित करें ताकि आपका generator संरचनात्मक रूप से valid PDUs बनाए, जो व्यवस्थित ढंग से dispatchers और IOCTL handlers तक पहुँचें।

Example (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]

यह तरीका सही structure sizes/offsets को लागू करने के लिए मजबूर करता है और blind mutation की तुलना में कवरेज को नाटकीय रूप से सुधारता है।


Directed Fuzzing With focus_areas

वर्तमान में जिन विशिष्ट functions/files का कवरेज कमजोर है, उन्हें अधिक वज़न देने के लिए syzkaller’s के experimental focus_areas का उपयोग करें। उदाहरण JSON:

json
{
"focus_areas": [
{"filter": {"functions": ["smb_check_perm_dacl"]}, "weight": 20.0},
{"filter": {"files": ["^fs/smb/server/"]}, "weight": 2.0},
{"weight": 1.0}
]
}

यह वैध ACLs बनाने में मदद करता है जो smbacl.c में arithmetic/overflow paths को ट्रिगर करते हैं।
उदाहरण के लिए, एक दुर्भावनापूर्ण Security Descriptor जिसमें अत्यधिक बड़ा dacloffset है, वह एक integer-overflow को पुनरुत्पन्न कर देता है।

रिप्रोड्यूसर बिल्डर (minimal Python):

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) जटिल संरचनाओं को ऐसे ब्लॉब्स में संकुचित करने की अनुमति देते हैं, जो सामान्यतः परिवर्तित होते हैं। public SMB pcaps से नया corpus तैयार करें और payloads को syzkaller programs में बदलें जो आपके pseudo-syscall (उदा., syz_ksmbd_send_req) को कॉल करते हों:

bash
# Extract SMB payloads to JSON
# tshark -r smb2_dac_sample.pcap -Y "smb || smb2" -T json -e tcp.payload > packets.json
python
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)"
)

यह अन्वेषण को तुरंत शुरू करता है और (उदाहरण के लिए ksmbd_sessions_deregister में) तुरंत UAFs को ट्रिगर कर सकता है, साथ ही कवरेज को कुछ प्रतिशत बढ़ा देता है।


Sanitizers: KASAN के परे

  • KASAN heap बग्स (UAF/OOB) के लिए प्राथमिक डिटेक्टर बना रहता है।
  • KCSAN अक्सर इस टार्गेट में false positives या कम-गंभीरता वाले data races देता है।
  • UBSAN/KUBSAN declared-bounds गलतियों को पकड़ सकता है जिन्हें KASAN array-index semantics के कारण मिस कर देता है। उदाहरण:
c
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 triggers an in-struct OOB read of sub_auth[-1], caught by UBSAN’s declared-bounds checks.


Throughput and Parallelism Notes

  • एक अकेला fuzzer process (shared auth/state) आमतौर पर ksmbd के लिए काफी अधिक स्थिर होता है और फिर भी races/UAFs को उजागर करता है, धन्यवाद syzkaller’s internal async executor।
  • कई VMs के साथ, आप कुल मिलाकर अभी भी सैकड़ों SMB commands/second मार सकते हैं। Function-level coverage लगभग ~60% fs/smb/server और ~70% smb2pdu.c तक प्राप्त किया जा सकता है, हालांकि state-transition coverage ऐसे मेट्रिक्स से कम दिखती है।

Practical Checklist

  • 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 करे।
  • स्ट्रक्चरल वैधता बनाए रखने के लिए SMB2 PDUs के लिए grammar का उपयोग करें।
  • कम आवृत्ति से कवर होने वाले फ़ंक्शन्स पर वजन देने के लिए focus_areas का उपयोग करें (उदा., smbacl.c paths जैसे smb_check_perm_dacl)।
  • plateaus तोड़ने के लिए असली pcaps से ANYBLOB से seed करें; reuse के लिए seeds को syz-db के साथ pack करें।
  • KASAN + UBSAN के साथ चलाएँ; UBSAN declared-bounds रिपोर्ट्स को सावधानी से triage करें।

References

  • 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 का समर्थन करें