Duplicate Paths Attack: Get Elevated Privilege from Forged Identities / 馬聖豪 === Speaker:馬聖豪 UAC 逆向說明。 Blog:https://www.30cm.tw/ (1) UAC Design 提供自動提權的程式設計邏輯 Double Trust Auth (認證環境發起的目錄是否可信任) 組合起來可以成為一個萬用提權內容 # UAC Design 使用者帳戶帳制:使用者權限較低,但執行時想要較高的權限執行的控管服務。 svhhost.exe->consent.exe >> 這隻視窗的 UI 分析人員思維: 1. UAC 的服務為什麼要叫 hosconsent.exe? 2. 如果逆向能確認,那麼意思為何?是否能利用? 3. 進階利用 觀察:svchosts 叫起來的服務,所以一切看起來超正常。 ### 創建Process的程序: - 程式碼要擺哪裡? - 執行緒該怎麼執行 1. Parent Process :CreatPrecess 2. Child Process created * Child process get mapped * with the same privilege as parent * RIP points to `RtlCreateThread` 3. Kernel Created a new Thread RtlUserThread 4. Jump into AddressOfEntry,然後程式叫起來了 但如果是vista版本之後,權限會有不一致,所以執行的Process 由於權限不夠,就會被遮罩起來了。 Kernel 就會 Lock 起來,UAC 會跳出來,然後去進一步做兩層新的驗證,如果RPC請求通過,所以就可以直接通過。 如果請求不通過,則Kernel 就會取消這個請求。 `appinfo.dll` 沒有 Google Search,只能手動逆向。 有部份自己 IDAPro 和 猜出來的。 `a.exe` 沒簽章的應用程式。 created process 常用的內容以及它的好伙伴。 執行起來的時候,由於權限較低,想要執行較高權限的程式,UAC 服務一次只能處理一個請求。所以它會Lock住。 再來會降級跟發起權限相同,然後再進一步去那隻發起的 token,再回到 UAC 高等級服務system,由於 pineline 資訊對接,所以 RPC 又降級一次,所以再重新要做FileMapping,是確保DACL這個服務(跨權請求沒有被改) 正確執行這樣。 兩個驗證關卡: (1) NT 檔案系統的路徑,先取一次,轉成DOS Deivce 的Winows 內的 DOS 傳統路徑。 那麼應該執行時就可以不用每一個子服務都叫起來,一次賦與權限,一次將子程序都給權限。 但,會再做一次路徑檢查是否在可信路徑中(非系統目錄)。 若為系統目錄的話,會再做進一步驗證,像說 system32 或 DEBUG,它有自行定義清單,但如果是系統預設清單,所以清單內的路徑,是不會自動給權限的,但如果是一般執行的內容(可信內容),那麼會自動給權限。 再來會再更進一步檢查,簽章+版本號+路徑驗證,進一步給值 `0x800000u | 0x200000u` 只要拿到這個flag,那麼路徑驗證就過了。 再來,呼叫完之後再RPC執行完,降完權限,賦與權限完,就可以做第二層認證。 ### 第二層認證 取得第一層認證過了,那麼也通過第二層認證。 先讀檔案進來,再驗證資訊清單(XML)有沒有 `autoElevate` 自動提權,如果有,那麼如果程式是 `mmc.exe` 且想提權,拿到flag:`0x1010000u` ,那麼之後 UAC 就不會再跳出來了。 `mmc.exe` >> 大量插件安裝程式 所以代表程式有意願提權,可以通過。 (Sample Code) 程式碼沒被改 + 認證也是微軟 => 驗證通過 就會彈出視窗 ResumeThead(hThread) 使用者也以UI方式給過 所以就會建立一個新的 ChildProcess Kernal 做filemapping + 分發 heap #### Over View [圖] 問題來了… 驗證是 `$p` 系統傳入的路徑,但執行時 pathInput 是由使用者傳入的… 所以如果今天不一致 `$p` 跟 pathInput 不同的話… TenableSecurity 認為程式要同時符合下面條件才能跳過UAC 數位簽章+白名單+But 執行Path不一致 ``` UNC Paths \\Server\Path\Foo.txt DOS Device Paths \\.\UNC\Server\Share\Foo.txt /? path_Normaliz ``` (1) kernel 確認相對路徑後,幫你串路徑 (2) 路徑是否合法 … … … … (6) 無用的路徑或檔名(..\)消毒掉 如果檔名包含空白,那麼它會消毒掉空白。 為什麼會有這樣的邏輯? Windows 10 允許超過 256Bytes,超過就存在另外一個 block。 若你的路徑上有 `\\?\` 那麼我們就不做資料消毒。 ``` c:\Windows\System32\a.exe $p:\??\C:\Windows\System32\a.exe ``` `C:\Windows \System32\a.exe` (中間有空白) 驗證沒空白的,執行有空白的惡意程式。 這樣就可以達成第一層認證了。 -特定系統路徑 再加上auto,就可以過第二層認證了。 -有簽章 -auto_elevte github (Demo) siofra64 工具:`Siofra64 --mode file-scan -f "C:\Windows32\"` 允許動態做感染 `Siofra64 --mode infect --payload-type process --payload-path mspaint` (小畫家) 結果會是一隻 dccw.exe,劫持程式 dxva2.dll 執行後就不會出現 UAC 。 ``` \\\\?\\c:\\windows \\' ``` 是個含有空白的路徑。 沒有 UAC 而且也是最高權限的狀態。 slide: https://speakerdeck.com/aaaddress1 C:\windows c:\ProgramFiles c:\ProgramFiles(x86) CreationFlag 可以要權限 ###### tags: `HITCONCMT2019`,`HITCONCMT`,`HITCON`