---
# System prepended metadata

title: 'Duplicate Paths Attack: Get Elevated Privilege from Forged Identities / 馬聖豪'
tags: [HITCONCMT, HITCON, HITCONCMT2019]

---

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`