Skip to content

08 · Lateral Movement

Lateral Movement Forensics: RDP, PsExec, WMI and WinRM

Map source and destination artifacts for RDP, PsExec, SMB, WMI, WinRM, scheduled tasks and DCOM, then build a cross-host lateral movement graph.

Published on 11 min read

Lateral movement is where a single compromised workstation becomes a domain-wide incident. This guide maps, technique by technique, which artifacts appear on the source host (where the attacker is) and which appear on the destination host (where they land), so you can prove each hop and chain them into a graph. By the end you should be able to pick the right logs for RDP, PsExec, SMB, WMI, WinRM, scheduled tasks and DCOM, and know which indicators suggest stolen hashes or explicit credentials.

If you are new to Windows event logs, start with the event log overview and the logon type reference, since almost every section below depends on them.

The source vs destination mindset

Every hop has two ends. The destination usually logs the most: an authentication (4624), a session, a service or a process creation. The source logs less, and what it logs is often user-side: client history, Prefetch for the tool that was launched, explicit credential use (4648). Investigators who only look at destinations can say "someone got in from 10.1.2.3" but not what that host did next. Investigators who only look at sources miss hops started from tooling that never touched disk.

Two rules keep you honest:

  • Pivot on the source IP and the logon ID. The IpAddress field of a 4624 on the destination tells you which host to collect next. The TargetLogonId links that logon to every later event of the same session.
  • Check your auditing baseline. Several events used here (4688 process creation, 5140/5145 share access, 4698 task creation) only exist if the matching audit subcategory was enabled. Absence of evidence is often absence of auditing.

RDP

RDP is the most visible technique because it creates an interactive session with its own lifecycle events. The RDP connections page has the full field reference.

Destination

  • Security 4624, logon type 10 (RemoteInteractive). A reconnect to an existing session, or an unlock, shows type 7. With Network Level Authentication you will often also see a type 3 logon just before the type 10.
  • Security 4778 / 4779: session reconnected / disconnected, with client name and address. These are useful for measuring how long a session actually lasted.
  • TerminalServices-RemoteConnectionManager/Operational 1149: network authentication succeeded, with user, domain and source IP. It is logged before the session exists, so treat it as "authenticated", not "logged on".
  • TerminalServices-LocalSessionManager/Operational: 21 (session logon), 22 (shell start), 24 (disconnected), 25 (reconnected), 23 (logoff). Event 22 is the one that tells you a desktop was actually delivered.
  • Process creation under the RDP session (rdpclip.exe, tstheme.exe) and the usual user activity artifacts for the account on that host.

Source

  • NTUSER.DAT\Software\Microsoft\Terminal Server Client\Default holds MRU0 to MRU9, the servers typed into the client. ...\Servers\<host> holds UsernameHint, the account used for that host. See NTUSER.DAT for hive handling.
  • TerminalServices-RDPClient/Operational 1024 (client attempting to connect to a named server) and 1102 (client initiated a multi-transport connection to an IP).
  • Documents\Default.rdp (hidden) keeps the settings of the last connection, including full address.
  • The RDP bitmap cache under %LOCALAPPDATA%\Microsoft\Terminal Server Client\Cache\ stores tiles of what the user saw on the remote screen. Reassembled, they can show the attacker's desktop on the destination.
  • Prefetch and Jump Lists for mstsc.exe, and a 4648 if alternate credentials were typed.

PsExec and other service-based execution

PsExec copies a service binary to the ADMIN$ share, creates a service through the Service Control Manager, and talks to it over named pipes. Impacket's psexec.py, smbexec.py and many C2 frameworks follow the same pattern with different names.

Destination

  • Security 4624 type 3 from the source IP, usually with a 4672 (special privileges) because administrative rights are required. When -u is given with explicit credentials, you may also see a separate logon for the account the remote process runs as; do not rely on a specific type there.
  • Security 5140 / 5145: access to \\*\ADMIN$ and to PSEXESVC.exe inside it (needs "File Share" and "Detailed File Share" auditing).
  • System 7045: service installed, service name PSEXESVC and image path %SystemRoot%\PSEXESVC.exe by default. With -r <name>, both the service name and binary name change, so hunt on the structure rather than the name. 7036 records the service entering the running and stopped states.
  • The service key under HKLM\SYSTEM\CurrentControlSet\Services\ (see services), usually deleted when PsExec exits cleanly but sometimes left behind after a crash or kill.
  • Prefetch for PSEXESVC.EXE (or the renamed binary) and for whatever was run through it. Child processes have the service binary as parent.

Source

  • Prefetch for PsExec.exe / PsExec64.exe, plus Amcache and ShimCache entries for the binary.
  • NTUSER.DAT\Software\Sysinternals\PsExec with EulaAccepted, created the first time the user accepted the EULA (bypassed with -accepteula, which still writes it).
  • 4648 when -u is used, naming the target server.

SMB and admin shares

Mapping C$ or ADMIN$ is often the step before PsExec, a copy of tools, or data staging.

  • Destination: 4624 type 3, 4672 for admins, 5140 (share accessed) and 5145 (file in share accessed), plus Microsoft-Windows-SMBServer operational logs on recent builds. New files in C:\Windows\ or C:\Windows\Temp\ with a creation time matching the logon are the classic follow-up.
  • Source: Prefetch for net.exe / net1.exe, MountPoints2 entries in NTUSER.DAT for shares mounted through Explorer, ShellBags if the user browsed the share, and 4648 if net use was given credentials.

WMI

Remote WMI (wmic /node:, Invoke-WmiMethod, Invoke-CimMethod, Impacket wmiexec.py) calls Win32_Process.Create on the destination.

  • Destination: 4624 type 3 with 4672. Processes spawned by WmiPrvSE.exe are the key indicator: a cmd.exe or powershell.exe whose parent is WmiPrvSE.exe deserves a look (4688 or Sysmon 1). Microsoft-Windows-WMI-Activity/Operational records provider activity and errors (5857, 5858), and permanent event subscriptions (5861), which is where WMI crosses into persistence (see the WMI repository). wmiexec.py also tends to redirect output to a file on ADMIN$, so 5145 can help.
  • Source: Prefetch for wmic.exe or PowerShell logs showing the WMI cmdlets, and 4648 if credentials were supplied.

WinRM and PowerShell remoting

Enter-PSSession, Invoke-Command and winrs all ride on WinRM (TCP 5985/5986).

Destination

  • 4624 type 3 for the connecting account.
  • wsmprovhost.exe is the host process of the remote session: anything it spawns ran through remoting. Prefetch for WSMPROVHOST.EXE is a quick check that remoting was ever used on the host.
  • Microsoft-Windows-WinRM/Operational: 91 (creating a shell / request handling), 168 (authentication of the user), among others. Event wording varies by build, so read the message text rather than trusting the ID alone.
  • PowerShell: Microsoft-Windows-PowerShell/Operational 4103 (module logging) and 4104 (script block logging, including the remote commands), and the classic Windows PowerShell log with 400/403 where the HostApplication or HostName indicates ServerRemoteHost. See PowerShell artifacts.

Source

  • Microsoft-Windows-WinRM/Operational 6 (creating a WSMan session, with the destination name), then connection events for the same shell.
  • PowerShell 4103/4104 on the source as well, and ConsoleHost_history.txt in the user profile if the commands were typed interactively.
  • 4648 if -Credential was used.

Remote scheduled tasks

schtasks /create /s <host> or the Task Scheduler COM API registers a task on the destination.

  • Destination: 4624 type 3, 4698 (task created), 4702 (updated), 4699 (deleted), which require "Other Object Access Events" auditing. Microsoft-Windows-TaskScheduler/Operational 106 (registered), 140 (updated), 141 (deleted), 200/201 (action started/completed). The task XML in C:\Windows\System32\Tasks\ and the TaskCache registry keys remain after the log rolls. Details on the scheduled tasks page.
  • Source: Prefetch for schtasks.exe and a 4648 if credentials were supplied. Attackers often create, run and delete the task within seconds, so look for 4698 and 4699 close together.

DCOM

DCOM lateral movement abuses objects such as MMC20.Application, ShellWindows or ShellBrowserWindow to execute commands remotely over RPC.

  • Destination: 4624 type 3, then an unusual process tree: a shell spawned by mmc.exe (MMC20) or by explorer.exe (ShellWindows / ShellBrowserWindow), or by DllHost.exe for other objects. Without process creation auditing or EDR, DCOM is hard to prove; Prefetch and memory are your fallbacks.
  • Source: usually only PowerShell logs or the tool that made the call.

Credential indicators: explicit credentials and pass-the-hash

  • 4648 (logon with explicit credentials) is logged on the host where the credentials were used, naming the target account and target server. On a source host it is one of the best records of "this user reached out to that server as that account".
  • 4624 type 9 (NewCredentials) with logon process seclogo is what runas /netonly produces, and also what pass-the-hash tooling produces when it spawns a process with injected credentials. The local identity stays the same; the network identity changes.
  • On destinations, pass-the-hash appears as 4624 type 3 with NTLM authentication (AuthenticationPackageName = NTLM) where you would normally expect Kerberos. 4776 (credential validation) is logged on the domain controller for domain accounts, and on the destination itself for local accounts.
  • Local administrator accounts reused across hosts (same password, same hash) are the usual enabler. A spray of NTLM type 3 logons for Administrator from a single source IP is a pattern worth graphing.

Source to destination reference table

TechniqueSource hostDestination host
RDPTerminal Server Client MRU/Servers, Default.rdp, RDPClient 1024/1102, bitmap cache, mstsc.exe Prefetch, 46484624 type 10/7, 4778/4779, RCM 1149, LSM 21/22/24/25
PsExecPsExec.exe Prefetch/Amcache, Sysinternals\PsExec key, 46484624 type 3, 4672, 5145 ADMIN$, 7045 PSEXESVC, PSEXESVC.EXE Prefetch
SMB / admin sharesnet.exe Prefetch, MountPoints2, ShellBags, 46484624 type 3, 5140/5145, new files in C:\Windows
WMIwmic.exe Prefetch, PowerShell logs, 46484624 type 3, children of WmiPrvSE.exe, WMI-Activity
WinRM / PS remotingWinRM 6, PowerShell 4103/4104, ConsoleHost_history.txt, 46484624 type 3, wsmprovhost.exe, WinRM 91/168, PowerShell 4103/4104, 400/403
Scheduled taskschtasks.exe Prefetch, 46484624 type 3, 4698/4699/4702, TaskScheduler 106/140/141/200/201, task XML
DCOMPowerShell / tool artifacts4624 type 3, shells spawned by mmc.exe, explorer.exe or DllHost.exe
Pass-the-hash4624 type 9 seclogo4624 type 3 NTLM, 4776 (DC or local)

MITRE ATT&CK catalogues these under Lateral Movement (TA0008), which is useful for mapping findings in a report.

Building the lateral movement graph

A lateral movement investigation is a graph problem: hosts are nodes, authenticated hops are edges. Build it from destination logs first, because they are richer, then confirm edges from the source side.

  1. Collect Security, System, TerminalServices, WinRM, PowerShell, TaskScheduler and WMI-Activity logs from every host in scope, plus domain controller Security logs. A triage collection with KAPE or Velociraptor is enough; see acquisition and triage.
  2. Normalise everything to CSV with one parser and one time zone (UTC).
  3. Extract edges: for each 4624 type 3/10 and each 4648, record time, source IP or workstation, destination host, account and logon ID. Resolve IPs to hostnames with DHCP logs or DNS, since IPs move.
  4. Filter noise: drop machine accounts, known admin jump hosts and service accounts you have explained, but keep a list of what you dropped.
  5. Walk from patient zero forward in time, and from each destination backwards to its source. An edge you can see from both ends is strong; an edge seen only on one side is a lead.
# Parse all event logs from a triage collection with EvtxECmd
EvtxECmd.exe -d C:\cases\HOST01\C\Windows\System32\winevt\Logs --csv C:\cases\out --csvf HOST01_evtx.csv

# Quick live check of network and RDP logons on a host
Get-WinEvent -FilterHashtable @{LogName='Security'; Id=4624} |
  Where-Object { $_.Properties[8].Value -in 3,10 } |
  Select-Object TimeCreated,
    @{n='User';e={$_.Properties[5].Value}},
    @{n='LogonType';e={$_.Properties[8].Value}},
    @{n='SourceIP';e={$_.Properties[18].Value}}

Then drop the edge list into a spreadsheet pivot, a graph tool, or your super timeline (see building a super timeline with Plaso) so the hops sit next to file and execution evidence.

Tools

  • EvtxECmd (Eric Zimmerman): maps normalise the key fields of hundreds of event IDs, which makes the edge extraction above a filter on a CSV.
  • Hayabusa: Sigma-based fast triage of EVTX, with built-in rules for PsExec, RDP and WinRM patterns and a logon summary mode.
  • Chainsaw: Sigma hunting and keyword/ID search over EVTX, good for sweeping many hosts quickly.
  • Velociraptor: run the same hunt across the fleet, for example Windows.EventLogs.RDPAuth for RDP logons or Windows.EventLogs.EvtxHunter for arbitrary IDs, and collect the evidence in one pass.
# Hayabusa: timeline and logon summary for a folder of EVTX files
hayabusa csv-timeline -d ./HOST01/Logs -o HOST01_hayabusa.csv
hayabusa logon-summary -d ./HOST01/Logs

# Chainsaw: Sigma hunt, then a targeted search for service installs
chainsaw hunt ./HOST01/Logs -s ./sigma/rules --mapping ./mappings/sigma-event-logs-all.yml --csv --output ./out
chainsaw search -t 'Event.System.EventID: =7045' ./HOST01/Logs

Command-line flags change between releases of these tools; check --help on the version you run.

When network captures are available, PCAP Parser opens pcap and pcapng files client-side to confirm SMB, RDP, WinRM (5985/5986) and RPC conversations between the hosts on your graph.

Common mistakes

  • Treating 1149 as a successful RDP logon. It proves authentication, not a delivered desktop. Confirm with 4624 type 10 and LSM 21/22.
  • Hunting on tool names only. PSEXESVC is trivially renamed with -r, and Impacket uses random names. Hunt on behaviours: service installs pointing to ADMIN$, shells under WmiPrvSE.exe or wsmprovhost.exe.
  • Forgetting the domain controller. 4768/4769 (Kerberos) and 4776 (NTLM) on DCs confirm edges when host logs have rolled.
  • Ignoring log retention. The Security log on a busy server can cover only hours. Check the oldest event before concluding that nothing happened.
  • Trusting WorkstationName over IpAddress. The workstation name is supplied by the client and can be spoofed or empty.
  • Assuming missing events mean no activity. Verify the audit policy first, and look for log clearing (1102 / 104), covered in detecting anti-forensics.

Workflow checklist

  1. Identify the first known compromised host and the time window.
  2. Collect event logs, registry hives and Prefetch from it and from every host it authenticated to; add DC Security logs.
  3. Check audit policy and log retention on each host.
  4. Extract logon edges (4624 types 3/9/10/7, 4648, 4776) and resolve IPs to hosts.
  5. For each edge, identify the technique with the destination artifacts: 7045 (service), 4698 (task), WmiPrvSE.exe or wsmprovhost.exe children, TerminalServices events.
  6. Confirm from the source side: Prefetch, client registry keys, 4648, PowerShell and WinRM logs.
  7. Build the host graph, then expand scope to every new source or destination you found.
  8. Correlate with execution and persistence findings (see hunting Windows persistence) and document each edge with its evidence.

Area 08

Lateral Movement

The artifact cheat sheets behind this guide: location by Windows version, what each one proves and the tools to parse it.

Related articles