ksmbd Επιφάνεια Επίθεσης & SMB2/SMB3 Protocol Fuzzing (syzkaller)
Reading time: 9 minutes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Επισκόπηση
Αυτή η σελίδα συνοψίζει πρακτικές τεχνικές για να εξασκήσετε και να κάνετε fuzz τον in-kernel SMB server (ksmbd) στο Linux χρησιμοποιώντας syzkaller. Επικεντρώνεται στην επέκταση της επιφάνειας επίθεσης του πρωτοκόλλου μέσω διαμόρφωσης, στην κατασκευή ενός stateful harness ικανό να αλυσοδέσει SMB2 operations, στη δημιουργία grammar-valid PDUs, στην εισροή μεταλλάξεων προς ασθενώς καλυμμένες διαδρομές κώδικα και στην εκμετάλλευση χαρακτηριστικών του syzkaller όπως τα focus_areas και ANYBLOB. Ενώ η αρχική έρευνα απαριθμεί συγκεκριμένα CVEs, εδώ δίνουμε έμφαση στη επαναχρησιμοποιήσιμη μεθοδολογία και σε συγκεκριμένα αποσπάσματα κώδικα που μπορείτε να προσαρμόσετε στις δικές σας ρυθμίσεις.
Target scope: SMB2/SMB3 over TCP. Kerberos and RDMA είναι εσκεμμένα εκτός πεδίου για να κρατήσουμε το harness απλό.
Επέκταση της Επιφάνειας Επίθεσης του ksmbd μέσω Διαμόρφωσης
Εξ ορισμού, μια ελάχιστη εγκατάσταση ksmbd αφήνει μεγάλα μέρη του server ανεξερεύνητα. Ενεργοποιήστε τα παρακάτω χαρακτηριστικά για να οδηγήσετε τον server μέσω επιπλέον parsers/handlers και να φτάσετε σε βαθύτερες διαδρομές κώδικα:
- Σε global επίπεδο
- Durable handles
- Server multi-channel
- SMB2 leases
- Σε επίπεδο κάθε share
- Oplocks (ενεργά από προεπιλογή)
- VFS objects
Η ενεργοποίηση αυτών αυξάνει την εκτέλεση σε modules όπως:
- 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)
Σημειώσεις
- Οι ακριβείς επιλογές εξαρτώνται από το userspace ksmbd της διανομής σας (ksmbd-tools). Ελέγξτε /etc/ksmbd/ksmbd.conf και τις ενότητες per-share για να ενεργοποιήσετε durable handles, leases, oplocks και VFS objects.
- Multi-channel και durable handles αλλάζουν τα state machines και τα lifetimes, συχνά αναδεικνύοντας UAF/refcount/OOB bugs υπό concurrency.
Προσαρμογές Πιστοποίησης και Rate-Limiting για Fuzzing
Το SMB3 χρειάζεται έγκυρη session. Η υλοποίηση Kerberos στα harnesses προσθέτει πολυπλοκότητα, οπότε προτιμήστε NTLM/guest για fuzzing:
- Επιτρέψτε guest πρόσβαση και ορίστε map to guest = bad user ώστε άγνωστοι χρήστες να καταλήγουν σε GUEST.
- Accept NTLMv2 (patch policy αν είναι απενεργοποιημένο). Αυτό διατηρεί το handshake απλό ενώ ασκεί τα SMB3 code paths.
- Patch out strict credit checks κατά τη διάρκεια του πειραματισμού (το post-hardening για CVE-2024-50285 έκανε το simultaneous-op crediting πιο αυστηρό). Διαφορετικά, τα rate-limits μπορούν να απορρίψουν fuzzed sequences πολύ νωρίς.
- Αυξήστε τα max connections (π.χ. σε 65536) για να αποφύγετε πρόωρες απορρίψεις κατά το high-throughput fuzzing.
Προσοχή: Αυτές οι χαλαρώσεις γίνονται μόνο για να διευκολύνουν το fuzzing. Μην τις εφαρμόσετε σε παραγωγικό περιβάλλον.
Stateful Harness: Extract Resources and Chain Requests
Το SMB είναι stateful: πολλές αιτήσεις εξαρτώνται από identifiers που επιστρέφονται από προηγούμενες απαντήσεις (SessionId, TreeID, FileID pairs). Το harness σας πρέπει να κάνει parse τις απαντήσεις και να επαναχρησιμοποιεί τα IDs εντός του ίδιου προγράμματος για να φτάσει σε βαθιούς 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;
}
}
Συμβουλές
- Διατήρησε μία διεργασία fuzzer που μοιράζεται την αυθεντικοποίηση/κατάσταση: καλύτερη σταθερότητα και κάλυψη με τους global/session πίνακες του ksmbd. Το syzkaller εξακολουθεί να εισάγει concurrency σημειώνοντας τις ops ως async, επανεκτελεί εσωτερικά.
- Το πειραματικό reset_acc_state του syzkaller μπορεί να επαναφέρει την global κατάσταση αλλά μπορεί να προκαλέσει μεγάλη επιβράδυνση. Προτίμησε σταθερότητα και εστίασε στο fuzzing.
Παραγωγή SMB2 με Οδηγό Γραμματικής (Έγκυρα PDUs)
Μετατρέψτε τις SMB2 δομές των Microsoft Open Specifications σε μια γραμματική για fuzzer ώστε ο generator σας να παράγει δομικά έγκυρα 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]
Αυτό το στυλ επιβάλλει σωστά μεγέθη/offsets των δομών και βελτιώνει δραματικά την κάλυψη σε σύγκριση με blind mutation.
Directed Fuzzing With focus_areas
Χρησιμοποιήστε το πειραματικό focus_areas του syzkaller για να δώσετε μεγαλύτερο βάρος σε συγκεκριμένες functions/files που αυτή τη στιγμή έχουν ασθενή κάλυψη. Παράδειγμα JSON:
{
"focus_areas": [
{"filter": {"functions": ["smb_check_perm_dacl"]}, "weight": 20.0},
{"filter": {"files": ["^fs/smb/server/"]}, "weight": 2.0},
{"weight": 1.0}
]
}
Αυτό βοηθά στην κατασκευή έγκυρων ACLs που ενεργοποιούν arithmetic/overflow paths στο smbacl.c. Για παράδειγμα, ένας κακόβουλος Security Descriptor με υπερμεγέθη dacloffset αναπαράγει ένα integer-overflow.
Reproducer builder (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
Τα anyTypes του syzkaller (ANYBLOB/ANYRES) επιτρέπουν τη μετατροπή σύνθετων δομών σε blobs που μεταβάλλονται γενικά. Δημιουργήστε ένα νέο corpus από δημόσια SMB pcaps και μετατρέψτε τα payloads σε προγράμματα syzkaller που καλούν το pseudo-syscall σας (π.χ., 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 (UAF/OOB).
- Ο KCSAN συχνά δίνει false positives ή data races χαμηλής σοβαρότητας σε αυτόν τον στόχο.
- Το UBSAN/KUBSAN μπορεί να εντοπίσει λάθη σε δηλωμένα όρια που ο KASAN χάνει λόγω της σημασιολογίας των array-index. Παράδειγμα:
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));
Η ρύθμιση num_subauth = 0 προκαλεί in-struct OOB read του sub_auth[-1], που εντοπίστηκε από τους declared-bounds checks του UBSAN.
Throughput and Parallelism Notes
- Μία μόνο διεργασία fuzzer (shared auth/state) τείνει να είναι σημαντικά πιο σταθερή για ksmbd και συνεχίζει να αποκαλύπτει races/UAFs χάρη στον internal async executor του syzkaller.
- Με πολλαπλά VMs, μπορείτε ακόμα να φτάσετε σε εκατοντάδες SMB commands/second συνολικά. Function-level coverage περίπου ~60% του fs/smb/server και ~70% του smb2pdu.c είναι εφικτή, αν και η κάλυψη των state-transition είναι υποαντιπροσωπευμένη από τέτοια metrics.
Practical Checklist
- Ενεργοποιήστε durable handles, leases, multi-channel, oplocks και VFS objects στο ksmbd.
- Allow guest και map-to-guest; αποδεχτείτε NTLMv2. Patch out credit limits και αυξήστε τα max connections για σταθερότητα του fuzzer.
- Κατασκευάστε ένα stateful harness που caches SessionId/TreeID/FileIDs και αλυσοδέτει create → ioctl → close.
- Χρησιμοποιήστε ένα grammar για SMB2 PDUs για να διατηρείτε structural validity.
- Χρησιμοποιήστε focus_areas για να overweightάρετε weakly-covered functions (π.χ. smbacl.c paths όπως smb_check_perm_dacl).
- Seed με ANYBLOB από πραγματικά pcaps για να σπάσετε plateaus; pack τα seeds με syz-db για reuse.
- Τρέξτε με KASAN + UBSAN; triage τα UBSAN declared-bounds reports προσεκτικά.
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
- Background reading: pwning.tech “Tickling ksmbd: fuzzing SMB in the Linux kernel”; Dongliang Mu’s syzkaller notes
tip
Μάθετε & εξασκηθείτε στο AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.