利用PolyTracker检测aCropalypse漏洞:从文件盲区到数据恢复

本文详细解析如何通过PolyTracker工具检测PNG文件中的aCropalypse漏洞,揭示文件盲区形成原理,并演示通过libpng解析器定位残留图像数据的具体操作步骤与技术实现方案。

如何避免aCropalypse - The Trail of Bits博客

上周,关于CVE-2023-21036(绰号"aCropalypse")的新闻在Twitter和其他媒体上传播开来,我很快意识到我们的工具PolyTracker可以检测到这个底层缺陷。我将解释PolyTracker如何在不具备特定文件格式知识的情况下检测受漏洞影响的文件,哪些文件部分可以通过acropalypse.app进行恢复,以及谷歌和微软如何通过使用我们的工具来捕获这个漏洞。

巧合的是,我和同事Evan Sultanik、Marek Surovič合写了一篇论文,描述了这类漏洞,定义了一种新颖的检测方法,并介绍了我们的实现和工具。该论文将出现在今年IEEE安全与隐私研讨会上的语言理论安全(LangSec)研讨会上。

使用PolyTracker检测漏洞

我们使用PolyTracker来检测图像解析器libpng。(任何解析器都可以,不仅仅是aCropalyptic解析器。)PolyTracker检测告诉我们输入文件的哪些部分被解析器完全忽略,我们称之为盲区。盲区几乎总是文件格式设计缺陷、输入文件畸形和/或解析器错误的指标。正常图像应该几乎没有盲区,但通过libpng解析畸形的aCropalyptic图像会在大盲区中显示裁剪的数据。

如果易受攻击的产品使用了PolyTracker进行检测并测试了输出的盲区,aCropalypse漏洞本可以被发现。

1
2
3
4
5
6
# 使用检测版本的pngtest解析截图
$ ./pngtest.instrumented re3eot.png.png out_re3eot.png.png
# 要求polytracker识别文件中的任何盲区
$ polytracker cavities polytracker.tdag
Re3eot.png,697120,1044358
# 发现从偏移量697120开始的盲区(大小约300KiB),它被忽略并包含可检索的裁剪图像数据

理解aCropalypse

根据这条推文,可以从裁剪或编辑的截图中恢复原始图像的部分内容。简而言之,当使用谷歌Pixel内置截图编辑工具Markup裁剪或调整图像大小时,它会覆盖原始图像,但只覆盖到新图像结束的偏移量。该偏移量之后原始图像的任何数据都保留在文件中。David Buchanan设计了一种算法来恢复文件中仍保留的原始图像数据;您可以在他的博客上阅读更多详细信息。

最近,Chris Blume发现了Windows截图工具的类似漏洞。我们在此描述的Markup工具方法可以用于Windows截图工具生成的图像。

PolyTracker有一个我们在几年前引入的功能,称为盲区检测。我们将盲区定义为输入字节集,其数据流从不影响导致输出的控制流或输出本身。或者,用外行的话说,未使用的文件数据可以更改为任何内容而不影响输出。根据定义,aCropalypse图像的裁剪区域是盲区,因此PolyTracker应该能够检测到它们!

跟踪输入字节和检测真实世界输入(如PNG图像或PDF文档)的盲区的一个挑战是污染爆炸。PNG文件格式包含压缩的图像数据块。压缩特别容易导致污染爆炸,因为输入字节以多种方式组合产生输出字节。PolyTracker独特的污染结构表示允许我们跟踪2^31个独特的污染标签,这对于分析图像数据zlib解压缩期间传播的污染是必要的。

处理时aCropalyptic文件会有盲区

要理解为什么aCropalypse漏洞会产生盲区,我们需要将我们对漏洞的了解与盲区的描述结合起来。当使用PNG解析器解析PNG文件时,解析器将解释头部数据并根据PNG规范使用块。特别是,它将在类型为IEND的块处结束,即使该块不在文件的实际末尾。

我们使用PolyTracker来检测一个工具(来自libpng项目的pngtest),该工具读取PNG文件并将其再次写入磁盘。这将产生一个额外的输出文件,称为polytracker.tdag,它捕获来自运行时跟踪的数据流。使用该文件和PolyTracker的盲区检测功能,我们可以枚举不影响结果图像的输入字节。请记住,这些是输入文件的字节,既不影响任何控制流,也不(可能与其他数据混合)出现在输出文件中。对于给定的解析器,它们在解释格式时没有实际意义。

演示!

使用PolyTracker检测的pngtest应用程序,我们再次加载、解析并将下图存储到磁盘。在此处理过程中,我们通过PNG和zlib处理跟踪所有输入字节,直到它们以某种形式到达输出文件。

我们使用包含PolyTracker检测的pngtest应用程序的Docker镜像。

1
2
3
$ docker run -ti --rm -v $(pwd):/workdir acropalypse
$ cd /workdir
$ /polytracker/acropalypse/libpng-1.6.39/pngtest.instrumented re3eot.png.png out_re3eot.png.png

re3eot.png图像的大小为1044358字节,而out_re3eot.png为697,182字节。尽管这表明大小显著减少,但此时我们无法确定原因;例如,可能是不同压缩设置的结果。

接下来,让我们从这个过程中找到盲区:

1
2
3
4
5
$ polytracker cavities polytracker.tdag

100%|███████████████████| 1048576/1048576 [00:01<00:00, 684922.43it/s]
re3eot.png,697120,1044358
out_re3eot.png,37,697182

我们感兴趣的输出是: re3eot.png,697120,1044358

这告诉我们,从偏移量697,120到文件末尾的数据在生成输出图像时被忽略。我们找到了一个盲区!额外的347,238字节未使用数据可能来自原始图像——这是aCropalypse漏洞的迹象。让我们使用acropalypse.app网页看看是否可以恢复它。

这表明该文件实际上是由易受攻击的应用程序生成的。此时,我们知道图像末尾包含来自原始图像的数据,因为这是漏洞的核心。我们还知道该数据的确切位置和范围(根据盲区的起始偏移量和大小)。为了确认数据实际上是盲区,让我们手动裁剪原始图像并重新进行pngtest操作,以确保结果文件实际上相等。首先,让我们只复制不是盲区的部分——用于生成输出图像的数据。

1
$ dd if=re3eot.png of=manually_cropped_re3eot.png count=1 bs=697120

接下来,让我们再次运行pngtest应用程序:

1
$ /polytracker/acropalypse/libpng-1.6.39/pngtest.instrumented manually_cropped_re3eot.png out_manually_cropped_re3eot.png

如果我们的假设——只有前697,120字节用于生成输出图像——是正确的,我们应该有两个相同的输出文件,尽管从manually_cropped_re3eot.png输入文件中删除了347,238字节。

1
2
3
$ sha1sum out_manually_cropped_re3eot.png out_re3eot.png
8f4a0417da4c68754d2f85e059ee2ad87c02318f  out_manually_cropped_re3eot.png
8f4a0417da4c68754d2f85e059ee2ad87c02318f  out_re3eot.png

成功!为了确保手动裁剪的文件仍然不受漏洞影响,让我们使用网页尝试重建文件中的其他图像数据。此尝试未成功,因为我们已经删除了原始图像内容。(是的,我已经检查了裁剪截图的盲区😁)。

为了更好地理解为什么盲区从特定偏移量开始,我们需要检查原始图像的结构。

PolyFile来救援

PolyTracker有一个姊妹工具:PolyFile,一个纯Python的libmagic清洁室实现,具有来自Kaitai结构的检测解析和交互式十六进制查看器。我们将使用PolyFile生成文件结构的HTML渲染的能力来理解为什么文件处理在文件结束之前结束。

首先,我们使用以下命令生成表示文件格式的HTML文件:

1
$ polyfile --html re3eot.html re3eot.png

当我们在浏览器中打开re3eot.html文件时,我们将看到文件的初始表示。

通过重复展开左侧的文件结构,我们最终到达最后一个块。

如上图所示,在解释PNG格式时,最后一个块的类型为IEND。该块之后是来自原始文件的剩余数据。注意多余数据从偏移量0xaa320开始——即697,120,与识别的盲区偏移量完全相同。如果您一直滚动到最后,您会发现一个额外的IEND结构(来自原始图像),但这不被解释为PNG文件的有效部分。

不止于此

几乎不了解PNG文件格式,我们能够使用PolyTracker检测现有的PNG处理应用程序,不仅检测具有盲区的文件,还检测它们的精确位置和范围。

PolyTracker可以检测文件中任何位置的盲区,而不仅仅是在末尾。尽管我们分析了PNG文件,但PolyTracker不限于特定格式。我们之前使用MμPDF分析了PDF到PostScript的转换。相同的技术适用于任何执行加载/存储或反序列化/序列化操作的应用程序。为了进一步增加我们对格式和漏洞影响的理解,我们使用PolyFile检查文件结构。

这些只是我们工具的几个用例,还有很多其他用例!我们鼓励您自己尝试我们的PolyTracker和PolyFile工具,看看它们如何帮助您识别意外处理并防止应用程序中出现类似aCropalypse的漏洞。

致谢

这项研究部分由国防高级研究计划局(DARPA)SafeDocs计划支持,作为Galois的子承包商,合同号为HR0011-19-C-0073。所表达的观点、意见和发现是作者的观点、意见和发现,不应解释为代表国防部或美国政府的官方观点或政策。

非常感谢Evan Sultanik、Marek Surovič、Michael Brown、Trent Brunson、Filipe Casal、Peter Goodman、Kelly Kaoudis、Lisa Overall、Stefan Nagy、Bill Harris、Nichole Schimanski、Mark Tullsen、Walt Woods、Peter Wyatt、Ange Albertini和Sergey Bratus对方法和工具的宝贵反馈。感谢Ange Albertini建议使用"angles morts"(法语中的"盲区")来命名这个概念,以及Will Tan分享受漏洞影响的文件。特别感谢PolyTracker的原始创建者Carson Harmon,他的想法和讨论孕育了这项研究,以及Evan Sultanik帮助撰写这篇博客文章。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计