BypassUAC


BypassUAC

本篇主要介紹如何以ICMLuaUtil方式BypassUAC,主要內容如下:

  • 過掉UAC提示框的方法總結
  • UACME項目
  • 什么類型的COM interface可以利用?
  • 如何快速找到系統中的所有可利用的COM組件?
  • 定位ICMLuaUtil的虛函數表vftable
  • 如何調用ICMLuaUtil.ShellExec執行命令?
    • C++ version
    • CSharp version
      • 兩個注意點
  • DLL形式
    • C++ dll導出函數方式
    • C# dll導出函數方式
      • 一個坑
  • 值得研究的C2推薦

過掉UAC提示框的方法總結

這里主要說的是dll的形式,通過上面的實操,可以發現有兩種方法:

  • 基於白名單程序繞過UAC
  • 偽裝進程PEB繞過UAC
  • 無文件技術

偽裝進程的方式其實也可以算做借助了白名單,但是沒有直接調用白名單進程,所以單獨列出來了。

基於白名單程序繞過UAC

有些系統程序是直接獲取管理員權限,而不會觸發UAC彈框,這類程序稱為白名單程序,例如:slui.exewusa.exetaskmgr.exemsra.exeeudcedit.exeeventvwr.exeCompMgmtLauncher.exerundll32.exeexplorer.exe等等。

常見的利用方式有:

  • DLL注入(RDI技術),一般注入到常駐內存的可信進程,如:explorer
  • DLL劫持,常和注冊表配合使用達到劫持目的

偽裝進程PEB繞過UAC

上面在利用COM接口的ShellExec執行命令的時候,因為執行該操作的進程身份是不可信的,所以會觸發UAC彈窗。為了能夠迷惑系統,通過修改PEB結構,讓系統誤認為這是一個可信進程,偽裝的可信進程可以是calc.exerundll32.exeexplorer.exe等。

利用火絨劍查看進程信息,可以看到已經識別為可信進程了:

關於PEB的結構,可以參照這里

無文件技術

“無文件攻擊”是一種攻擊策略,其出發點就是避免將惡意文件放在磁盤上,以逃避安全檢測。無文件四種攻擊形式:

  1. 惡意文檔

    比如:在word中加入惡意的宏代碼實現命令執行,又或者郵件中。

  2. 惡意腳本

    常用的腳本引擎:powershell.exe,cscript.exe,cmd.exe 和 mshta.exe,同樣不生成惡意二進制文件。

  3. 惡意本地程序交互

    例如:rundll32.exewmi等,詳細參考這里

  4. 惡意內存代碼

    直接生成純shellcode,通過其他方式加載到內存執行。

UACME項目

項目地址:https://github.com/hfiref0x/UACME

項目總結了50多種繞過UAC的方式,並且列出具備auto-elevate能力的UAC白名單程序或接口。

利用方式主要可以分為兩大類:

  1. 各類UAC白名單程序的DLL劫持(Dll Hijack
  2. 各類提升權限的COM接口利用(Elevated COM interface

項目的主程序為Akagi,其中包含了所有的method,使用vs2019本地編譯后可以使用akagi32 41或者akagi64 41啟動程序,41這個指的是README中描述的方法索引,運行后可以直接得到管理員權限的cmd窗口。

項目的Source目錄存儲的是所有子項目的源碼,其中Source/Shared存放的是被所有子項目共同引用的一些函數,本篇主要利用AkagiYuubari這兩個Project來探究一下如何利用COM接口提升權限。

什么類型的COM interface可以利用?

以項目中索引為41的方法為例:

Author: Oddvar Moe
Type: Elevated COM interface
Method: ICMLuaUtil
Target(s): Attacker defined
Component(s): Attacker defined
Implementation: ucmCMLuaUtilShellExecMethod
Works from: Windows 7 (7600)
Fixed in: unfixed 🙈
How: -

該方法的目標接口是ICMLuaUtil,對應Akagi項目中具體實現函數為ucmCMLuaUtilShellExecMethod,在項目中的methods/api0cradle.c文件中可以找到該方法的定義:

觀察發現這里利用的是CMSTPLUA組件的ICMLuaUtil接口。

我的測試系統Windows 10 (1909),使用OleViewDotNet工具可以查看系統中的COM接口屬性信息,注意需要以管理員權限運行。

打開CLSIDs窗口搜索cmstplua,可以快速定位該組件:

右鍵查看CMSTPLUA組件的Elevation屬性:

這里的EnabledAuto Approval值都是True表示這個組件可以用來繞過UAC認證,這是第一點。

第二點是目標接口ICMLuaUtil需要有一個可以執行命令的地方,通過在CISIDs窗口鼠標懸浮在ICMLuaUtil上,可以看到該接口對應的二進制文件為cmlua.dll

虛函數偏移為cmlua.dll+0x6360,通過IDA打開該系統文件(c:\windows\system32\cmlua.dll),跳到虛函數表的位置,可以看到ICMLuaUtil接口的虛函數表:

摘出來看接口函數如下:

01 QueryInterface(_GUID const &,void * *)
02 AddRef(void)
03 Release(void)
04 SetRasCredentials(ushort const *,ushort const *,ushort const *,int)
05 SetRasEntryProperties(ushort const *,ushort const *,ushort * *,ulong)
06 DeleteRasEntry(ushort const *,ushort const *)
07 LaunchInfSection(ushort const *,ushort const *,ushort const *,int)
08 LaunchInfSectionEx(ushort const *,ushort const *,ulong)
09 CreateLayerDirectory(ushort const *)
10 ShellExec(ushort const *,ushort const *,ushort const *,ulong,ulong)
11 SetRegistryStringValue(int,ushort const *,ushort const *,ushort const *)
12 DeleteRegistryStringValue(int,ushort const *,ushort const *)
13 DeleteRegKeysWithoutSubKeys(int,ushort const *,int)
14 DeleteRegTree(int,ushort const *)
15 ExitWindowsFunc(void)
16 AllowAccessToTheWorld(ushort const *)
17 CreateFileAndClose(ushort const *,ulong,ulong,ulong,ulong)
18 DeleteHiddenCmProfileFiles(ushort const *)
19 CallCustomActionDll(ushort const *,ushort const *,ushort const *,ushort const *,ulong *)
20 RunCustomActionExe(ushort const *,ushort const *,ushort * *)
21 SetRasSubEntryProperties(ushort const *,ushort const *,ulong,ushort * *,ulong)
22 DeleteRasSubEntry(ushort const *,ushort const *,ulong)
23 SetCustomAuthData(ushort const *,ushort const *,ushort const *,ulong)

其中第10個函數ShellExecIDA中看到該函數調用了ShellExecuteEx這個Windows API實現了命令執行:

通過對ICMLuaUtil接口的分析,可以看出可以用來BypassUAC執行命令的COM組件需要有兩個特點:

  1. elevation屬性啟用,且開啟Auto Approval
  2. COM組件中的接口存在可以命令執行的地方,例如ICMLuaUtilShellExec

如何快速找到系統中的所有可利用的COM組件?

除了通過上面的方式在OleView中手動去找,還可以通過UACMe項目提供的Yuubari工具快速查看系統UAC設定信息以及所有可以利用的程序和COM組件,使用方法如下:

使用VS2019加載Yuubari,生成后會得到二進制文件UacInfo64.exe,運行后在同目錄生成一個log文件記錄所有輸出結果:

從這里面可以找到所有的Autoelevated COM objects,包括CMSTPLUA組件的信息:

定位ICMLuaUtil的虛函數表vftable

通過分析UACMe中的ucmCMLuaUtilShellExecMethod實現可以知道想要利用COM接口,需要知道這幾個東西:

  • 標識COM組件的GUID,即CLSID
  • 標識interfaceGUID,即IID
  • 該接口的虛函數表,主要用來找到ShellExec的函數偏移

前兩個可以很容易找到,虛函數表可以通過OleView提示的虛函數表位置偏移找到,這里再說一種通用的方法,完全利用IDA

第一步,用IDA打開cmlua.dll
第二步,在左側函數列表中搜索destructor或者constructor,雙擊后跳轉后,上下找找可以看到調用vftable的地方:

雙擊跳轉到變量定義位置,就可以找到虛函數表!

參考:Get interface definition of undocumented COM objects

如何調用ICMLuaUtil.ShellExec執行命令?

c++ version

代碼是從UACMe中摘出來的,放在了github上。

代碼地址:BypassUAC

如果直接把ucmCMLuaUtilShellExecMethod這個函數直接摘出來,會發現還是會彈UAC的窗:

vs2019中可以對Akagi項目調試,項目屬性中設置命令參數為41

直接在函數ucmCMLuaUtilShellExecMethod的地方下斷:

通過分析函數調用鏈,發現ucmMain在調用對應方法之前先調用了supMasquradeProcess這個函數。

該函數負責進行PEB的偽裝,將自己的進程信息偽裝成為c:\windows\explorer.exe這個系統的可信進程,這樣才能繞過UAC認證窗口,所以在使用COM組件提權之前需要先偽裝一下進程才可以:

這種方式,因為修改的是自己的進程信息,並不是修改其他進程,所以一般殺軟、AV是不會攔的。

CSharp version

代碼摘自Moriarty2016p0wnedShell

代碼地址:BypassUAC_csharp

兩個注意點

C#版本的代碼中需要注意ICMLuaUtil接口的定義,其繼承自IUnKnown,該接口定義函數如下:

IUnknown::AddRef
IUnknown::QueryInterface
IUnknown::QueryInterface

所以在定義ICMLuaUtil的時候,有以下兩點需要注意:

  1. 指明繼承自IUnKnown接口;
  2. 繼承的函數不需要加上,C#會自動添加;

關於C#接口的知識,可以從這里了解更多。

DLL 形式

如何使用?

dll可以使用系統可信進程rundll32.exe進行加載,這樣也不需要調用MarquradePEB

C++ dll導出函數的方式

代碼地址:BypassUAC_Dll

導出的函數為BypassUAC,導出方式直接新建一個def文件,格式參考這里,內容如下:

LIBRARY	BypassUAC
EXPORTS
	BypassUAC

生成之后通過CFF Explorer查看導出表:

利用rundll32.exe .\BypassUAC_Dll.dll,BypassUAC命令測試后,bypass成功!

C# 導出dll函數的方式

代碼地址:BypassUAC_Dll_csharp

C#導出dll函數的方式有兩種:

  1. 使用DllExport這個NuGet
  2. 通過IL反編譯的方式

DllExport

默認C#導入其他庫函數,可以使用[DllImport],但是不支持[DllExport],通過NuGet包管理器安裝DllExport這個包可以實現這個功能。

vs中可以對指定項目安裝這個包:

安裝之后,直接使用[DllExport]導出BypassUAC函數即可:

重新生成dll文件,在CFF中查看,已經導出成功:

IL 反編譯

如果了解Java的,java文件首先編譯成class,然后交給JVM去解釋成機器碼。.net為了跨平台,這里類似,同樣有一個中間語言的文件,但不是class了,而是IL

通過修改IL文件,也可以導出dll函數。

首先去除[DllExport]后將dll代碼編譯,編譯后的dll文件是看不到Export Directory的。

然后ildasmdll文件反編譯成il文件,命令如下:

ildasm BypassUAC_Dll_csharp.dll /out=BypassUAC_Dll_csharp.il

打開生成的BypassUAC_Dll_csharp.il文件,找到需要導出的目標函數BypassUAC,在函數開頭處添加如下代碼:

.export [1]

保存后,需要使用ilasm再把il編譯成dll文件,這里遇到一個坑,如果按照如下命令進行編譯:

ilasm BypassUAC_Dll_csharp.il /dll /out=BypassUAC_Dll_csharp_exp.dll

發現使用rundll32.exe .\BypassUAC_Dll_csharp_exp.dll,BypassUAC運行后沒有任何反應。

BypassUAC函數開頭處添加一個MessageBox彈窗,再次運行彈框之后,附加到windbg調試,讓程序再次跑起來,運行結束后在windbg中可以看到:

進程加載的cmlua.dll文件並不是system32目錄,而是SysWOW64的,SysWOW64放的是32位系統文件,程序為什么去加載的是32位的,使用CFF看一下生成的dll文件類型:

問題的根源就是這里,利用IL轉之前的dll64位的,轉之后變成了32位的,解決方法很簡單,使用ilasm的時候添加一個/X64參數就可以了:

ilasm BypassUAC_Dll_csharp.il /dll /X64 /out=BypassUAC_Dll_csharp_exp.dll

這樣就可以成功的BypassUAC了。

值得研究的C2推薦

  • Python

    • Empire,官方已經不維護了不推薦用,但是值得研究借鑒
    • Pupy,很適合玩Python的研究
    • SILENTTRINITY,利用的.net DLR方式實現,動態加載不落地
    • PoshC2
  • .NET

其他參考


免責聲明!

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



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