Wireshark Threat Hunting – From Packets to Indicators [SMB: DEEP-DIVE]

Wireshark Threat Hunting – From Packets to Indicators [SMB: DEEP-DIVE]

This entry is part 16 of 7 in the series Digital Forensics and Incident Response

Views: 3

SMB & Windows Auth Deep-Dive — Wireshark DFIR
SMB2 — Session Negotiation & Setup
SES

SMB2 Session Lifecycle Filters

Protocol Negotiation
smb2.cmd == 0x0000NEGOTIATE — dialect selection
smb2.dialect == 0x0202SMB 2.0.2 (old — flag)
smb2.dialect == 0x0210SMB 2.1
smb2.dialect == 0x0300SMB 3.0
smb2.dialect == 0x0311SMB 3.1.1 (current)
Session Setup
smb2.cmd == 0x0001SESSION_SETUP (auth start)
smb2.cmd == 0x0001 && smb2.flags.response == 0Client session requests only
smb2.cmd == 0x0001 && smb2.flags.response == 1Server session responses
smb2.cmd == 0x0002LOGOFF — session teardown
Session Tracking
smb2.sesid == 0x000000010000001dTrack specific session ID
smb2.sesid && smb2.cmd == 0x0001All session auth packets
Session IDs (smb2.sesid) persist across an SMB2 conversation. Use them to correlate all file operations back to the authenticating user captured in SESSION_SETUP.
ID

SMB2 Identity Fields During Session Setup

SMB2 itself does not carry username/password — authentication is embedded as NTLM or Kerberos blobs inside SESSION_SETUP packets. Extract with the NTLM / Kerberos filters in the sections below.
Extracting Identity from SESSION_SETUP
smb2.cmd == 0x0001 && ntlmsspSession uses NTLM auth
smb2.cmd == 0x0001 && kerberosSession uses Kerberos auth
smb2.cmd == 0x0001 && ntlmssp.auth.usernameCapture username at auth time
smb2.cmd == 0x0001 && ntlmssp.auth.domainCapture domain at auth time
smb2.cmd == 0x0001 && ntlmssp.auth.workstationSource workstation name
Correlating Session to File Operations
smb2.sesid == <id> # All ops for one session
Workflow: capture ntlmssp.auth.username + smb2.sesid from SESSION_SETUP, then use that session ID to filter all subsequent file access by that user.
SMB2 — Share & Tree Access
SHR

Share / Tree Connection Filters T1021.002

Connect & Disconnect
smb2.cmd == 0x0003TREE_CONNECT (any share)
smb2.cmd == 0x0003 && smb2.flags.response == 0Client connect requests
smb2.cmd == 0x0004TREE_DISCONNECT
Share Name Filters (smb2.tree)
smb2.tree contains “C$”Admin C$ share access
smb2.tree contains “ADMIN$”Remote admin share (PsExec)
smb2.tree contains “IPC$”Named pipes / RPC over SMB
smb2.tree contains “SYSVOL”Domain policy share (GPO)
smb2.tree contains “NETLOGON”Logon scripts share
smb2.tree contains “print$”Printer driver share
smb2.tree matches “\\\\[0-9]{1,3}\.”IP-based share access (unusual)
Share Enumeration Pattern T1135
smb2.cmd == 0x0003 && ip.src == <ip>All shares from one host
Rapid TREE_CONNECT attempts across multiple share names from a single source is a strong indicator of automated share enumeration (T1135).
PIPE

Named Pipe Access over IPC$ T1021.002

Named pipes accessed via \\<host>\IPC$ are the backbone of Windows RPC. Attackers use them for WMI, PsExec, DCSync, and lateral movement. The pipe name is the key artefact.
Pipe Name Filters (smb2.filename)
smb2.filename == “svcctl”Service Control Manager (PsExec)
smb2.filename == “samr”SAM remote protocol (user enum)
smb2.filename == “lsarpc”LSA RPC (privilege/policy)
smb2.filename == “drsuapi”Directory Replication (DCSync)
smb2.filename == “netlogon”Netlogon pipe (ZeroLogon, etc)
smb2.filename == “atsvc”Task Scheduler RPC
smb2.filename == “epmapper”RPC endpoint mapper
smb2.filename == “wkssvc”Workstation service
smb2.filename == “spoolss”Print Spooler (PrintNightmare)
smb2.filename contains “PSEXESVC”PsExec service binary
SMB2 — File Paths, Operations & Disposition
PATH

File & Folder Path Filters (smb2.filename)

High-Value Target Paths T1003
smb2.filename contains “NTDS.dit”AD database — DCSync staging
smb2.filename contains “SAM”SAM hive (local creds)
smb2.filename contains “SYSTEM”SYSTEM hive (needed with SAM)
smb2.filename contains “SECURITY”SECURITY hive (LSA secrets)
smb2.filename contains “ntds”AD database variant path
User Profile & Sensitive Paths
smb2.filename contains “\\Users\\”User profile directory
smb2.filename contains “\\Desktop\\”Desktop access
smb2.filename contains “\\Documents\\”Documents folder
smb2.filename contains “AppData”AppData (browser creds, tokens)
smb2.filename contains “.kdbx”KeePass password database
smb2.filename contains “.pfx”Private key/cert file
smb2.filename contains “.rdp”RDP connection file
smb2.filename contains “id_rsa”SSH private key
Staging & Persistence Paths T1547
smb2.filename contains “\\Temp\\”Temp directory staging
smb2.filename contains “\\Startup\\”Startup folder persistence
smb2.filename contains “\\System32\\”System32 — DLL hijacking risk
smb2.filename contains “\\Windows\\”Windows directory access
smb2.filename contains “\\Tasks\\”Scheduled task files
smb2.filename contains “\\services\\”Service binary paths
Executable & Script Extensions T1105
smb2.filename matches “.*\\.exe$”Executable transfer
smb2.filename matches “.*\\.(dll|sys)$”DLL / driver drop
smb2.filename matches “.*\\.(ps1|psm1)$”PowerShell scripts
smb2.filename matches “.*\\.(bat|cmd|vbs|hta)$”Script-based payloads
smb2.filename matches “.*\\.(zip|7z|rar)$”Archives (staging/exfil)
OPS

File Operation Commands & Disposition

Core File Commands
smb2.cmd == 0x0005CREATE — file open or create
smb2.cmd == 0x0006CLOSE
smb2.cmd == 0x0007FLUSH
smb2.cmd == 0x0008READ — file read
smb2.cmd == 0x0009WRITE — file write
smb2.cmd == 0x000eQUERY_DIRECTORY — dir listing
smb2.cmd == 0x0010QUERY_INFO — file metadata
smb2.cmd == 0x0011SET_INFO — rename/delete/ACL
smb2.cmd == 0x000bIOCTL — device control / DCE/RPC

Create Disposition — What happened to the file
FilterValueMeaning
smb2.create.disposition == 0x00FILE_SUPERSEDEReplace if exists, create if not
smb2.create.disposition == 0x01FILE_OPENOpen existing only — no create
smb2.create.disposition == 0x02FILE_CREATECreate new — fail if exists
smb2.create.disposition == 0x03FILE_OPEN_IFOpen existing or create new
smb2.create.disposition == 0x04FILE_OVERWRITEOverwrite existing — fail if not
smb2.create.disposition == 0x05FILE_OVERWRITE_IFOverwrite or create — always wins
Write Size & Volume
smb2.cmd == 0x0009 && smb2.write.length > 100000Large write (>100KB)
smb2.cmd == 0x0009 && ip.src == <suspect>All writes from host
smb2.cmd == 0x0008 && smb2.read.length > 100000Large reads (exfil staging)
SMB2 — Access Masks & Permissions
ACL

Access Mask Filters — What the Client Requested

Access masks appear in CREATE requests. They tell you what the client intended to do with the file — read, write, delete, change ACL, etc. Combine with smb2.filename for context.
Common Access Mask Filters (smb2.create.access)
smb2.create.access == 0x00120089Read-only access
smb2.create.access == 0x0012019fRead + Write access
smb2.create.access == 0x00100080Read attributes only
smb2.create.access & 0x00040000WRITE_DAC (ACL modification)
smb2.create.access & 0x00010000DELETE access requested
smb2.create.access == 0x001f01ffFull control (all permissions)
smb2.create.access == 0x02000000MAXIMUM_ALLOWED (privilege escalation)
Specific Bit Flags (smb2.access.*)
smb2.access.read_data == 1Read file data
smb2.access.write_data == 1Write file data
smb2.access.delete == 1Delete file
smb2.access.read_control == 1Read security descriptor
smb2.access.write_dac == 1Modify DACL (ACL tampering)
smb2.access.write_owner == 1Change owner
smb2.access.execute == 1Execute access requested
ERR

SMB2 NT Status / Error Codes

Auth & Access Errors — High Forensic Value
FilterNTSTATUSMeaning
smb2.nt_status == 0xC000006DSTATUS_LOGON_FAILUREWrong password / unknown user
smb2.nt_status == 0xC0000022STATUS_ACCESS_DENIEDValid user, insufficient rights
smb2.nt_status == 0xC0000034STATUS_OBJECT_NAME_NOT_FOUNDFile/path not found
smb2.nt_status == 0xC0000035STATUS_OBJECT_NAME_COLLISIONFile already exists
smb2.nt_status == 0xC000006ESTATUS_ACCOUNT_RESTRICTIONAccount policy violation
smb2.nt_status == 0xC0000064STATUS_NO_SUCH_USERUsername does not exist
smb2.nt_status == 0xC0000193STATUS_ACCOUNT_EXPIREDAccount expired
smb2.nt_status == 0xC000018CSTATUS_TRUST_FAILUREDomain trust issue
smb2.nt_status == 0xC00000CCSTATUS_BAD_NETWORK_NAMEShare name not found
Broad Error Filters
smb2.nt_status != 0x00000000All non-success responses
smb2.nt_status && ip.src == <host>All errors from one host
smb2.nt_status == 0xC000006D && ip.src == <host>Auth failures from one host
SMB2 — Combined Threat Scenario Filters
THR

Compound Filters for Known Attack Patterns

DCSync via SMB T1003.006
Mimikatz DCSync accesses the drsuapi named pipe over IPC$ to pull password hashes without touching disk. Look for the pipe access followed by large READ operations.
smb2.filename == “drsuapi” || drsuapi
smb2.tree contains “IPC$” && smb2.filename == “drsuapi”
PsExec Execution T1570
PsExec copies a service binary to ADMIN$ then calls svcctl to install and start it. All three artefacts appear in sequence.
smb2.tree contains “ADMIN$” && smb2.filename contains “.exe”
smb2.filename == “svcctl” && smb2.tree contains “IPC$”
Credential File Theft T1552.001
Attacker reads SAM/SYSTEM hives or credential stores directly over SMB. These paths should never be accessed remotely in normal operations.
smb2.filename contains “SAM” || smb2.filename contains “SYSTEM” || smb2.filename contains “NTDS.dit”
Ransomware File Encryption T1486
Ransomware performs rapid WRITE operations to many different files across network shares. Large write size + high frequency + modified extensions are key indicators.
smb2.cmd == 0x0009 && smb2.write.length > 50000
smb2.filename matches “.*\.(encrypted|locky|ryuk|cerber|wncry)”
smb2.filename contains “README” || smb2.filename contains “DECRYPT”
Lateral Movement via WMIC/WMI T1047
WMI lateral movement opens an IOCTL on the epmapper pipe to discover RPC endpoints, then targets IWbemServices interface. Watch for DCERPC over IPC$.
smb2.filename == “epmapper” && smb2.tree contains “IPC$”
dcerpc && smb2 && smb2.tree contains “IPC$”
GPO Persistence via SYSVOL T1484.001
Attackers with domain admin write scripts to SYSVOL to persist across all domain-joined systems. Any write to SYSVOL from a non-DC source is suspicious.
smb2.tree contains “SYSVOL” && smb2.cmd == 0x0009
smb2.tree contains “SYSVOL” && smb2.filename matches “.*\\.(bat|ps1|vbs)”
NTLM Authentication — Message Flow & Fields
NTLM

NTLM Three-Way Handshake Filters

NTLM Flow: Client sends NEGOTIATE → Server sends CHALLENGE → Client sends AUTHENTICATE with hashed response. Username, domain, and workstation are in message 3.
CLIENT
NTLMSSP_NEGOTIATE (Message Type 1)
Flags negotiated — no credentials yet
ntlmssp.messagetype == 1
SERVER
NTLMSSP_CHALLENGE (Message Type 2)
Server nonce for hashing — extract with ntlmssp.ntlmserverchallenge
ntlmssp.messagetype == 2
CLIENT
NTLMSSP_AUTH (Message Type 3) ← Key forensic packet
Username, domain, workstation + NTHash response
ntlmssp.messagetype == 3
Broad NTLM Filters
ntlmsspAll NTLM packets
ntlmssp.messagetype == 3All auth responses (creds in here)
ntlmssp.messagetype == 3 && tcp.port == 445NTLM auth over SMB
ntlmssp.messagetype == 3 && tcp.port == 80NTLM auth over HTTP
ntlmssp.messagetype == 3 && tcp.port == 389NTLM auth over LDAP
FLD

NTLM Fields Reference — All Extractable Values

ntlmssp.auth.username identity
The authenticating username. Present in AUTHENTICATE (message 3) only.
Filter: ntlmssp.auth.username contains “admin”
tshark: -e ntlmssp.auth.username
ntlmssp.auth.domain identity
The Windows domain or workgroup the user belongs to (e.g. NORTHBRIDGE).
Filter: ntlmssp.auth.domain == “NORTHBRIDGE”
ntlmssp.auth.workstation source
Source machine hostname that initiated the authentication.
Filter: ntlmssp.auth.workstation contains “WS-FINANCE”
ntlmssp.ntlmserverchallenge crypto
8-byte server nonce. Needed with the NTHash to crack the NTLMv2 response offline.
tshark: -e ntlmssp.ntlmserverchallenge
ntlmssp.auth.ntresponse hash
NTHash response (NTLMv1) or NTLMv2 response blob. Can be fed into Hashcat.
tshark: -e ntlmssp.auth.ntresponse
Practical Hunting Filters
ntlmssp.auth.username && ip.src == 203.0.113.114All auth from attacker IP
ntlmssp.auth.domain != “NORTHBRIDGE” && tcp.port == 445Non-domain creds on SMB
ntlmssp.messagetype == 3 && ntlmssp.auth.username == “”Anonymous auth attempt
Pass-the-Hash detection: Look for ntlmssp.messagetype == 3 where no corresponding successful Kerberos TGT exists for that user. PtH never generates a Kerberos exchange — only NTLM.
Kerberos Authentication — Message Flow & Abuse
KRB

Kerberos Message Types & Exchange Flow

CLIENT
AS-REQ (msg_type == 10) — TGT Request
User → KDC. Contains CNameString (username) + realm
kerberos.msg_type == 10
KDC
AS-REP (msg_type == 11) — TGT Issued
Encrypted ticket + session key returned to client
kerberos.msg_type == 11
CLIENT
TGS-REQ (msg_type == 12) — Service Ticket Request ← Kerberoast trigger
Client requests ticket for a specific SPN
kerberos.msg_type == 12
KDC
TGS-REP (msg_type == 13) — Service Ticket Issued ← Kerberoast target
Service ticket encrypted with service account’s NTLM hash
kerberos.msg_type == 13
CLIENT
AP-REQ (msg_type == 14) — Service Authentication
Client presents ticket to service (not the KDC)
kerberos.msg_type == 14
KDC
KRB-ERROR (msg_type == 30) — Failure / Attack Indicator
Error code determines failure reason — see below
kerberos.msg_type == 30
FLD

Kerberos Fields & Error Code Reference

kerberos.CNameString identity
Username in the AS-REQ / TGS-REQ. Most important identity field.
Filter: kerberos.CNameString == “svc_backup”
tshark: -e kerberos.CNameString
kerberos.realm domain
Kerberos realm (domain name in uppercase). Identifies which domain is authenticating.
Filter: kerberos.realm == “NORTHBRIDGE.LOCAL”
kerberos.sname SPN
Service Principal Name being requested. Kerberoasting targets accounts with registered SPNs.
Filter: kerberos.sname contains “MSSQLSvc”
kerberos.encryption_type
Encryption algorithm used. RC4 (0x17) in TGS-REP is the Kerberoasting indicator — RC4-encrypted tickets are crackable offline.
Filter: kerberos.encryption_type == 23  # 0x17 = RC4 — crackable

Kerberos Error Codes (kerberos.error_code)
Filter ValueErrorAttack Context
== 6KDC_ERR_C_PRINCIPAL_UNKNOWNInvalid username — user enumeration
== 7KDC_ERR_S_PRINCIPAL_UNKNOWNInvalid SPN — service recon
== 14KDC_ERR_ETYPE_NOSUPPUnsupported encryption (downgrade attempt)
== 18KDC_ERR_CLIENT_REVOKEDAccount disabled / locked
== 23KDC_ERR_KEY_EXPIREDPassword expired
== 24KDC_ERR_PREAUTH_FAILEDWrong password — spray indicator
== 25KDC_ERR_PREAUTH_REQUIREDAS-REP Roasting (no pre-auth set)
== 37KRB_AP_ERR_SKEWClock skew >5min — possible replay attack
Attack-Specific Compound Filters
kerberos.msg_type == 12 && kerberos.encryption_type == 23Kerberoasting — RC4 TGS request T1558.003
kerberos.msg_type == 10 && !kerberos.encrypted_PA_DATAAS-REP Roasting — no pre-auth T1558.004
kerberos.error_code == 24 && ip.src == <ip>Password spray from single host
kerberos.msg_type == 12 && ip.src == <ip>All TGS requests from one host
kerberos.sname contains “krbtgt”Golden/Silver ticket use (T1558.001)
LDAP — Authentication & Directory Reconnaissance
LDAP

LDAP Bind Authentication Filters T1078

LDAP Simple Bind sends credentials in cleartext. Even over port 389. Always flag ldap.simple traffic regardless of content — it indicates a system misconfiguration.
Bind Request Types
ldap.protocolOp == 0bindRequest (any type)
ldap.protocolOp == 1bindResponse (success/failure)
ldap.simpleSIMPLE BIND — cleartext credential
ldap.simple != “”Non-empty simple bind (has password)
ldap.nameBind DN (full distinguished name)
ldap.name contains “CN=svc_”Service account bind
ldap.saslSASL bind (NTLM/Kerberos wrapped)
Bind Failures & Results
ldap.resultCode != 0Any bind failure
ldap.resultCode == 49invalidCredentials (wrong password)
ldap.resultCode == 53unwillingToPerform (policy)
ldap.resultCode == 0Successful bind
TShark: Extract All LDAP Bind Credentials
tshark -r cap.pcap -Y “ldap.protocolOp==0” -T fields -e ip.src -e ldap.name -e ldap.simple
RECON

LDAP Directory Reconnaissance Filters T1087.002

Search Operations
ldap.protocolOp == 3searchRequest — any query
ldap.protocolOp == 4searchResEntry — result record
ldap.protocolOp == 5searchResDone — end of results
Filter String Analysis (ldap.filter)
ldap.filter contains “objectClass=*”Dump all AD objects
ldap.filter contains “samAccountType=805306368”Enumerate all user accounts
ldap.filter contains “samAccountType=805306369”Enumerate computer accounts
ldap.filter contains “adminCount=1”Privileged account enumeration
ldap.filter contains “servicePrincipalName”SPN search — Kerberoasting prep
ldap.filter contains “memberOf”Group membership queries
ldap.filter contains “Domain Admins”Domain Admins group lookup
ldap.filter contains “userAccountControl:1.2.840.113549”Disabled/locked account queries
ldap.filter contains “pwdLastSet”Password age enumeration
ldap.filter contains “badPasswordTime”Lockout enumeration
BloodHound / SharpHound LDAP Fingerprint T1087.002
BloodHound generates a burst of LDAP queries in rapid succession covering users, groups, computers, GPOs, trusts, and ACLs. Correlate volume + diversity of filter types from a single source IP.
ldap && ip.src == <host> && ldap.protocolOp == 3All LDAP searches from one source
ldap.filter contains “msDS-AllowedToDelegateTo”Kerberos delegation recon
ldap.filter contains “msDS-GroupMSAMembership”GMSA account recon
TShark — SMB Forensic Extraction Pipelines
CLI

TShark — SMB File & Share Access Extraction

All File Paths Accessed Over SMB
tshark -r cap.pcap -Y “smb2.cmd==5 && smb2.flags.response==0″ \ -T fields -e ip.src -e smb2.sesid -e smb2.tree -e smb2.filename \ -E separator=”|” -E header=y | sort -u
File Writes — Who Wrote What to Where
tshark -r cap.pcap -Y “smb2.cmd==9″ \ -T fields -e frame.time -e ip.src -e smb2.tree -e smb2.filename -e smb2.write.length \ -E separator=”|”
All Shares Accessed (with Source IP)
tshark -r cap.pcap -Y “smb2.cmd==3 && smb2.flags.response==0” \ -T fields -e ip.src -e smb2.tree | sort | uniq -c | sort -rn
All SMB Errors from a Single Host
tshark -r cap.pcap -Y “smb2.nt_status != 0x00000000 && ip.src==<host>” \ -T fields -e frame.time -e smb2.nt_status -e smb2.tree -e smb2.filename
Export All Files Transferred Over SMB
tshark -r cap.pcap –export-objects smb,/tmp/smb_dump/ # Or filter first, then export: tshark -r cap.pcap -Y “smb2.cmd==8 || smb2.cmd==9” –export-objects smb,/tmp/smb_dump/
Detect Rapid Directory Listing (Recon)
tshark -r cap.pcap -Y “smb2.cmd==14” \ -T fields -e frame.time -e ip.src -e smb2.tree -e smb2.filename \ | sort -t’|’ -k2,2 | uniq -c | sort -rn
CLI

TShark — Auth Identity Extraction Pipelines

Extract All NTLM Usernames + Domain + Workstation
tshark -r cap.pcap -Y “ntlmssp.messagetype==3″ \ -T fields -e frame.time -e ip.src -e ip.dst \ -e ntlmssp.auth.domain -e ntlmssp.auth.username -e ntlmssp.auth.workstation \ -E header=y -E separator=”|” | tee ntlm_auth.csv
Extract NTLMv2 Hashes for Hashcat (format: user::domain:challenge:response)
tshark -r cap.pcap -Y “ntlmssp.messagetype==3” \ -T fields -e ntlmssp.auth.username -e ntlmssp.auth.domain \ -e ntlmssp.ntlmserverchallenge -e ntlmssp.auth.ntresponse
Extract All Kerberos Usernames + Realms + SPNs
tshark -r cap.pcap -Y “kerberos” \ -T fields -e frame.time -e ip.src \ -e kerberos.CNameString -e kerberos.realm -e kerberos.sname \ -e kerberos.msg_type -e kerberos.error_code \ -E header=y -E separator=”|”
Identify AS-REP Roastable Accounts
tshark -r cap.pcap -Y “kerberos.msg_type==11 && !kerberos.encrypted_PA_DATA” \ -T fields -e ip.src -e kerberos.CNameString -e kerberos.realm
Identify Kerberoasting (RC4 TGS Requests)
tshark -r cap.pcap -Y “kerberos.msg_type==12 && kerberos.encryption_type==23” \ -T fields -e ip.src -e kerberos.CNameString -e kerberos.sname
Extract All LDAP Bind Credentials (Cleartext)
tshark -r cap.pcap -Y “ldap.protocolOp==0 && ldap.simple != ”” \ -T fields -e ip.src -e ldap.name -e ldap.simple \ -E header=y -E separator=”|”
SMB Session → User Correlation (NTLM over SMB)
tshark -r cap.pcap \ -Y “smb2.cmd==1 && ntlmssp.messagetype==3″ \ -T fields -e ip.src -e smb2.sesid \ -e ntlmssp.auth.domain -e ntlmssp.auth.username -e ntlmssp.auth.workstation \ -E header=y -E separator=”|”

Digital Forensics and Incident Response

Wireshark Threat Hunting – From Packets to Indicators Wireshark Threat Hunting – From Packets to Indicators [HTTP: DEEP-DIVE]