UAC 實現原理及繞過方法


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.dllstring,可以直接在這個網站看,用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

可以知道這個dlluac直接相關了。
下面在 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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM