原文链接
几周前Saif El-Sherei
和我在SensePost
的博客上发表了一篇关于DDE
和在无需宏的情况下在MSWord
中执行命令行的文章。这篇博客得到了比我预期多得多的关注。现在DDE
已经被用在钓鱼邮件和恶意软件传播活动中,同时也被合法的红队采用。随着使用DDE
进行的攻击的快速增长,对其的检测也开始加强,大多数杀毒引擎已经内建对DDE
的基本检测。大多数这类检测基于Yara
规则,通过在.docx
和.doc
文档中查找DDE
或DDEAUTO
字段实现。这让我开始思考是否能在文档外混淆DDE
。目前已经有一两种这类尝试出现,威胁者已经改变DDE
字符串的样式,并且将其分解到多行中,如这篇文章描述: Macroless DOC malware that avoids detection with Yara rule
在这篇博客中,我将分享我在混淆和绕过检测方面的尝试。希望这可以同时帮助攻击者和防御者。
在深入探究混淆DDE
和DDEAUTO
字段代码的方法之前,我决定先关注混淆载荷。这样做的原因是双重的。首先,载荷是一段简单的字符串,而不是一段保留的字段代码,这意味着混淆不太可能打破其功能性。再者,我们在载荷混淆上有更多的空间,尝试去隐藏3
个字符(DDE)
比混淆255
个字符有挑战性多了。
看着我们正在处理的字段代码,它感觉就像一个能发现一些更多混淆的好地方。对“list field codes word”
的快速搜索指引我们到了这篇微软的支持文章 ,这篇文章包含一系列受支持的字段代码,这对于我们是有帮助的。在花了一些时间浏览这些不同的字段后,其中一个因其可能有帮助而引起了我的注意。这就是QUOTE
字段,它有被描述为“Quote字段插入指定的文本到一个文档” 的功能。这听起来让我们感到鼓舞,因为我们正在查找能操作载荷字符串的方法,而QUOTE
字段允许操作一个字符串并且将其插入到一个文档。
作为一个旁注,记住这个字段代码可以被嵌入word
是重要的,下面提供了一个使用QUETO
字段的例子:
这里我们嵌入了字段代码,QUOTE
字段包含内部的IF
字段代码的结果,它反过来包含DATE
或格式化的时间,基于一个公式(=)
。
QUOTE
字段可以被用来提供一个字符原始值,它会自动转换这个值到对应的字符(很不幸我没有在发现关于这个的引用)。作为一个例子,如果我们想要去找出65
这个值对应的字符,我们可以在Word
里面使用下面的字段:{ QUOTE 65 }
这最终会展示A
而不是65
,这正是我们在寻找的。我们现在可以将载荷表示为整数并且在DDE
执行前让word
将它们自动转换为字符。让这些起作用的整个系列的字段代码将会是:
这会有效地转换为:
现在你可以发挥你的想象,并知道我们将会用相应的载荷替换AAAA
和GGGG
。为了让这变得更简单,我写了一个快速的Python
脚本来简单地将一个给定的字符串转化为相应的QUOTE
字段。
为了弹出powershell
,我们现在可以使用下面的字段代码:
需要指出的一件事是DDEAUTO
会在文档打开时自动更新,正如它的名字所示。然而,并不是所有字段都会自动更新,除非我们在文档打开时点击“更新链接”。为了做到这点(或许有比我更好的方式),我们需要去将我们的链接标记为“脏的”或将文档设置为自动更新链接。
一旦你创建了你的.docx
文档,你可以用压缩软件打开这个文件,而且你需要修改document.xml
。为了标记链接为肮的并且要求更新,需要在每个<w:fldChar>
开始的地方增加
保存document.xml
并且更新这个压缩文件。现在你打开.docx
,所有链接将会被自动更新。你也会接收到更为干净的“你是否想要自动更新”对话框。
最大的问题是,除了使用QUOTE
外,我们达到了任何目的吗?看起来是的。这个简单启动powershell
的样本(我认为word打开powershell是恶意软件的一个指标)在VirusTotal
上只有1/59
的检出率。
通常你能够简单地将.docx
文件存储为.doc
并得到相同的代码执行。不幸的是,在这里你使用这种方法会在尝试打开.doc
文件的时候收到“错误!没有指定的应用程序”,这是因为嵌入的字段代码并不能正确地自动更新。可能有一种强制更新所有字段代码的方法,但是我的Word
知识有限,所以并不能找到一个这样的方法。
下一个挑战是尝试去从现有检测中隐藏,这包括YARA
规则和对DDE
链接的抽取。
大多数我见过的YARA
规则尝试检测.docx
文档(我关注.docx
是因为它容易被修改)中instrText
元素里面的DDE
和DDEAUTO
其中之一或两者。其中最早的一条YARA
规则是被Nvsi Labs
发布的并且包含以下正则:
这在第一批恶意文档中工作得很好,但是随后就被分解为多行的变种所绕过。我(在多行的样本出现前)发现了另一个关于这个正则的问题,并将其报告给了Didier Stevens
。当查看Office Open XML
文件格式规范时,你会发现fldchar
字段是“复合字段”类型,并且可以有一个额外属性。增加这个可选属性后既绕过了上面的YARA
规则,也允许我们去使用DDE
而不是DDEAUTO
。这个属性叫做dirty
,这个值如果被设置为布尔值的true
,就会强制一次更新,正如在格式文档里描述的“特别的,这个值被一个应用程序标记以指明它的当前结果已经不再正确”那样。
这是和我上面在QUOTE
字段里面使用以强制更新值的同一个属性。为了将其加入文档,简单地和之前那样并且手动修改.docx
即可。
正则马上就失效了,因为它不能匹配到这个可选属性。我向Didier
提交了下列更新,这可以同时匹配到有可选属性的情况和XML
可以包含任意空格的事实。
decalage2
的python-oletools
工具是一个我之前从未尝试过的相当有趣的项目。它在从所有DDE
“攻击”的变种抽取DDE
载荷方面工作得非常好。如果我们使用它来抽取我们的QUOTE
版本,抽取出的DDE
链接是清晰的,而且我们仍然可以知道DDE
是存在的。
这需要稍微多一点的工作,但是你可以很容易地解码这些QUOTE
值到可被执行的字符串。我们该如何绕过它呢?
回到Office Open XML
文件格式规范(我喜爱规范),我们得知存在另一个我们可以使用来引用字段代码的元素。从上面使用到现在的是都是fldchar
的“Complex Field”
字段,然而,还有一个“简单字段”的版本叫做:fldSimple
。fldSimple
元素并没有与fldchar
相同的<w:instrText>
子元素,它事实上将字段作为一个属性包含;w:instr="FIELD CODE"
。
来自规范文档的例子如下:
这很容易被改成能让`DDE起作用的版本,而且我们简单将载荷嵌入如下:
这给了我们能自动执行的DDE
,并且绕过了Oletools
:
我向oletools
推送了更新 去检测嵌入在fldSimple
元素里面的DDE
链接。
这在对抗杀毒引擎 方面也相当不错
记住基于行为的杀毒引擎应当能检测到这种类型的载荷执行,所以这些结果应该被视为“绕过静态扫描。”
当使用fldSimple
时会带来一些副作用。如果你决定去使用DDEAUTO
并且包含w:dirty="true"
,在想要执行DDE
应用程序之前,终端用户会被提示3
次(不清楚为什么会有3
次而不是2
次)。这确实因为这你有3
次他们点击“是”的机会而不是像通常一样。
有趣的是当使用fldSimple
和c:\\windows\\system32\\cmd.exe /k powershell
启动powershell
时,powershell
将会在cmd
窗口内被执行,而不是直接启动powershell
控制台。这和你从已存在的cmd
实例中启动powershell
是一样的行为。并且你会收到一则“不能加载PSReadLine模块”的消息。控制台运行时没有PSReadline”(截图)。也许有人会对深入研究这一点有兴趣?
现在,最后的胜利将会是在文档中完全没有DDE
或DDEAUTO
,这可能吗?这是肯定的,并且有社会工程学方面的附加益处。MSWord
会足够友好去询问用户关闭保护模式以查看文档内容。
为了这一点,我们可以滥用另一个遗留特性(难道这些还不够好吗)。在某个时间点Word
变成了一个任何相关文本的一站式商店,这包括创建网页。Word
在某个点上是一个HTML
的IDE
,HTML
从来不漂亮但是它能工作。大约在这个时间点被引入的事物是frames
和framesets
。Frames
允许你去加载不同的HTML/Text
页面到word
的内部frames
,HTML
会自动解析和转换成Word格式的内容。这个功能似乎在Word 2016
的用户界面中已被移除(也许更早),但是下层的处理例程还在。这意味这你可以创建一个嵌入frames
的文档,Word
将会仍然为你解析。
为了插入一个frameset
,你需要回去编辑一个新的.docx
文档。首先解压,然后打开webSetting.xml
。然后你需要去添加新的XML
元素frameset
:
这应当进入已存在的<w:webSettings>
元素,就在<w:optimizeForBrowser/><w:allowPNG/>
元素前面。接下来你将需要在rId1
中增加对我们文档链接到外部文档的链接。这通过增加一个叫webSettings.xml.rels
的新文件到word/_rels/
来实现。
这个文档的内容应当如下:
当你的目标是包含DDE
的.docx
文档时。在这个例子里我们将要去从位于x.x.x.x
的http
服务器去加载样本.docx
文件。保存所有修改/创建的文件,并且更新.docx
压缩文件。现在你可以发送到修改过的文档到你的目标,他们将会打开它。因为它有mark of the web
标记,所以会在保护模式下打开。然而,因为Word
检测到文件需要外部内容以正确显示,内容会被显示为“链接文档和另外功能已被禁止。要还原这个功能,你必须去编辑该文档”——注意这是来自Word
的默认提示,我们无法控制这个。
只要保护模式被禁止,Word
就会下载包含我们DDE
的外部文档。这将不会收到“mark of the web”
标记并且被Word
解析。触发正常的DDE
消息。这是一个在避免被杀毒软件扫描到的情况下偷渡我们的DDE
载荷的相当有用的方式。
最好的防御似乎就是禁止自动更新链接,这种方法并不依赖杀毒软件。更改你的office
设置去忽略链接和保护自动更新这些的操作步骤被Will Dormannn - @wdormann
创建,并且在这里可以访问到:https://gist.github.com/wdormann/732bb88d9b5dd5a66c9f1e1498f31a1b。
我超想尝试的另一个机制是在Windows 10秋季创意者更新版本
里面引入的Defender Exploit Guard
:https://docs.microsoft.com/en-us/windows/threat-protection/windows-defender-exploit-guard/attack-surface-reduction-exploit-guard 。这个机制的美妙之处在于你可以防止Word/Excel/Powerpoint
派生子进程。这应该不仅能停止这类攻击,而且也能停止DDE
和内嵌的OLE
。需要记住的是,Matt Nelson - @enima0x3
已经证明Outlook
和Access
都没有被注册到ASR。
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)