作者:Mitja Kolsek,0patch团队
有一点介绍:上周我们都可以看到一个熟悉的“这是一个没有 - 不是没有”的舞蹈,这次是零日活动和福昕软件。简而言之,ZDI向史蒂文·Seeley和Ariele Caltabiano 发现的Reader和PhantomPDF产品中两个安全问题报告给Foxit 。Foxit表示,他们不会解决这些问题,因为他们的剥削需要用户禁用安全模式,从而允许不安全的JavaScript代码执行。然后,ZDI转而发布 概念证明细节,导致福昕决定解决这些问题无论如何。最后, Foxit表示,他们将“ 在PhantomPDF / Reader代码中增加一名警卫,当打开PDF文档包含这些强大的(因此可能不安全)的JavaScript功能时,软件将检查该文档是否由可验证的/值得信赖的人员进行数字签名实体,即使“安全阅读模式”被关闭,只有经过认证的文档才能运行这些强大的JS功能。 “ 他们还宣布了”
本周(ETA Aug 25th)发布Reader / PhantomPDF 8.3.2修补程序更新,同时防止滥用强大(潜在的不安全)JavaScript功能 - 这将使Foxit软件与Adobe的功能相当。“
我们在0patch像下一个人一样挑战,虽然我们通常是修补内存损坏错误(最关键的远程可利用的外露是这样的),我们很高兴地证明,内存中的微代码可以同样如此用于修复逻辑错误 - 至少暂时的,直到正式的修补程序被应用为止,
所以我们设置了一个CVE-2017-10952的微批处理程序,允许PDF文档中的脚本使用saveAs使用任意选择的文件扩展名将其自身保存到用户计算机上任意选择的位置。例如,包含其中某个脚本的<html>块的PDF文档可以简单地将其自身保存为用户的StartUp文件夹中的HTA文件(本地可执行HTML文件),如下所示:
this.saveAs(“/ c / Users /” + identity.loginName +“/AppData/Roaming/Microsoft/Windows/STARTM~1/Programs/Startup/si.hta”);
因此,当用户下次登录Windows时,此HTA文件将被执行。
复制问题
重现问题很简单:我们下载并安装了最新版本的Foxit Reader(8.3.1.21155),并将上述代码放入样本PDF文件中,以获得POC。
使用默认/推荐配置在Foxit Reader中打开POC导致安全阅读模式警告。按“确定”即可禁用安全阅读模式并执行代码。确实,在StartUp文件夹中创建了si.hta。分析 找到实现JavaScript函数的代码通常不是微不足道的,特别是如果POC的结果不是崩溃的话。但是,在这种情况下,saveAs函数会将文件写入磁盘,以便在调用其中一个写入Windows API的功能时被拦截。虽然ZDI文章提到了WriteFile函数,但在其上放置一个断点导致了太多的命中。所以我们去了CreateFile
。
然而,CreateFile也经常使用一些BMP文件,因为某些原因Foxit Reader似乎正在加载。通过简单地检查文件路径的两个字母,并且如果匹配所述BMP文件路径,则不会中断断点:条件是:
bp kernel32!CreateFileW“j poi(poi(esp + 4)+6)!= 0x00730055” ;'gc'“
宾果!第一个中断发生在我们的saveAs调用中,由我们的HTA路径确认传递给CreateFile。调用堆栈尾部看起来像这样:
0030eba8 01703c5e kernel32!CreateFileW
0030ebdc 016f7d4f FOXITREADER + 0x823c5e
0030ebfc 011c5a22 FOXITREADER + 0x817d4f
0030efac 010bd155 FOXITREADER + 0x2e5a22
0030f068 0238ad23 FOXITREADER + 0x1dd155
0030f230 02377492 FOXITREADER + 0x14aad23
0030f2e4 012f17c7 FOXITREADER + 0x1497492
0030f31c 0217568e FOXITREADER + 0x4117c7
IDA的时间。由于FOXITREADER.EXE是一个54MB的野兽,它需要IDA一段时间才能整理出来。之后,查看调用堆栈中的函数显示包含地址FOXITREADER + 0x14aad23的函数保存大部分的saveAs实现。存在对所有saveAs参数的引用(cPath,cConvID,cFS,bCopy和bPromptToOverwrite),并且可以看到 bPromptToOverwrite值,其中,如果属实,称PathFileExistsW并设置我们叫一个局部变量allowed_to_save_file为0;如果用户拒绝覆盖。
下图显示了allowed_to_save_file设置为0的位置,并且进一步检查了allowed_to_save_file的位置,如果为0,则会绕过一堆代码。旁路代码包括执行向CreateFile调用进行的绿色块。
补丁
对于我们来说,为了解决这个问题,我们很难做到正是Foxit要做的事情(只允许正确签名的文档使用诸如saveAs之类的危险功能),因为深入挖掘文档签名数据的方法很容易带我们几天 所以我们决定以一种仍然允许 saveAs的方式简化修复,但不是以RCE风格的危险方式。
我们注意到(和测试),与Adobe的产品不同,Foxit Reader的 saveAs功能似乎不支持文档转换。因此,允许文档使用除“ .pdf ”之外的任何其他扩展名保存自己是没有意义的。所以我们的逻辑是检查传递给 saveAs的文件名,并且只允许具有“ .pdf ”扩展名的文件继续,同时静默地阻止所有其他扩展。
有了这个修补逻辑,我们已经知道如何在上面显示的函数中获取文件路径,所以我们只需要一种方法来破坏不允许扩展的文件创建,而不会引起任何不必要的副作用。bPromptToOverwrite逻辑
的实现非常方便,因为我们看到当用户不允许覆盖时,执行只是绕过一个代码块,否则会导致CreateFile,这肯定没有不必要的副作用。 所以我们做了一个类似的事情:我们决定在绿色块的开头注入补丁代码,然后执行以下操作:
1)获取最后一个“。”的地址。在cPath_string(如果有)。
2)如果没有点,跳出块
3)用“.pdf”做一个不区分大小写的_wcsicmp
4)如果我们没有匹配,跳出块
5)否则继续
IDA真的有助于识别的实现_wcsrchr和_wcsicmp内FOXITREADER.EXE我们,所以我们并没有实现它们的补丁。
此外,我们决定确定任何尝试将一些其他文件扩展名的文件保存为漏洞尝试,从而导致“漏洞尝试被阻止”弹出窗口。
这是从这出来的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
; target: Foxit Reader 8.3.1.21155 MODULE_PATH "C:\Program Files (x86)\Foxit Software\Foxit Reader\FoxitReader.exe" PATCH_ID 275 PATCH_FORMAT_VER 2 VULN_ID 2891 PLATFORM win32 patchlet_start PATCHLET_ID 1 PATCHLET_TYPE 2 PIT FoxitReader.exe!0x5CA2A1,FoxitReader.exe!0x5C9A22,FoxitReader.exe!0x14AAD23 PATCHLET_OFFSET 0x14AACF2 N_ORIGINALBYTES 5 code_start mov edx, dword [ebp-1A0h] push '.' push edx call PIT_0x5CA2A1 ; (_wcsrchr) find the last dot in cPath add esp, 8 ; restore esp test eax, eax ; was a dot found? jz Abort ; no dot found, we don't allow that call GetLocalPdfString ; a trick to get the address of a local ; string on stack dw __utf16__(".pdf"),0 GetLocalPdfString: ; at this point, the address of string ; ".pdf" is on the stack push eax ; eax points to the found dot in cPath call PIT_0x5C9A22 ; (_wcsicmp) compare the two strings, ; case insensitive add esp, 8 ; restore esp test eax, eax ; do strings match? jz Continue ; they do match, we allow saveAs to continue Abort: call PIT_ExploitBlocked ; show the "Exploit Blocked" popup jmp PIT_0x14AAD23 ; jmp out of the block, sabotaging saveAs Continue: code_end patchlet_end |
结束语
我们制作了这个微型显示器,显示了如何修补逻辑漏洞,并展示了创建微批量所需的工作量。我们花了6个工作时间安装易受攻击的Foxit Reader来安装一个工作的微处理器。记住,大部分时间都用于分析漏洞和读者代码,并决定一个很好的补丁方式。原始产品开发人员已经知道产品内部,并将跳过大部分此过程。
我们相信,通过福昕对产品的深入了解,以及我们对微量捕获的了解,高质量的微量捕捉可以在不到一小时的时间内完成。使用我们的分销系统,它将在一个小时内在每个人的计算机上,并自动应用。即使是那时使用Foxit Reader的用户,也不会注意到任何事情 - 读者会立即从“易受攻击”到“固定”,同时滚动某些文档的页面。这就是我们相信大多数软件漏洞应该(并且可能)被修复。
如果您已经安装了0patch代理(免费!),此微型计算机已经在您的计算机上,并且在启动易受攻击的Foxit Reader时会自动应用。您可以使用此POC玩它。玩得开心,写一些微调,如果您是一个软件供应商,有意为您的产品配备自我微调功能,请通过support@0patch.com与我们联系。
原文地址:https://0patch.blogspot.hk/2017/08/0patching-foxit-readers-saveas-0day-cve.html
翻译:腹黑
您必须[登录] 才能发表留言!