A reverse shell is fine, but sometimes you need to actually click around — open the user’s browser to look at internal apps, dig through the desktop for files, see the environment the way the user sees it. That means RDP.
The catch with RDP is that it normally wants the plaintext password. Which means dumping the SAM and getting an NTLM hash should leave you out of luck. Except that thanks to a Microsoft “security feature” called Restricted Admin Mode, you can use the hash directly. This post is about how that works and how to use xfreerdp to do it.
1. Why Pass-the-Hash usually fails on RDP#
Pass-the-Hash works because NTLM authentication is challenge/response — the server proves the client knows the password by exchanging hashes, never the password itself. So in theory, a hash is as good as the password.
For most NTLM-using services that’s true. RDP is different.
A normal RDP session is a Logon Type 10 (RemoteInteractive). The OS has to actually decrypt the user’s protected data: DPAPI master keys, EFS-encrypted files, Chrome cookies, anything that was sealed with a key derived from the plaintext password. NTLM hashes are one-way, so there’s no way to derive that master key from a hash. Logon fails.
Restricted Admin Mode (and later Remote Credential Guard) was added to keep admin credentials from getting cached on potentially compromised servers. The way it does that is by skipping the interactive logon entirely and doing a Type 3 (Network) logon instead — the same kind of logon you get when you mount a file share. No DPAPI unsealing, no plaintext password requirement. Which conveniently means a hash is enough.
Microsoft built it to stop hash theft against jump servers; it ended up being one of the more reliable ways to use a hash for interactive access. Both things can be true at the same time.
2. Restricted Admin Mode#
Before any of this works, the target must have Restricted Admin Mode enabled. If xfreerdp connects, the hash is right, and you still get STATUS_LOGON_FAILURE, this is almost always why.
The setting lives in the registry at:
HKLM\System\CurrentControlSet\Control\Lsa\DisableRestrictedAdmin
0— Restricted Admin enabled. PtH works.1or missing — disabled. Default on older Windows versions; enabled out of the box on more recent ones.
Enabling it remotely#
If you already have a shell with Local Admin (Evil-WinRM, psexec, Cobalt Strike, whatever), you can flip it on:
# Using PowerShell
New-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 0 -PropertyType DWORD -ForceThis is a configuration change on a production host. It persists. If you set it, you have to remember to put it back when you’re done — and “I’ll clean it up later” is how this turns into a finding in the post-engagement debrief.
# Cleanup Command
Remove-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin"3. xfreerdp syntax#
A common first mistake is putting the hash into /p:. That doesn’t work. The flag you want is /pth:.
# Syntax: /p:passwd is NOT used.
# The hash format is usually NTHASH (32 chars).
xfreerdp /v:<target_ip> /u:<username> /pth:<NT_HASH>The actual command I run looks more like this — it tolerates self-signed certs (which you’ll see on every internal machine), enables clipboard, and lets the window resize:
# Example
# User: Administrator
# Hash: aad3b435b51404eeaad3b435b51404ee:7b455e245e1c7f1d2c3a7d305ba65f22
# Note: xfreerdp can take just the NTHASH (2nd part) or LM:NT format.
xfreerdp /v:192.168.1.10 /u:Administrator /pth:7b455e245e1c7f1d2c3a7d305ba65f22 /cert:ignore +clipboard /dynamic-resolutionA note on the flags:
/v:is the target./pth:takes either the bare NT hash or the fullLM:NTstring fromsecretsdump. Both work./cert:ignoreis essential. Without it the connection drops on the self-signed cert prompt./nlais on by default. No need to specify it unless you’re explicitly testing whether NLA is even enforced.
4. RDP through a tunnel#
RDP isn’t usually exposed to the internet, so you’ll be running this through a SOCKS proxy on a jump box.
# 1. Establish the SOCKS proxy via SSH to your jump box
ssh -D 1080 user@bastion-host
# 2. Run xfreerdp through proxychains
# Ensure /etc/proxychains.conf points to socks5 127.0.0.1 1080
proxychains xfreerdp /v:10.0.0.50 /u:Admin /pth:[HASH] /cert:ignoreBe warned: RDP over SOCKS over SSH is sluggish at best. There are some flags that help:
/bpp:16drops the color depth./network:modemtunes the compression for low-bandwidth links.- Disable bitmap caching if you start seeing visual artifacts.
If you’re doing anything serious in the session — running a tool, watching a process — assume every interaction has half a second of latency on top.
5. The Logon Type 3 anomaly#
This is the IOC that gives the whole technique away.
A normal RDP session writes Event ID 4624 with Logon Type 10 (RemoteInteractive). A Restricted Admin RDP session writes Event ID 4624 with Logon Type 3 (Network) — the same logon type you’d see for an SMB share connection.
So from the SOC’s perspective: a Type 3 logon shows up, which by itself is unremarkable. Then explorer.exe and the user-init chain spawn under that session. Network logons don’t normally do that. The pattern is hard to miss if anyone has bothered to write the rule.
Credential Guard#
Worth noting alongside this: if the target has Credential Guard enabled, the NTLM hashes for sessions on that machine are sealed in LSAISO and you generally can’t dump them. But that’s about extraction. If you’ve already got a hash from somewhere else — a legacy box where the same admin reused credentials — you can usually still authenticate to the Credential Guard machine via PtH, provided Restricted Admin is on.
6. Doing it from a Windows attack VM#
If you’re operating off a Windows VM (Commando VM, for example) inside the target network, Mimikatz can inject the hash into your current logon session and launch the regular mstsc.exe:
# In an Administrator Command Prompt running Mimikatz:
mimikatz # sekurlsa::pth /user:Administrator /domain:CORP /ntlm:7b455e245e1c7f1d2c3a7d305ba65f22 /run:"mstsc.exe /restrictedadmin"/restrictedadmin is the flag on mstsc.exe that tells the client to negotiate the Restricted Admin handshake instead of the regular interactive one.
Wrapping up#
PtH against RDP isn’t something I’d treat as a default capability. It needs Restricted Admin on the target, and enabling it yourself means leaving a registry change behind — the kind of thing a configuration-drift report will surface long after the engagement closes out.
Where it earns its place is in the cases a shell can’t cover. Thick-client GUI applications. Industrial dashboards that only render in a real session. The legacy intranet that uses ActiveX controls in IE mode. Anything where you need an actual user-mode desktop and not just code execution.
And keep an eye on what the Type 3 logon does to the host’s event correlation. If the SOC has anything joining 4624 event records to subsequent process creation under the resulting session, this is one of the easier offensive primitives to detect.
UncleSp1d3r out.