[翻译]微软 Word OneTableDocumentStream的下溢分析
发表于:
2017-3-9 18:20
3541
[翻译]微软 Word OneTableDocumentStream的下溢分析
今天,Microsoft 发布了 MS16-148 补丁CVE-2016-7290,我发现它解决了一个整数下溢问题。这个下溢会在复制操作期间触发超范围读取,这可能导致以下问题:当一个进程处理特制二进制文档时,基于栈的缓冲区从保护模式下的window.exe进程中溢出。
篇幅太长,没有读完(tl;dr);虽然所有这一切听起来很很戏剧性,但在现实中,概念证明(poc)只触发了一个超出范围的阅读条件,具有潜在的信息披露,然而在这篇博文中,我将进一步详细地说明这个漏洞。
这个漏洞影响着Microsoft Word 2007 Service Pack 3、Microsoft Office 2010 Service Pack 2(32位版本)、Microsoft Office 2010 Service Pack 2(64位版本)和Microsoft Office Compatibility Pack Service Pack 3。所有分析都是在Microsoft Office 2010 Professional WinWord.exe v14.0.4734.1000上执行的,这是当时最新的补丁。
如上图,首先,让我们使用我们最喜欢的二进制编辑器010来看看示例和poc文件的差异。
比较 poc.doc 和 sample.doc
你可能注意到的是,文件只有一个字节的增量修改。 使用Offviz,我们就可以看出哪里包含这个修改。
如上图,分析poc.doc的结构
字节修改出现在OneTableDocumentStream块的数据字段内。 该示例包含字节值0x68,然而是poc使用0xfa触发了下溢。
0x0 触发漏洞
首先,为了进行调试,我启用了页面堆和用户模式堆栈跟踪:
然后运行 poc.doc 文件,这导致以下访问冲突,并超出保护模式:
没有符号看起来不漂亮不是吗?
0x1调查访问的内存
我做的第一件事就是开始检查在腐败时访问的内存。
我们已经可以看到这是一个超过0x19字节大小的堆缓冲区读取,我们试图将另外204个字节复制到一个基于堆栈的地址@edi。有人可能会问,堆栈变量的大小是什么?
事实证明,从许多其他变量和偏移动态可以计算出,该栈变量向上传递了6个帧。不用符号竟然很难追踪到这些。
0x2写存储器
如果我们可以继续从@esi读写,那么我们可以大胆地假设我们可以继续写作。虽然我知道这是一个巨大的假设,但是有能力使用eps喷涂堆或获得堆的精度的话,我们就可以控制在该偏移量的数据。但是我们可以覆盖什么呢? 让我们来看看目标堆栈地址:
使用@ corelanc0d3r的优秀的mona插件,我们可以使用副本的剩余部分转储目标堆栈地址,并且可以看到我们有一个指向.text(wwlib!GetAllocCounters + 0x128118)的指针。如果我现在不得不相对准确地猜测的话,我会说,我们不应该覆盖这个值。
因此,我们可能溢出堆栈缓冲区(但不是太多)。如果我们想要一个返回地址的话,直到目的地址+ 0x1e8,它都不会发生。其中,你好奇的地方可能在这里:
我们不会在调用堆栈中看到它,因为它的公平框架在堆栈中:
下一个问题是,我们将如何模拟继续执行?
@bannedit写了另一个被称为伪造的优秀插件,我们可以用它来在windbg中分配一个块(使用VirtualAlloc),并用标记的数据填充它。然后,我们可以使用这个值来替换@esi,并继续复制操作。
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课