记一次电子表格文件转换中的漏洞挖掘和利用 | Sunbet
登录
  • 欢迎进入Sunbet!
  • 如果您觉得Sunbet对你有帮助,那么赶紧使用Ctrl+D 收藏Sunbet并分享出去吧
  • 您好,这里是Sunbet!

记一次电子表格文件转换中的漏洞挖掘和利用

Sunbet_新闻事件 申博 46次浏览 已收录

记一次电子表格文件转换中的漏洞挖掘和利用

研究人员:

· Brett Buerhaus 布雷特 · 布尔豪斯

· Cody Brocious (Daeken) 科迪 · 布罗斯(戴肯)

· Sam Erb (erbbysam)

· Olivier Beg (Smiegles) 奥利维尔 · 贝格(Smiegles)

介绍

我们在尝试将 LibreOffice 识别为 PDF 渲染服务时,发现了多个代码实现上的漏洞。

本文介绍了我们在 LibreOffice 指纹识别、 LibreOffice 文件检测(以及滥用)和 LibreOffice Python-UNO 桥接方面的工作。

比较流行的 unconv 库无意中滥用了 Python-UNO 桥接器,导致了 CVE-2019-17400漏洞。

我们相信我们的研究并不是终点,我们鼓励其他人也研究这个领域。

LibreOffice

Libreoffice 是 OpenOffice 的一个开源分支,通过在 google 搜索,你可以看到仅在过去几周就有几个关键的 CVE 产生。 LibreOffice 的 Github 项目有超过50万的提交代码,其中包括多年未更新的代码。 由于允许无头文件转换,许多公司依赖于使用 LibreOffice 将通用文档格式导出到 HTML/PDF。

电子表格转换器指纹识别

我们采用以下两种方法对多个网站的文档渲染服务进行了指纹识别。

INFO 功能

大多数电子表格规范,例如 XLSX 或 ODS,都为你提供 INFO 功能,以便为你提供有关打开电子表格的软件或系统的信息。

这里需要注意的一个重要观察结果是,尽管客户端限制了文件扩展名,但我们遇到的许多网站都允许渲染任何支持 LibreOffice 的文件类型。 利用这一点,我们可以测试 XLSX 文件上传。 (更多内容见下文)

 记一次电子表格文件转换中的漏洞挖掘和利用

这是一个有用的标识符,原因如下。 =INFO(“osversion”)函数对于 OpenOffice/LibreOffice 具有硬编码值。 OpenOffice 和旧版本的 Libre 返回了一个 INFO 函数的错误,2015年后它不支持 LibreOffice ,并将显示“,N/A”。 这些细微差别为创建一个 XLSX 文件提供了机会,该文件可用于更好地了解服务器上处理电子表格的内容。

下面是我们最终使用的指纹:

其中 c4单元格为 =INFO(“DIRECTORY”) 

记一次电子表格文件转换中的漏洞挖掘和利用

对 OpenOffice 的检查是由于 Libre 是 OpenOffice 的分支,如果你调用一个 OO/Libre 不支持的 Excel INFO 函数,最终会添加结果 ,N/A。 这是在这个提交中添加的: https://github.com/LibreOffice/core/commit/db6a928a420868b2a80ba11c8d46151d16c13624。 所以不能完全保证,但是她可以帮助你决定是否要尝试一些老版本的 Libre CVE。

同样值得注意的是,最近 Libre 开始将 git 散列作为他们的版本号,因此 INFO(“release”) 将帮助你找到正在使用的软件的确切版本。

除了指纹识别应用程序进行转换之外,它还会告诉你一些其他的事情。 一个有用的例子是 OSVERSION,因为它将告诉你服务器的操作系统(WIN、 LINUX、 SOLARIS) ,这些操作系统可能是有用的侦察数据,可以根据服务器的情况调整攻击。另一个对Excel有用的是DIRECTORY,它告诉你当前的工作目录,根据文件位置给你一个路径提示或Windows用户名。

PDF 元数据

由于大多数应用程序使用 OpenOffice/LibreOffice 将 XLSX/DOCX 导出为 PDF,如果应用程序将转换后的原始PDF返回给你,那么它很可能包含诸如正在使用的LibreOffice版本之类的元数据。下面是 Slack 中的情况。

https://files.slack.com/files-pri/[filehash]/download/asdf.odt_converted.pdf

结果如下:

记一次电子表格文件转换中的漏洞挖掘和利用

一个常见的文件扩展名陷阱

在我们最初的测试中,我们观察到一个网站只会渲染扩展名为.xlsx 的文档。 然后,该网站将使用 LibreOffice 渲染该文件。 然后,我们创建了一个 ODS 文档,并将其重命名为使用 XLSX 扩展。 噗! 它现在返回 ODS 文件的预览。 这是利用  Open/LibreOffice 转换的入口点。

有些应用程序获取你用 XLSX 或 DOCX 扩展上传的文件,并将它们传递到 OpenOffice,而不执行强文件格式验证或安全地配置过滤器。 当转换这些文件时,所使用的转换流是由文件内容而不是扩展名决定的。

LibreOffice/OpenOffice 文件检测

请注意,我们对代码分析没有很高的信心。

当使用 –convert-to 和 –headless 参数通过 soffice 传递文件时,它将通过代码流来确定要传递给它的文件类型。 在我们的研究中,绝大多数都输出到 PDF 中,可以用下面的流程来概括:

· 如果没有指定硬过滤器,会进行文件格式的猜测

· 检查传递文件的文件扩展名

· 它根据文件内容(例如魔术头)检查过滤器

· 它有一个文档格式列表分析系统,并根据复杂程度对它们进行排序。 例如,它将在回到 XML 或 HTML 之前检测它是否是复杂的 XML 格式(如 docbook)

· 如果扩展和过滤器不匹配,它就会回到仅仅依赖过滤器猜测的状态

https://github.com/LibreOffice/core/blob/master/desktop/source/app/dispatchwatcher.cxx,L595

OUString aParam = aDispatchRequest.aPrinterName;
sal_Int32 nFilterIndex = aParam.indexOf( ':' );
bool bGuess = false;
if( nFilterIndex >= 0 ) {
    ...
} else {
    // Guess
    bGuess = true;
    aFilterExt = aParam.copy( 0, nPathIndex );
}

如果在 URI 中未指定筛选器,则启用猜测文件格式流。

Mimilib利用分析

0x00 前言 Mimilib是mimikatz的子工程,编译成功后生成文件mimilib.dll,包含多个导出函数。 目前介绍这个dll用法的资料比较少,于是我将结合自己的测试结果,逐个介绍mimilib.dll导出函数的用法。 0x01 简介 本文将要介绍以下内容: · Mimilib导出函数简介 · 6种功能的具体用法 0x02 Mimilib导出函数简介 对应文件的地址为: https://github.com/gentilkiwi/mimikatz/blob/master/mimilib/mimilib.def 内容如下: EXPORTS
startW = kappfree_startW

SpLsaModeInitialize = kssp_SpLsaModeInitialize

InitializeChangeNotify = kfilt_InitializeChangeNotify
PasswordChangeNotify = kfilt_PasswordChangeNotify

WinDbgExtensionDllInit = kdbg_WinDbgExtensionDllInit
ExtensionApiVersion = kdbg_ExtensionApi

if ( bGuess ) {
    ...
    aFilter = impl_GuessFilter( aOutFile, aDocService );
}
OUString impl_GuessFilter( const OUString& rUrlOut, const OUString& rDocService ) {
    std::shared_ptr pOutFilter = impl_getExportFilterFromUrl( rUrlOut, rDocService );
    ...
}
std::shared_ptr impl_getExportFilterFromUrl( const OUString& rUrl, const OUString& rFactory) {
    try {
        const Reference< XComponentContext > xContext( comphelper::getProcessComponentContext() );
        const Reference< document::XTypeDetection > xTypeDetector( xContext->getServiceManager()->createInstanceWithContext( "com.sun.star.document.TypeDetection", xContext ), UNO_QUERY_THROW );
        const OUString aTypeName( xTypeDetector->queryTypeByURL( rUrl ) );

现在,它依赖于一组基于com.sun.star.document.TypeDetection的可配置过滤器。 这些过滤器用于确定文件类型,可以大致概括为检查文件内容中的魔术头字节或硬编码字符串。 这意味着,如果你使用 word 文档或电子表格并导出到 PDF,它将完全否定 docx 或 xlsx 扩展名,并猜测如果它没有检测到xlsx或docx文件头,文件格式会是什么。

下面是一个 Encapsulated PostScript (EPFS) 的例子:

· 过滤器:https://github.com/LibreOffice/core/blob/master/filter/source/config/fragments/types/eps_Encapsulated_PostScript.xcu

· 检查:https://github.com/LibreOffice/core/blob/master/vcl/source/filter/GraphicFormatDetector.cxx,L322

bool GraphicFormatDetector::checkEPS()
{
    if ((mnFirstLong == 0xC5D0D3C6)
        || (ImplSearchEntry(maFirstBytes.data(), reinterpret_cast("%!PS-Adobe"),
                            10, 10)
            && ImplSearchEntry(&maFirstBytes[15], reinterpret_cast("EPS"), 3, 3)))
    {
        msDetectedFormat = "EPS";
        return true;
    }
    return false;
}

正如你所看到的,你不能只是将“PS-Adobe”放入一个文本文件并进行转换。 它还会检查“EPS”是否跟在PS-Adobe 头之后。 一旦确定了如何对特定文件格式进行文件检测,如果转换允许,就可以开始利用该文件格式。

LibreOffice 支持的文件格式

LibreOffice 支持的文件格式大约有100个。 这里有太多的内容需要介绍,所以我将在这里留下 Wiki 表的链接:

https://en.wikipedia.org/wiki/LibreOffice,Supported_file_formats

你需要单击“Show”链接来展开表。

Excel 中的 Ghost (script)

在支持的文件格式中,我们首先注意到 LibreOffice 支持 EPFS,这意味着 可以利用 PostScript/Ghostscript。 在过去的几年里,在 Ghostscript 已经有了一些有趣的利用,它也是唯一支持的(我们可以识别的) 文件格式,允许一些原始脚本与文件或执行命令交互。

使用 Ghostscript 有效载荷,我们能够实现文件读写。

这个有效载荷的代码可以在这里找到:

· https://gist.github.com/ziot/fb96e97baae59e3539ac3cdacbd09430

感谢 Cody Brocious (daeken) 让 Ghostscript 有效载荷正常工作。

关于 LibreOffice 我们了解到的一件事是,尽管 EPFS 文件是由 LibreOffice 处理的,但并不能保证它会导致 Ghostscript。 这是由于 EPFS 解析的层次系统导致的:

pstoedit、convert (ImageMagick的一部分)和GhostScript (gs或gswin32c)在所有平台上都按这个顺序进行了尝试。这是第一个可以用于渲染预览的组件。

更多信息请点击这里:

· https://github.com/LibreOffice/core/blob/master/filter/source/graphicfilter/ieps/ieps.cxx

但是,EPFS只是将postscript传递给其他应用程序,不能保证系统上有一个二进制文件可以处理传递给它的postscript。在这些情况下,你需要找到一个可以进行漏洞利用的替代路径。

Slack, OLE 对象和文本节

通过 LibreOffice 指纹电子表格文件,我们开始检查其他可能以类似方式使用 LibreOffice 的网站。 我们偶然发现 Slack 正在使用 LibreOffice (我共享文件使用的是Slack…)。 我们的 LFI Ghostscript 有效载荷不能正常工作,所以我们必须找到一个与Libre 不同的漏洞利用链。

下面我们将介绍 OLE 对象 xLinks 和文本节的具体细节,我们使用这些细节来读取本地文件内容和捕获 AWS 凭据。

LFD/SSRF——远程 OLE 对象 xLinking

这类似于 =WEBSERVICE LFD/SSRF 漏洞 (CVE-2018-6871)。 在 LibreOffice 文档中,可以在文档中嵌入 OLE 对象。 这也支持在打开文档时进行更新的远程对象。 尽管 LibreOffice 文档包含一些允许这样做的特性,比如浮动帧(iframe 的转换) ,但是在转换为 PDF 文档时,可能无法正常渲染。

Libreoffice 中的 OLE 对象通过获取远程 URL 的内容并显示帧内的内容来工作。 OLE 对象嵌入到 LibreOffice 文件的 content.xml 中。 默认情况下,这些 x-href 链接在转换时不会更新。 实际上,在 OpenOffice/LibreOffice 中,大多数情况下需要在打开文档后手动启用链接更新。 这就把我们带到了广受欢迎的 Universal Office Converter (unconv) 上,稍后将在博客中详细介绍。

只要启用了 x-href 更新,就可以获取任意内容。 这可以通过创建以下 PoC 来看到:

Poc 步骤

1. 在 LibreOffice 中创建一个新的电子表格;

2. 插入->对象 -> OLE 对象-从文件创建;

3. 勾选“链接到文件”复选框;

4. 输入一个实际文件的 url (如果是404,libre 就会失败);

5. 保存 odt 文件;

6. 用 zip 工具打开 odt 文件,如7zip;

7. 修改 content.xml, 使用 “file:///etc/passwd” 替换url。

· * 查找: `

· * 替换为: `

  · Oasis 文件规范

  · LibreOffice/OpenOffice 文件检测和解析

  · PyUNO 桥和 OpenOffice API 调用的实现

  · 无头版本的 LibreOffice 在转换过程使用的公共代码路径中的任何漏洞都可能影响在线 LibreOffice 的使用

  · https://wiki.openoffice.org/wiki/PyUNO_bridge

  · https://github.com/LibreOffice/core/blob/master/pyuno/

本文翻译自:https://buer.haus/2019/10/18/a-tale-of-exploitation-in-spreadsheet-file-conversions/:


Sunbet|网络安全巴士站声明:该文看法仅代表作者自己,与本平台无关。版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权
转载请注明记一次电子表格文件转换中的漏洞挖掘和利用
喜欢 (0)
[]
分享 (0)