0
Red Team ADVANCED 15 min read Updated

Lateral Movement in AD: WMI, PsExec and WinRM

How lateral movement works in an AD estate: SMB/PsExec, WMI and WinRM execution, pass-the-hash, picking a technique by noise, plus detection and defense.

founder & security researcher · 39 writeups
Lateral Movement in AD: WMI, PsExec and WinRM

Lateral movement is how an operator turns a single foothold into control of an Active Directory estate, stepping from one host to the next with credentials that already work. You have a shell on one workstation, or a password, a hash, or a ticket for an account, and the question becomes which remote execution path to ride to the next box and how loud that path is. This guide walks the three workhorse techniques, PsExec over SMB, WMI, and WinRM, shows the standard tool invocation for each, chains them across a lab, and then flips to the defender side to cover what each one leaves in the logs and how to shut the paths down.

Read it top to bottom once to build the model, then keep it open as a reference while you work a lab. Every command here is meant for a domain you own or are explicitly authorized to assess.

Scope

Run everything below only inside a lab you built or an engagement you have written authorization for. The example estate is lab.local on 10.10.10.0/24 with a domain controller at 10.10.10.10 and a workstation at 10.10.10.20. Running code on hosts you do not own or control is a crime.

01What lateral movement is and where it sits

Lateral movement is the phase that starts once you own one box and ends when you own the ones that matter. In the MITRE ATT&CK model it is tactic TA0008, and the techniques here map to Remote Services (T1021) and Windows Management Instrumentation (T1047). It is not initial access and it is not privilege escalation on a single host. It is reuse: taking authentication material you already hold and spending it against another machine that trusts it.

In a real engagement the order is roughly fixed. You get in, you collect credentials, you move, and you repeat until you reach a domain controller or the data you were hired to reach. Lateral movement is the repeating middle of that loop, and each hop tends to feed the next by handing you fresh credentials from the new host.

where the hop fits in the loop
Initial access Credential access Lateral movement Domain control each hop yields new credentials

02What you need before you move

Before any lateral movement technique fires you need one of three things that prove who you are to the target, plus the right for that account to run code there. The authentication material comes in three shapes. A plaintext password is the simplest. An NTLM hash is the account's NT hash, which NTLM authentication accepts directly without the password behind it. A Kerberos ticket is a TGT or service ticket you present in place of either, which the tools call with a -k flag against a ticket in your cache.

Having an identity is only half of it. PsExec and WMI both expect the account to be a local administrator on the target, because they touch the service control manager, the admin shares, or the WMI namespace, all of which are admin gated. WinRM wants the account in the local Administrators group or in Remote Management Users. Confirm the right before you spend the credential: an account that is admin on one subnet and a plain user on another decides your whole route.

Check access first

Spray the credential with netexec across the subnet before you pick a technique. The (Pwn3d!) marker tells you which hosts the account can execute on, so you move with intent instead of guessing.

03SMB and PsExec style execution

PsExec style execution runs your command over SMB by creating a Windows service on the target. The impacket version, psexec.py, connects to port 445, writes a small service executable to the ADMIN$ share, registers it with the service control manager, and starts it. The service runs as LocalSystem, so you land in a SYSTEM shell, and input and output flow back over a named pipe. It is reliable and it gives you the highest privilege on the box, which is exactly why it is also the loudest option in the set.

what psexec touches on the target
Operator SMB 445 ADMIN$ sharedrop service .exe SCMregister + start SYSTEM shell
bash
# 0xpriv.dev/red-team
# psexec: SYSTEM shell via a service dropped on ADMIN$ (loud, leaves event 7045)
impacket-psexec lab.local/j.smith:'Autumn2026!'@10.10.10.20

# smbexec: a service per command, no binary dropped, output read back over SMB
impacket-smbexec lab.local/j.smith:'Autumn2026!'@10.10.10.20

smbexec.py is the close cousin that trades the dropped binary for a service that runs a single command through cmd.exe and redirects the output to a file on the share, which you then read back. Nothing lands on disk as an executable, but it creates and deletes a service for every command you type, so it trades one artifact for a stream of them. Both run as SYSTEM, both ride SMB, and both announce themselves to anyone watching service creation.

04WMI execution and why it is quieter

WMI execution uses Windows Management Instrumentation to start your process without creating a service, which is why it is the quieter choice. The impacket tool, wmiexec.py, reaches the target over DCOM (the RPC endpoint mapper on port 135 and then a dynamic high port), calls Win32_Process.Create to launch your command, and reads the output back from the ADMIN$ share. There is no new service, so there is no service creation event, and nothing is installed as a persistent object on the host.

bash
# wmiexec: semi-interactive shell over DCOM/WMI, no service created
# runs in the invoking user's context, not SYSTEM
impacket-wmiexec lab.local/j.smith:'Autumn2026!'@10.10.10.20

# fire a single command and read the output, no interactive prompt
impacket-wmiexec lab.local/j.smith:'Autumn2026!'@10.10.10.20 'whoami /groups'

Two differences from PsExec matter for an operator. First, the shell is semi-interactive: each command spawns a fresh process and the tool collects its output, so there is no live session the way a service pipe gives you. Second, the command runs in the context of the account you authenticated with rather than as SYSTEM, which can matter if you need SYSTEM level access for a follow-on action. You gain quiet, you give up the automatic privilege, and that trade is usually worth it on a monitored network.

a semi-interactive shell over WMI, no service created
$ impacket-wmiexec lab.local/j.smith:'Autumn2026!'@10.10.10.20
[*] SMBv3.0 dialect used
[!] Launching semi-interactive shell, type exit to quit
C:\> whoami
lab\j.smith
C:\> hostname
WS01

05WinRM execution with netexec and evil-winrm

WinRM execution rides Windows Remote Management, the same channel PowerShell Remoting uses, so it blends into traffic that administrators already generate. WinRM speaks over HTTP on port 5985 or HTTPS on 5986, and an account that is a local admin or a member of Remote Management Users can run commands through it. On a network where admins manage boxes with PowerShell Remoting all day, a WinRM session is far less conspicuous than a new service.

Start with netexec to confirm the account can use WinRM, then drop into an interactive session with evil-winrm when you want to work the host by hand.

bash
# netexec: check WinRM access across the subnet, then run one command
netexec winrm 10.10.10.0/24 -u j.smith -p 'Autumn2026!'
netexec winrm 10.10.10.20 -u j.smith -p 'Autumn2026!' -x 'whoami'

# evil-winrm: an interactive PowerShell session over WinRM
evil-winrm -i 10.10.10.20 -u j.smith -p 'Autumn2026!'

evil-winrm gives you a real PowerShell prompt with helpers for uploading and downloading files and loading scripts into memory. It also accepts a hash in place of a password, which is the bridge to the next section. Where PsExec and WMI run through SMB and DCOM, WinRM is HTTP, so if a host firewall blocks 445 but leaves 5985 open for management, WinRM is often the path that still works.

confirming WinRM access across the subnet
$ netexec winrm 10.10.10.0/24 -u j.smith -p 'Autumn2026!'
WINRM  10.10.10.10  5985  DC01  [*] Windows Server 2022 (name:DC01) (domain:lab.local)
WINRM  10.10.10.20  5985  WS01  [*] Windows 10 (name:WS01) (domain:lab.local)
WINRM  10.10.10.20  5985  WS01  [+] lab.local\j.smith:Autumn2026! (Pwn3d!)

06Using a hash instead of a password: pass-the-hash

Pass-the-hash lets you authenticate with an account's NTLM hash instead of its plaintext password. It works because NTLM authentication never sends the password itself: the client proves it knows the account by using the NT hash as the key in a challenge and response. If you hold the NT hash, you hold everything the protocol checks, so the plaintext is not needed. This is why dumping hashes from one host so often unlocks execution on the next.

Every tool in this guide accepts a hash in the same way. impacket takes -hashes LMHASH:NTHASH, where the LM half is usually blank, so you pass a leading colon. netexec and evil-winrm take -H. The command is otherwise identical to the password version.

bash
# pass-the-hash: same techniques, NT hash in place of the password
# the LM half is blank, so it starts with a colon
impacket-wmiexec -hashes : lab.local/[email protected]
netexec smb 10.10.10.10 -u administrator -H 
evil-winrm -i 10.10.10.20 -u administrator -H 

One limit worth keeping straight: pass-the-hash is an NTLM trick, so it does not apply to Kerberos. The Kerberos equivalent is pass-the-ticket, where you present a stolen TGT or service ticket, and overpass-the-hash, where you turn an NT hash into a Kerberos TGT. Those are separate techniques with their own tooling, and the tools flag them with -k rather than -hashes.

Accounts with reused secrets

Pass-the-hash spreads fastest through a shared local administrator password. If every workstation has the same local admin hash, one dump moves you to all of them. That single misconfiguration is what the LAPS mitigation later in this guide exists to kill.

07Choosing a technique by noise and footprint

Choosing a technique comes down to how much noise you can afford and what artifacts each one leaves on the target. There is no single best option: the right call depends on what the defenders watch, which ports are open, and whether you need SYSTEM. The table lines up the three on the things that decide it in practice.

TechniquePortMain artifactRuns asRelative noise
psexecSMB 445Service install (7045) plus a binary on ADMIN$SYSTEMHigh
smbexecSMB 445A service per command, output file on the shareSYSTEMHigh
wmiexecDCOM 135 plus SMBTemp output file on ADMIN$, no serviceCallerLower
evil-winrmWinRM 5985WinRM and PowerShell logs, no serviceCallerLower, blends in

A rule of thumb that holds up on most engagements: start with WMI or WinRM for quiet work, and keep PsExec in reserve for when you genuinely need SYSTEM or when the quieter paths are blocked. If the environment manages hosts with PowerShell Remoting, WinRM hides in plain sight. If SMB is the only admin path open, PsExec or WMI it is, and you accept the extra noise.

08A worked walkthrough across the lab

This walkthrough chains the techniques across the 10.10.10.0/24 lab, moving from a single working credential to the domain controller. Treat it as the shape of a route, not a script to paste. The account j.smith has a password recovered during credential access, and the goal is to reach DC01 at 10.10.10.10.

Spray and spot admin

Run the credential across the subnet with netexec over SMB. The (Pwn3d!) marker shows j.smith is a local admin on WS01 at 10.10.10.20.

Move quietly to WS01

Pick wmiexec over psexec on the first hop, because WS01 is a workstation likely to be watched and you do not need SYSTEM yet.

Collect the next credential

On WS01, in a real engagement, you gather the material that moves you forward, such as a cached local admin hash reused across the fleet.

Pass the hash to DC01

Reuse the recovered hash against 10.10.10.10. If the administrator secret is shared, the same hash authenticates on the domain controller.

spraying one credential and spotting admin access
$ netexec smb 10.10.10.0/24 -u j.smith -p 'Autumn2026!'
SMB  10.10.10.10  445  DC01  [*] Windows Server 2022 (domain:lab.local) (signing:True)
SMB  10.10.10.20  445  WS01  [*] Windows 10 (domain:lab.local) (signing:False)
SMB  10.10.10.10  445  DC01  [+] lab.local\j.smith:Autumn2026!
SMB  10.10.10.20  445  WS01  [+] lab.local\j.smith:Autumn2026! (Pwn3d!)
reusing a recovered NT hash against the domain controller
$ netexec smb 10.10.10.10 -u administrator -H 
SMB  10.10.10.10  445  DC01  [*] Windows Server 2022 (domain:lab.local)
SMB  10.10.10.10  445  DC01  [+] lab.local\administrator: (Pwn3d!)

Four moves from one password to the domain controller, and only one of them is loud. That is the point of choosing by footprint: the route that reaches the goal with the fewest service installs and the fewest unusual logons is the one a defender is least likely to catch in time.

09Detection: the events that give it away

Detecting lateral movement means reading the logon, service, and management protocol events each technique writes. Every method here authenticates to the target, so it generates a logon event 4624, and remote execution is almost always a network logon, type 3. When an administrative account logs on, Windows also writes event 4672 for the special privileges assigned. A sudden network logon by a privileged account on a host it never touches is one of the clearest signals you have.

From there the techniques split by their artifacts. PsExec and smbexec install a service, so they write event 7045 in the System log (and 4697 in Security when service auditing is on). WMI execution shows up in the Microsoft-Windows-WMI-Activity/Operational log and, with Sysmon, as a process creation (event 1) where WmiPrvSE.exe is the parent of cmd.exe or powershell.exe. WinRM execution lands in the Microsoft-Windows-WinRM/Operational log and spawns wsmprovhost.exe, and PowerShell script block logging (event 4104) captures what ran.

powershell
# hunt the service installs PsExec and smbexec leave behind
Get-WinEvent -FilterHashtable @{LogName='System'; Id=7045} |
  Select-Object TimeCreated, Message

# network logons (type 3) that back remote execution
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} |
  Where-Object { $_.Properties[8].Value -eq 3 } |
  Select-Object TimeCreated, @{n='User';e={$_.Properties[5].Value}}
Watch the parents, not the names

Attackers rename tools freely, so match on behaviour. WmiPrvSE.exe or services.exe giving birth to a command interpreter, and wsmprovhost.exe spawning anything unusual, are strong leads no matter what the child is called. Sysmon process creation plus parent tracking catches all three techniques.

10Defense: shutting the paths down

Defending against lateral movement is about denying the shared credentials and open paths it depends on, not about chasing individual tools. The techniques are built on legitimate Windows features, so you cannot simply turn them off. You make them stop working by removing what they reuse: shared secrets, over broad admin rights, and unrestricted host to host traffic.

How to shut it down
Run a tiered admin model. Keep tier 0 accounts (domain admins) off tier 1 and tier 2 hosts entirely, so a workstation compromise never exposes a credential that works on a domain controller.
Deploy LAPS. Give every machine a unique, rotating local administrator password. This single control kills pass-the-hash across a fleet that once shared one local admin secret.
Restrict local admin and lateral paths. Trim local Administrators membership to what is needed, and use the host firewall to block inbound SMB (445) and WinRM (5985) between workstations, which have no reason to execute on each other.
Disable WDigest. Set UseLogonCredential to 0 so plaintext credentials are not cached in LSASS. Modern Windows defaults this off, but confirm it rather than assume it.
Practice credential hygiene. Put privileged accounts in the Protected Users group, enable Credential Guard where you can, and limit where sensitive accounts are allowed to log on with the "Deny access to this computer from the network" right.

11FAQ

Do I need to be a local admin to move laterally?FAQ

For PsExec and WMI, yes, because they touch the service control manager, the admin shares, or the WMI namespace, which are all admin gated. WinRM needs the account in the local Administrators group or in Remote Management Users. A plain domain user with no local rights on the target cannot run code through any of these paths.

Why is wmiexec considered quieter than psexec?FAQ

wmiexec starts your process through WMI instead of installing a service, so it never writes the service creation event (7045) that psexec does, and it drops no executable on disk. It still leaves a logon event and a temporary output file on the ADMIN$ share, so quieter does not mean silent.

Does pass-the-hash work against Kerberos?FAQ

No. Pass-the-hash is an NTLM technique that reuses the NT hash in the NTLM challenge and response. The Kerberos equivalents are pass-the-ticket, where you present a stolen ticket, and overpass-the-hash, where you convert an NT hash into a Kerberos TGT. Tools select those with a -k flag rather than -hashes.

Which single control stops the most lateral movement?FAQ

LAPS, by a wide margin, in estates that once shared a local administrator password. A unique, rotating local admin secret per host means a hash dumped from one machine authenticates nowhere else, which breaks the most common pass-the-hash chain outright.

Can defenders just block these tools by name?FAQ

No, because operators rename binaries and the underlying features are legitimate. Detection has to key on behaviour: network logons by privileged accounts on unusual hosts, service installs, and management hosts like WmiPrvSE.exe or wsmprovhost.exe spawning command interpreters.

12Wrapping up

Lateral movement is credential reuse with a choice of transport. PsExec gives you SYSTEM over SMB at the cost of a service install, WMI trades that privilege for a quieter run with no service, and WinRM hides inside the PowerShell Remoting traffic admins already generate. A hash stands in for a password on all of them, which is why one dumped secret so often becomes the whole domain. Learn the three on a lab, pick by footprint rather than habit, and remember that the defenses that matter most, unique local admin passwords and a tiered admin model, break the reuse the techniques depend on.

references

Was this writeup useful?
Alex Rowan Founder & Security Researcher at 0xpriv

Founder of 0xpriv, covering offensive security, web application vulnerabilities, and practical security research through PHP, Python, and hands-on technical analysis.

related writeups

more in Red Team →

discussion

0 comments
`code` supported · comments are reviewed before they appear