本文是技术译文,原文地址:
https://labs.nettitude.com/blog/com-and-the-powerthief/
近几年来,组件对象模型(COM)已经有了很大的发展,特别是在用于持久性和横向移动方面。在本篇文章中,我们将会学习它是如何在IE浏览器中进行有限进程迁移以及JavaScript注入。接着,我们会在新PowerShell库Invoke-PowerThIEf中完成对它的组合,并运行。希望通过这篇文章能够帮助大家学习到一些红队的知识。
在今年早些时候,我开始注意到一项关于Junction Folders / CLSID的技术,该技术细节已经在Vault 7文件中泄露。当我开始研究这些应用程序的深度应用时,我了解到组件对象模型(COM)与Internet Explorer交互和自动化的能力。当然,这并不是一个新发现; 许多功能都在CodeProject等网站上有详解。但是,它还没有整理成一个可以帮助红队渗透时利用的库。
因此,这也就有了我今年7月7号在谢菲尔德的关于“COM和PowerThIEf”的分享,具体内容可以参看:
具体分享的内容放在了YOUTUBE上:
快速掌握COM
在我们深入研究之前,如果大家不熟悉COM,那么我强烈推荐以下资源。这些是关于这个主题的一些最近的优秀讲座和博客文章:
- James Forshaw在60秒内推出COM - https://vimeo.com/214856542
- Casey Smith和Matt Nelson的Windows考古学 - https://www.youtube.com/watch?v=3gz1QmiMhss
- Matt Nelson使用Excel应用程序和DCOM进行横向移动 - https://enigma0x3.net/2017/09/11/lateral-movement-using-excel-application-and-dcom/
连接文件夹
我首先在b33f的优秀Patreon视频中看到了上文提到的Junction Folders / CLSID技术。据我所知,这首先被用作持久化方法,因为如果你以CLSID.{<CLSID>}格式命名文件夹, 那么当你跳转到该文件夹时,资源管理器将在注册表中执行查找。CLSID然后运行任意已注册的COM服务器。作为他的DefCon 25 WorkShop的一部分(值得一读,上传在https://github.com/FuzzySecurity/DefCon25)
同时,他发布了一个名为Hook-InProcServer的工具,它使你能够构建用于COM Hijack或JunctionFolders / CLSID技术所需的注册表结构。这些都被用作持久性机制,因此我就开始考虑这能否可以用作进程迁移的手段,至少可以用于explorer.exe。
第一步是找出是否有可能以编程方式跳转到其中一个配置的文件夹 ——很幸运,事实证明它确实可以。为了能够跳转,我们首先需要访问任意运行中的资源管理器实例。Windows通过ShellWindows对象简化了这一过程:
https://msdn.microsoft.com/enus/library/windows/desktop/bb773974(v=vs.85).aspx
在此对象上枚举Item属性列出了Explorer和Internet Explorer的所有当前运行实例。ShellWindows由CLSID“{9BA05972-F6A8-11CF-A442-00A0C90A8F39}”标识; 以下PowerShell演示了如何激活它。
$shellWinGuid = [System.Guid]::Parse("{9BA05972-F6A8-11CF-A442-00A0C90A8F39}")
$typeShwin = [System.Type]::GetTypeFromCLSID($shellWinGuid)
$shwin = [System.Activator]::CreateInstance($typeShwin)
通过索引.Item集合返回的对象将根据它是否是资源管理器和IE实例而产生不同。一个简单的检查方式就是使用FullName,它存在于两者上,并具有应用程序的名称,如下所示。
$fileName = [System.IO.Path]::GetFileNameWithoutExtension($shWin[0].FullName);
if ($fileName.ToLower().Equals("iexplore"))
{
// Do your IE stuff here
}
2010年的这篇文章(https://www.thewindowsclub.com/the-secret-behind-the-windows-7-godmode)不仅包含Vault7技术,还表明可以使用语法连接到CLSID 外壳:: :{ CLSID }。假设我们至少打开了一个IE窗口,我们可以索引ShellWindows.Item对象以获得对该窗口的访问权限(例如,为了获得对第一个IE窗口的访问权限,可以使用$ shWin [0] .Item)。这将为我们提供一个对象,该对象表示IE的实例,并且是一个名为IWebBrowser2的类型。进一步研究这种类型,我们在文档中发现它有一个名为Navigate2的方法。(https://msdn.microsoft.com/en-us/library/aa752134(v=vs.85).aspx)。此方法的MSDN页面上的备注声明已添加它以扩展Navigate方法以“允许shell集成”。
以下代码将激活ShellWindows,假设第一个窗口是IE实例(这是概念证明),然后将尝试通过控制面板的CLSID(可在注册表中找到)导航到控制面板。
$shellWinGuid = [System.Guid]::Parse("{9BA05972-F6A8-11CF-
A442-00A0C90A8F39}")
$typeShwin = [System.Type]::GetTypeFromCLSID($shellWinGuid)
$shwin = [System.Activator]::CreateInstance($typeShwin)
$shWin[0].Navigate2("shell:::{ED7BA470-8E54-465E-825C-99712043E01C}", 2048)
/*
CLSID must be in the format "shell::{CLSID}"
Second param 2048 is BrowserNavConstants value for
navOpenInNewTab:
https://msdn.microsoft.com/en-us/library/dd565688(v=vs.85).aspx
Further ideas on what payloads you may be able to use:
https://bohops.com/2018/06/28/abusing-com-registry-structure-clsid-
localserver32-inprocserver32/
*/
以下动画将展示代码的运行结果:
通过CLSID ID导航到的控制面板:
然后我们可以通过Process Monitor的跟踪看到IE已经查找了CLSID然后导航到它,最终在资源管理器中打开它,其中涉及在InProcServer注册表项中启动DLL。如果我们创建自己的注册表项,那么我们希望有一种方法要求IE(或资源管理器)为我们所有人从另一个进程加载DLL。从实际触发,我们并不能保证每次都从Word.exe发出网络连接,但是在IE的情况下,DLL必须是x64。有许多方法可以配置注册表项来执行脚本,通过查看subTee或bohop的作品都可以获取更多信息。
JavaScript
一旦获得对Internet Explorer窗口的引用,就可以访问该实例的DOM。也就是说,我们可以访问页面和浏览器。例如,您可以查看和编辑HTML,注入JavaScript,导航到其他选项卡以及显示/隐藏窗口。以下代码段演示了如何注入和执行JavaScript:
$shellWinGuid = [System.Guid]::Parse("{9BA05972-F6A8-11CF-
A442-00A0C90A8F39}")
$typeShwin = [System.Type]::GetTypeFromCLSID($shellWinGuid)
$shwin = [System.Activator]::CreateInstance($typeShwin)
$parentwin = $shWin[0].Document.parentWindow
$parentwin.GetType().InvokeMember("eval",
[System.Reflection.BindingFlags]::InvokeMethod, $null, $parentwin,
@("alert('Self XSS, meh \r\n\r\n from '+ document.location.href)"))
此次的不同之处在于我们实际上必须在能够调用它之前在DOM窗口上找到 eval方法。这需要使用.NET的Reflection API来定位和调用该方法。
接下来我们将显示该段代码运行的情况:
一切尽在PowerThIEf库
尽管编程结构和一些技术都有很好的文档记录,但似乎没有一个库可以将它们整合在一起,以便红队在以下情况下使用:
- 目标是使用密码管理器,例如LastPass,其中密钥记录无效。
- 用户登录到应用程序,我们希望能够将其注销,而无需清除所有浏览器历史记录和cookie。
- 目标应用程序位于后台选项卡中,无法等待用户切换选项卡。我们需要从该页面查看或获取HTML。
- 我们希望从目标IP地址查看网站,而无需了解目标。
以上需求,促使了我编写了PowerThIEf库,该库现在位于https://github.com/nettitude/Invoke-PowerThIEf
初始版本中包含的功能如下:
- DumpHtml:从DOM中检索HTML,可以使用一些选择器(但不是jQuery样式)。
- ExecPayload:使用前面的迁移技术在IE中启动有效负载DLL。
- HookLoginForms:通过挂钩登录表单并监视新窗口来窃取凭据。
- InvokeJS:在您选择的窗口中执行JavaScript。
- ListUrls:列出所有当前打开的选项卡/窗口的URL。
- 导航:导航到另一个URL。
- NewBackgroundTab:在后台创建一个新选项卡。
- 显示/隐藏窗口:显示或隐藏浏览窗口。
用法和功能的示例包括:
从页面中提取HTML:
记录用户,以便捕获凭据:
使用联结文件夹触发PoshC2有效负载:
捕获通过LastPass输入的传输中的凭据:
用法
最新的Invoke-PowerThIEf文档可在以下位置找到:
路线图
未来计划进一步的功能,包括
- 屏幕截图:截图所有浏览器窗口。
- CookieThIEf:窃取cookie(会话cookie)。
- 重构DOM事件处理:因为开发包含在Powershell中的Complex C#并不理想。
- 纯C#模块
- 支持.Net 2.0-3.5