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 custom Data. C$ and ADMIN$ are admin-only
  • Null session: an unauthenticated login, -u '' -p ''; some hosts still allow it
  • Permission flags: smbmap reports READ ONLY, READ, WRITE, or NO ACCESS per 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) or 139 (legacy NetBIOS), set with -P
  • Recursion: -r peeks one level, -R walks the whole tree so you see files, not just share names
  • Remote exec: -x runs 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.

FlagDoesFlagDoes
-HTarget host-sLimit to one share
--host-fileRead targets from a file-rList one level inside shares
-u / -pUser / password (or LM:NT hash)-RRecurse the full tree
-dDomain for a domain account--depthCap how deep -R walks
-PPort (445 default, 139 legacy)-AAuto-download files matching a regex
-LList all drives, incl. admin shares--downloadPull a file SHARE\path
-vShow the target OS / version--uploadPush a local file to SHARE\path
-xRun a remote command (admin, loud)--deleteDelete 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 seeMeaningDo next
READ ONLYYou can list and downloadRecurse with -R, pull anything useful
READ, WRITEYou can also upload, modify, deleteHigh value; confirm what the write enables
NO ACCESSShare exists, your account cannot enterNote it, try another credential
Disk / Comment columnShare name plus its descriptionRead the comment for intent hints
Empty share tableSession worked, nothing exposedTry other creds or a domain account
STATUS_LOGON_FAILURELogin rejectedWrong 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#

ProblemCauseFix
command not foundNot installed / stale PATHReinstall; open a fresh shell; or python3 smbmap.py from a clone
STATUS_LOGON_FAILUREBad credentialsRecheck -u/-p, add -d DOMAIN
STATUS_ACCESS_DENIEDAccount lacks rights on that shareTry guest, another account, or accept NO ACCESS
Connection refused / timeout445 closed or filteredConfirm with Nmap; try -P 139; check the route/scope
STATUS_LOGON_TYPE_NOT_GRANTEDAccount cannot log on remotelyUse a different account or method
Empty share listNull session restrictedAuthenticate with valid credentials
Python traceback (pip install)Dependency mismatchReinstall in a clean venv, or use the apt package
-x returns nothingNot admin, or exec is blockedConfirm admin rights and scope; exec is not always available

Gotchas#

  • NO ACCESS means “not with this account,” not “empty.” A domain or admin credential can light up shares a null session never sees.
  • A READ, WRITE flag 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.
  • -x is 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 -R on a huge share floods your terminal and the target’s file-access logs (5140/5145). Scope it with -s SHARE and --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.

Find us elsewhere

Merch, stickers, and moreSupport the work at the Solvere Labs shop