Smbmap
smbmap answers one question fast: given some level of access to a host on port 445, which shares exist and what can you actually do with each one? It lists shares with your effective READ or WRITE permissions, walks directory trees, pulls and pushes files, and (with admin rights) runs remote commands. Reach for it the moment Nmap shows 445 open and you want a permission map before you start clicking around a mounted share.
Mental model: smbmap -H TARGET_IP [auth] [action]. Everything else is one flag away.
New to SMB? Core concepts
- Share: a named network folder, for example
C$,ADMIN$,IPC$, or a customData.C$andADMIN$are admin-only - Null session: an unauthenticated login,
-u '' -p ''; some hosts still allow it - Permission flags: smbmap reports
READ ONLY,READ, WRITE, orNO ACCESSper share - these are your effective rights, not the share’s global ACL - Authentication: local user, domain user (
-d DOMAIN), guest, or an NTLM hash (-p LM:NT) - Ports: SMB over TCP
445(modern) or139(legacy NetBIOS), set with-P - Recursion:
-rpeeks one level,-Rwalks the whole tree so you see files, not just share names - Remote exec:
-xruns a command over SMB, needs admin rights, and leaves a service artifact (loud) - UNC path: smbmap addresses files as
SHARE\folder\file, backslash separated
When to reach for smbmap (and when not)
Reach for it to map which shares an account can touch and at what permission, sweep for world-readable or writable shares, confirm a permission change actually removed anonymous READ, or validate what a fresh credential reaches before deeper work.
Reach for something else when you want to interactively browse and get/put one known share (smbclient), run the same share checks across many hosts at once (netexec), enumerate users, groups, and policies beyond shares (enum4linux-ng, rpcclient, ldapsearch), or need scriptable execution primitives (impacket’s psexec.py / smbexec.py).
Install, update, verify#
sudo apt install -y smbmap # Debian / Ubuntu / Kali
pipx install smbmap # isolated, on non-Kali Linux
sudo apt install --only-upgrade -y smbmap # update (or: pipx upgrade smbmap)
smbmap -h # confirm it runs, show the option groups
command -v smbmap # confirm it is on PATH
smbmap is Python and runs entirely from your attacker box; nothing is installed on the target. From a git clone, call it as python3 smbmap.py in the clone directory. The -h output touches no network, so it is the safe first test: a clean option listing means it works, a traceback means a dependency problem in a pip install.
Flags you’ll actually use#
Skim these first; the cheat sheet below is these flags combined.
| Flag | Does | Flag | Does |
|---|---|---|---|
-H | Target host | -s | Limit to one share |
--host-file | Read targets from a file | -r | List one level inside shares |
-u / -p | User / password (or LM:NT hash) | -R | Recurse the full tree |
-d | Domain for a domain account | --depth | Cap how deep -R walks |
-P | Port (445 default, 139 legacy) | -A | Auto-download files matching a regex |
-L | List all drives, incl. admin shares | --download | Pull a file SHARE\path |
-v | Show the target OS / version | --upload | Push a local file to SHARE\path |
-x | Run a remote command (admin, loud) | --delete | Delete a remote file |
Cheat sheet#
Each block starts simple and adds one flag at a time, so you can stop at the line that does the job.
# Build up an enumeration: stop at the line you need
smbmap -H TARGET_IP -u '' -p '' # 1. null-session share table
smbmap -H TARGET_IP -u 'guest' -p '' # 2. guest, when null is refused
smbmap -H TARGET_IP -u USERNAME -p PASSWORD # 3. + authenticated
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -d DOMAIN # 4. + domain account
# Pass-the-hash (NTLM, no password to crack)
smbmap -H TARGET_IP -u USERNAME -p 'aad3b435b51404eeaad3b435b51404ee:NTHASH'
# Look inside shares
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -r # top level of every readable share
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -s SHARE -r # just one share
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -R SHARE # full tree of one share
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -R SHARE --depth 5 # cap the descent
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -L # all drives incl. C$/ADMIN$
# Pull and push files (need the matching permission)
smbmap -H TARGET_IP -u USERNAME -p PASSWORD --download 'SHARE\notes\creds.txt'
smbmap -H TARGET_IP -u USERNAME -p PASSWORD --upload ./local.txt 'SHARE\remote.txt'
smbmap -H TARGET_IP -u USERNAME -p PASSWORD --delete 'SHARE\remote.txt'
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -R -A '.*\.(txt|ini|conf|config)$' # grab matches
# Many hosts (small batch)
smbmap --host-file hosts.txt -u USERNAME -p PASSWORD
# Authorized remote command execution (admin rights, very loud)
smbmap -H TARGET_IP -u ADMINUSER -p PASSWORD -x 'whoami'
# Legacy / tuning
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -P 139 # NetBIOS port
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -v # print target OS/version
# Save for notes
smbmap -H TARGET_IP -u USERNAME -p PASSWORD | tee notes/shares.txt
Command breakdowns#
Each block below explains one situation, the exact command, and what to expect back.
List shares over a null session#
smbmap -H TARGET_IP -u '' -p ''
The fastest first look, no credentials needed. Success is a share table with READ ONLY / READ, WRITE / NO ACCESS flags. An access-denied message or empty table just means null sessions are restricted, which is itself worth knowing.
Try a guest login when null fails#
smbmap -H TARGET_IP -u 'guest' -p ''
Some hosts refuse the null session but still allow guest. Same output as above. Cheap to try before you spend a real credential.
List shares with a real account#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD
Shows every share the account can see plus its effective permissions. Authenticated listings usually reveal far more than anonymous ones.
Authenticate as a domain user#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -d DOMAIN
Against a domain-joined host, forgetting -d DOMAIN is the classic reason access looks thin. The domain context often unlocks shares a local login cannot see.
List admin drives (C$, ADMIN$)#
smbmap -H TARGET_IP -u ADMINUSER -p PASSWORD -L
-L enumerates all drives on the host, including hidden admin shares like C$ and ADMIN$. If these come back readable, the account is effectively local admin.
Peek one level inside every readable share#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -r
-r lists the top layer of files and folders in each readable share, so you see contents instead of only share names, without drowning in a full tree.
Walk the full tree of one share#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -R 'Department Share'
-R recurses the whole share. Point it at one interesting share, not everything, or the output (and the target’s file-access logs) explodes.
Cap how deep the recursion goes#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -R SHARE --depth 5
--depth limits -R to a fixed number of directory levels. Handy on deep or noisy shares where you want structure without every leaf file.
Download a specific file#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD --download 'SHARE\notes\creds.txt'
Pulls one file to your working directory using its SHARE\path UNC form. Single-quote the path so the shell leaves the backslashes alone.
Upload a file to a WRITE share#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD --upload ./local-note.txt 'SHARE\remote-note.txt'
Local source first, then the remote destination. Only works where the flag says READ, WRITE; confirm the write is in scope before you use it.
Auto-download every file matching a pattern#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD -R -A '.*\.(txt|ini|conf|config)$'
-A takes a regex and pulls every matching file it finds while recursing. Keep the pattern tight, a loose one grabs huge or sensitive trees.
Pass the hash instead of a password#
smbmap -H TARGET_IP -u USERNAME -p 'aad3b435b51404eeaad3b435b51404ee:NTHASH'
Supply the full LM:NT hash in the password slot. Same result as a password login, useful right after dumping a hash in the lab, no cracking required.
Run an authorized remote command#
smbmap -H TARGET_IP -u ADMINUSER -p PASSWORD -x 'whoami'
-x executes a command over SMB and prints the result. It needs admin rights, leaves a service artifact, and is the loudest thing smbmap does. Confirm scope first.
Sweep a small batch of hosts#
smbmap --host-file hosts.txt -u USERNAME -p PASSWORD
--host-file runs the same listing against every IP in the file, one per line. Good for a handful of hosts; for a real subnet sweep switch to netexec.
Save the share table to your notes#
smbmap -H TARGET_IP -u USERNAME -p PASSWORD | tee notes/shares.txt
Keeps a clean, greppable record you can attach to a report while still seeing it live in the terminal.
Reading the output#
| You see | Meaning | Do next |
|---|---|---|
READ ONLY | You can list and download | Recurse with -R, pull anything useful |
READ, WRITE | You can also upload, modify, delete | High value; confirm what the write enables |
NO ACCESS | Share exists, your account cannot enter | Note it, try another credential |
| Disk / Comment column | Share name plus its description | Read the comment for intent hints |
| Empty share table | Session worked, nothing exposed | Try other creds or a domain account |
STATUS_LOGON_FAILURE | Login rejected | Wrong creds, or missing -d DOMAIN |
The flags are your effective rights, not the share’s global ACL. A different account can see a completely different set, so re-run after switching credentials rather than trusting an earlier table.
Troubleshooting#
| Problem | Cause | Fix |
|---|---|---|
command not found | Not installed / stale PATH | Reinstall; open a fresh shell; or python3 smbmap.py from a clone |
STATUS_LOGON_FAILURE | Bad credentials | Recheck -u/-p, add -d DOMAIN |
STATUS_ACCESS_DENIED | Account lacks rights on that share | Try guest, another account, or accept NO ACCESS |
Connection refused / timeout | 445 closed or filtered | Confirm with Nmap; try -P 139; check the route/scope |
STATUS_LOGON_TYPE_NOT_GRANTED | Account cannot log on remotely | Use a different account or method |
| Empty share list | Null session restricted | Authenticate with valid credentials |
| Python traceback (pip install) | Dependency mismatch | Reinstall in a clean venv, or use the apt package |
-x returns nothing | Not admin, or exec is blocked | Confirm admin rights and scope; exec is not always available |
Gotchas#
NO ACCESSmeans “not with this account,” not “empty.” A domain or admin credential can light up shares a null session never sees.- A
READ, WRITEflag is a lead, not impact. Confirm what writing there actually enables (web root, startup folder, config) before you report it. - SMB paths use backslashes:
'SHARE\folder\file'. Single-quote them so the shell does not eat the backslash or mangle sequences like\f. -xis the loudest action. It drops a service or named-pipe artifact and generates process-creation events (4688) that EDR flags fast; use it only with admin rights and explicit scope.- Permission flags are per-account, per-session. Do not carry an old table forward after changing credentials, re-run and re-read.
- A full
-Ron a huge share floods your terminal and the target’s file-access logs (5140/5145). Scope it with-s SHAREand--depth.
Pairs with#
nmap -p139,445 TARGET_RANGE finds the hosts with SMB exposed before you point smbmap at them. smbclient gives a shell-like session for browsing and get/put once smbmap shows where to look, while netexec runs the same share checks across many hosts at once. For enumeration beyond shares (users, groups, policies) reach for enum4linux-ng, rpcclient, or ldapsearch; for scriptable execution primitives use impacket’s psexec.py or smbexec.py. Pipe the share tables through tee and grep to keep tidy, searchable notes.