0x00 UAC 工作流程
UAC 是微軟在 Windows Vista 以后版本引入的一種安全機制,
通過 UAC,應用程序和任務可始終在非管理員帳戶的安全上下文中運行,除非管理員特別授予管理員級別的系統訪問權限。UAC 可以阻止未經授權的應用程序自動進行安裝,並防止無意中更改系統設置。
https://msdn.microsoft.com/en-us/library/bb384608.aspx
從圖上可以看到,如果要獲取管理員權限,通過的路徑有以下幾條:
1,進程已經擁有管理權限控制;
2,進程被用戶允許通過管理員權限運行。
0x01 UAC 實現方法(用戶登陸過程)
ACL(Access Control List):Windows 中所有資源都有 ACL ,這個列表決定了擁有何種權限的用戶/進程能夠這個資源。
在開啟了 UAC 之后,如果用戶是標准用戶, Windows 會給用戶分配一個標准 Access Token
.
如果用戶以管理員權限登陸,會生成兩份訪問令牌,一份是完整的管理員訪問令牌(Full Access Token),一份是標准用戶令牌。一般情況下會以標准用戶權限啟動 Explorer.exe 進程。如果用戶同意,則賦予完整管理員權限訪問令牌進行操作。
0x02 UAC 架構
0x03 觸發UAC
UAC需要授權的動作包括:
配置Windows Update
增加或刪除用戶賬戶
改變用戶的賬戶類型
改變UAC設置
安裝ActiveX
安裝或移除程序
安裝設備驅動程序
設置家長控制
將文件移動或復制到Program Files或Windows目錄
查看其他用戶文件夾
via Wiki
0x04 UAC 虛擬化
UAC 虛擬化(Virtualization)也被稱為重定向(Data Redirection)。在權限判定的過程中,如果用戶的權限沒有達到程序所需的權限,UAC 就會重定向該文件夾。例如,如果程序試圖寫入到 C:\Program Files\Contoso\Settings.ini
目錄下,但用戶沒有寫入權限,這個寫操作就會被重定向至 C:\Users\Username\AppData\Local\VirtualStore\Program Files\contoso\settings.ini
.
UAC 虛擬化分為兩個部分,文件虛擬化和注冊表虛擬化。
要注意的是,在以下情況下,虛擬化不可用:
- 64 位程序
- 非交互式程序
- 模擬令牌的進程 (Processes that impersonate)
- 內核模式調用方
- 帶有 requestedExecutionLevel(請求執行等級)的可執行程序
文件虛擬化(File Virtualization)
Luafv.sys
實現的是改變寫入文件位置。
注冊表虛擬化
Ntoskrnl.exe
實現的是改變寫入注冊表位置。
0x05 UAC 逆向分析
先使用 procexp 查看現有進程
然后使用管理員權限運行一個文件以彈出 UAC 提示框,可以看到多出一個進程consent.exe
:
這個進程中有一個 Dll appinfo
,
UAC 主要的實現文件在於 appinfo.dll
這個文件,
先查看一下appinfo.dll
的 string
,可以直接在這個網站看,用rehacker
查看不出,原因未知:
100 Application Information
101 Facilitates the running of interactive applications with additional administrative privileges. If this service is stopped, users will be unable to launch applications with the additional administrative privileges they may require to perform desired user tasks.
200 User Account Control: Behavior of the elevation prompt for administrators in Admin Approval Mode
201 User Account Control: Behavior of the elevation prompt for standard users
202 User Account Control: Detect application installations and prompt for elevation
203 User Account Control: Run all administrators in Admin Approval Mode
204 User Account Control: Virtualize file and registry write failures to per-user locations
205 User Account Control: Only elevate executables that are signed and validated
206 User Account Control: Switch to the secure desktop when prompting for elevation
207 User Account Control: Admin Approval Mode for the Built-in Administrator account
208 User Account Control: Only elevate UIAccess applications that are installed in secure locations
225 User Account Control: Allow UIAccess applications to prompt for elevation without using the secure desktop
251 Prompt for credentials on the secure desktop
252 Prompt for consent on the secure desktop
253 Elevate without prompting
254 Automatically deny elevation requests
255 Prompt for credentials
256 Prompt for consent
257 Prompt for consent for non-Windows binaries
可以知道這個dll
和uac
直接相關了。
下面在 Windows 10 平台下使用 IDA 對其進行逆向分析。
查看一下導出函數,會發現其使用的 RPCRT4 Library 較多。
RPC Functions(Remote Procedure Call),使得一個程序可以調用另一計算機的子程序,順便一提,本地過程調用(LPC,Local Procedure Call)則是在本機進程間進行通訊。
這個 dll
是通過注冊LPC接口進行調用的。
然后上 MSDN 看一看關鍵的庫的作用:
RpcServerInqBindings :Returns a pointer to a pointer to a vector of server binding handles.
RpcServerRegisterIfEx:The RpcServerRegisterIfEx function registers an interface with the RPC run-time library.
進入RpcServerRegisterIfEx
查看一下交叉引用:
進入其中一個(反正都是相近的)查看:
.text:0000000180004140
.text:0000000180004140 MaxCalls = dword ptr -18h
.text:0000000180004140 IfCallback = qword ptr -10h
.text:0000000180004140 BindingVector = qword ptr 8
.text:0000000180004140 arg_8 = qword ptr 10h
.text:0000000180004140
.text:0000000180004140 ; FUNCTION CHUNK AT .text:0000000180007B1C SIZE 000000F4 BYTES
.text:0000000180004140
.text:0000000180004140 mov [rsp+arg_8], rbx
.text:0000000180004145 push rdi
.text:0000000180004146 sub rsp, 30h
.text:000000018000414A xor edi, edi
.text:000000018000414C lea rcx, Protseq ; "ncalrpc"
.text:0000000180004153 xor r8d, r8d ; SecurityDescriptor
.text:0000000180004156 mov [rsp+38h+BindingVector], rdi
.text:000000018000415B lea edx, [rdi+0Ah] ; MaxCalls
.text:000000018000415E call cs:__imp_RpcServerUseProtseqW
.text:0000000180004164 mov ebx, eax
.text:0000000180004166 test eax, eax
.text:0000000180004168 jnz loc_180007B1C
.text:000000018000416E lea rcx, [rsp+38h+BindingVector] ; BindingVector
.text:0000000180004173 call cs:__imp_RpcServerInqBindings
.text:0000000180004179 mov ebx, eax
.text:000000018000417B test eax, eax
.text:000000018000417D jnz loc_180007B1C
.text:0000000180004183 mov [rsp+38h+IfCallback], rdi ; IfCallback
.text:0000000180004188 lea r9d, [rdi+29h] ; Flags
.text:000000018000418C xor r8d, r8d ; MgrEpv
.text:000000018000418F mov [rsp+38h+MaxCalls], 4D2h ; MaxCalls
.text:0000000180004197 xor edx, edx ; MgrTypeUuid
.text:0000000180004199 lea rcx, unk_18000FD00 ; IfSpec
.text:00000001800041A0 call cs:__imp_RpcServerRegisterIfEx
.text:00000001800041A6 mov ebx, eax
.text:00000001800041A8 test eax, eax
.text:00000001800041AA jnz loc_180007B1C
.text:00000001800041B0 lea edi, [rax+1]
.text:00000001800041B3 xor r8d, r8d ; MgrEpv
.text:00000001800041B6 lea rax, ?AiCOMSecurityCallBack@@YAJPEAX0@Z ; AiCOMSecurityCallBack(void *,void *)
.text:00000001800041BD xor edx, edx ; MgrTypeUuid
.text:00000001800041BF mov [rsp+38h+IfCallback], rax ; IfCallback
.text:00000001800041C4 lea r9d, [rbx+69h] ; Flags
.text:00000001800041C8 lea rcx, unk_18000FCA0 ; IfSpec
.text:00000001800041CF mov [rsp+38h+MaxCalls], 4D2h ; MaxCalls
.text:00000001800041D7 call cs:__imp_RpcServerRegisterIfEx
.text:00000001800041DD mov ebx, eax
.text:00000001800041DF test eax, eax
.text:00000001800041E1 jnz loc_180007B1C
.text:00000001800041E7 lea edi, [rax+5]
.text:00000001800041EA xor r8d, r8d ; MgrEpv
.text:00000001800041ED lea rax, ?AiMSISecurityCallBack@@YAJPEAX0@Z ; AiMSISecurityCallBack(void *,void *)
.text:00000001800041F4 xor edx, edx ; MgrTypeUuid
.text:00000001800041F6 mov [rsp+38h+IfCallback], rax ; IfCallback
.text:00000001800041FB lea r9d, [rbx+69h] ; Flags
.text:00000001800041FF lea rcx, unk_18000FC40 ; IfSpec
.text:0000000180004206 mov [rsp+38h+MaxCalls], 4D2h ; MaxCalls
.text:000000018000420E call cs:__imp_RpcServerRegisterIfEx
為了防止眼瞎,看一下有顏色的:
RpcServerRegisterIfEx
具有多個參數,不應該過多關注其本身,這個函數是用來注冊 LPC/RPC 接口的,那么就要找出他到底注冊了什么借口。
說到這里,要先了解一下 Windows 的進程創建。
http://blog.csdn.net/myjisgreat/article/details/53262932,其中AicLaunchAdminProcess
是用以創建管理員進程的。
搜索一下也可以驗證 UAC
中使用到了這個接口。
梳理一下,在觸發 UAC
時,系統會創建一個consent.exe
進程,該進程用以確定是否創建管理員進程(通過白名單和用戶選擇判斷),然后creatprocess
.
請求進程將要請求的進程cmdline和進程路徑通過LPC接口傳遞給appinfo的RAiLuanchAdminProcess函數,該函數首先驗證路徑是否在白名單中,並將結果傳遞給consent.exe進程,該進程驗證被請求的進程簽名以及發起者的權限是否符合要求,然后決定是否彈出UAC框讓用戶進行確認。這個UAC框會創建新的安全桌面,屏蔽之前的界面。同時這個UAC框進程是SYSTEM權限進程,其他普通進程也無法和其進行通信交互。用戶確認之后,會調用CreateProcessAsUser函數以管理員權限啟動請求的進程。
1x00 UAC Bypass
目前公開的方法中,有以下幾種方法繞過 UAC:
1,白名單提權機制;如Wusa.exe Bypass UAC
,infDefault.exe Bypass UAC
,PkgMgr.exe Bypass UAC
等。
2,DLL 劫持;
3,Windows 自身漏洞提權;
4,遠程注入;
5,COM 接口技術。
其余的如通過計划任務、路徑欺騙等方式不算入繞過,因為這是經過用戶確認
1x01 無文件白名單提權機制
sdclt.exe實現無文件繞過UAC
原文:
https://enigma0x3.net/2017/03/17/fileless-uac-bypass-using-sdclt-exe/
sdclt.exe
是 Windows 7 模式下的備份與還原文件,在我的 Windows 10 下位於C:\Windows\WinSxS\amd64_microsoft-windows-safedocs-main_31bf3856ad364e35_10.0.10586.494_none_91de6b09c5f6a4d2
目錄下。
首先使用sigcheck
這個工具對文件是否自動能提權進行查看:
>sigcheck.exe -m sdclt.exe
對這個文件進行反匯編分析:
其中,test eax,eax
是標志位置位。
_wcsicmp
是一個比較函數,如果參數為/KickOffJob
則繼續向下執行:
其中,xor ecx,ecx
是類似於 eax
置零,他將 CPU 狀態重置以繼續執行下面的指令。
下面對sub_140071B08
進行分析:
查看 off_14008F1A0
,該函數作用為Hidden_Window
,即隱藏當前窗口,右鍵重命名一下方便查看。
跳入 140071B63
進行查看,可以知道這是一個提升權限的函數,同樣地右鍵重命名。
loc_140071B63:
mov r9d, 1
lea rdx, aSxshellexecute ; "SxShellExecuteWithElevate"
mov r8d, 56Ah
lea rcx, [rsp+108h+var_E8] ; Load Effective Address
call sub_140056A68 ; Call Procedure
返回之前的函數,命名為Hidden&Elevate
,這時候整體結構比較清晰了,
lea r9, aKickoffjob ; "/KICKOFFJOB"
mov edx, r13d
lea r8, aSystemrootSyst ; "%systemroot%\\system32\\sdclt.exe"
xor ecx, ecx ; Logical Exclusive OR
call Hidden_Elevate ; Call Procedure
mov [rsp+0F0h+var_C0], eax
test eax, eax ; Logical Compare
jns short loc_140002CB5 ; Jump if Not Sign (SF=0)
總結以上的流程如下:
1,啟動sdclt.exe
進程;
2,校驗是否為KICKOFFJOB
參數,若為該參數則啟動%systemroot%\system32\sdclt.exe
;
3,對該進程進行提權。
使用procmon
運行並分析:
然后改注冊表就行(未實現……鍵值不在了)。
這個博主很多方法都類似這個,可以看一看(不過感覺很多的內容嚴格上來說不算 Bypass)……
1x02 DLL 文件注入提權
上邊說的是未使用文件的,下面來看看使用了 DLL 替換的。
第一個是監聽端口的,沒打算折騰這個,具體可以看這里……
第二個是轉發 DLL 文件,類似於上面的方法,可以使用DLL_Hijacker.py
進行更換不再贅述。
參考資料:
http://undoc.airesoft.co.uk/ntdll.dll/RtlQueryElevationFlags.php
(微軟非公開 DLL )
https://en.wikipedia.org/wiki/User_Account_Control
https://www.codeproject.com/Articles/19165/Vista-UAC-The-Definitive-Guide
https://www.wilderssecurity.com/threads/malware-achieves-privilege-escalation-via-windows-uac.376464/
http://pan.baidu.com/s/1slbHD6H
https://technet.microsoft.com/en-us/library/2009.07.uac.aspx
http://paper.seebug.org/127/