作者: 1u0m@WoodSec
本文為作者投稿,Seebug Paper 期待你的分享,凡經采用即有禮品相送!
投稿郵箱:paper@seebug.org

0x00 起因

在一次項目過程中遇到了一個需要通過服務器攻擊pc管理員的情況,在拋開tsclient的傳統攻擊方法下我發現了checkpoint團隊關于rdp客戶端的研究文章,文章描述了rdesktop,FreeRDP以及mstsc的研究結果,由于項目有了其他突破便沒研究,直到前兩天看見有牛人已經實現了,于是乎仔細分析了一下

0x01 分析

在高版本的mstsc和rdp服務里面微軟已經實現了粘貼板的功能,從text到文件都可以以復制粘貼的方法在服務器和PC機之間傳輸。一個文件的傳輸過程有如下流程

  1. 在服務器上,"復制"操作會創建格式為"CF_HDROP"的剪貼板數據
  2. 在客戶端計算機中執行"粘貼"時,將觸發一系列事件
  3. 要求服務器上的rdpclip.exe進程提供剪貼板的內容,并將其轉換為FileGroupDescriptor(Fgd)剪貼板格式
  4. 使用HdropToFgdConverter::AddItemToFgd()函數,將文件的元數據添加到描述符中
  5. 完成后,將Fgd Blob發送到服務器上的RDP服務
  6. 服務器只是將其包裝并將其發送給客戶端
  7. 客戶端將其解包并將其存儲在自己的剪貼板中
  8. "粘貼"事件將發送到當前窗口(例如,explorer.exe)
  9. 處理事件并從剪貼板讀取數據
  10. 通過RDP連接接收文件的內容

使用ClipSpy觀察服務器和PC上的剪貼板變化

當復制一個文件的時候,剪貼板的CF_HDROP是以Unicode編碼儲存的文件的路徑

而此時PC上的剪貼板的FileGroupDescriptorW以Unicode編碼儲存的文件的名稱

在IDA中通過查找幾個剪貼板的API(OpenClipboard,CloseClipboard)定位到一處可疑的函數:CClipBase::OnFormatDataRequest

這里具體的操作就是打開剪貼板,獲取剪貼板數據,如果存在CF_HDROP的格式就進入CHdropToFgdConverter::DoConversion進行處理不然就去CFormatDataPacker::EncodeFormatData里面處理

可以看出DoConversion就是我們要找的文件處理的函數,繼續跟進

DoConversion 只是做了檢查HDrop格式和堆的分配等準備工作,然后進入了CHdropToFgdConverter::DoConversionWorker 跟進DoConversionWorker發現終于開始干正事了

首先是獲取Hdrop里面文件是數量,以及是否是unicode編碼和編碼轉換

然后遍歷Hdrop里面的文件,通過wcsrchr()在路徑里面獲取文件名,最后把文件路徑和文件名一起傳給CHdropToFgdConverter::AddItemToFgd

根據checkpoint的描述,這里將文件逐個通過AddItemToFgd打包成Fgd格式然后發送給PC端,這里應該就是發送文件前最后的文件打包檢查操作了。

在這里面我發現對傳入進來的文件名沒有任何檢查之類的,直接打包

通過傳入的文件全路徑獲取文件的一些基本信息和屬性然后打包

接下來就是發送給RDP服務然后發給PC端,這里不再跟進

回顧上面的關鍵點就是如下幾條

  1. 通過GetClipboardData函數在剪貼板中獲取Hdrop數據
  2. 遍歷Hdrop數據獲取文件路徑信息,并且使用wcsrchr()獲取文件名
  3. 使用文件路徑獲取文件的基本信息和屬性
  4. 將文件名和文件基本信息和屬性打包

0x02 Poc

那我們的攻擊點就在文件名,修改文件名實現跨目錄

文件名是通過wcsrchr(&szFile, '\\')獲取到的,看來微軟忘了他自己的文件API還支持"/"訪問

wcsrchr返回的是一個指針,意味著修改了文件名之后路徑也會變,路徑變化之后后面的CreateFileW函數會出錯返回失敗,這里我想到的Hook大法好,當然可能還有其它辦法

A.定義兩個文件路徑

B.首先我Hook GetClipboardData函數,在正常的Hdrop數據里面加入我們的文件

C.然后Hook DragQueryFileW函數,在枚舉文件路徑的時候修改成跨目錄的路徑

D.最后Hook GetFileAttributesWCreateFileW函數,在打開文件的時候不要用我們跨目錄的路徑,而使用之前的正常路徑

總結流程如下

  1. 在獲取剪貼板的Hdrop數據的時候插入我們的正常路徑
  2. 在枚舉文件路徑的時候返回跨目錄的路徑
  3. 在執行GetFileAttributesWCreateFileW的時候給他正常路徑

運行poc之后我們再來看看ClipSpy的變化

服務器上和之前沒有變化(GetClipboardData是在PC端粘貼的時候觸發的)

PC端以及有了兩條數據,其中包括我們的跨目錄

演示視頻

0x03 最后

  1. 由于mstsc可以多窗口復制粘貼,所以這種方法在多窗口一樣生效
  2. 在測試的時候發現,跨目錄的同時還可以創建不存在的目錄
  3. 由于建立了RDP連接,兩邊的系統就會同步剪貼板,可以實現通過服務器監控PC的剪貼板
  4. 感謝checkpoint的文章

Paper 本文由 Seebug Paper 發布,如需轉載請注明來源。本文地址:http://www.bjnorthway.com/1074/