6

如果您没有听说过这段代码在 Safari 中运行时会在 x64 位 Windows 7 上导致 BSoD 崩溃

<iframe height='18082563'></iframe>

所以很自然的问题是它到底是如何发生的,为什么 18082563 而不是说 "1808256 4 " ?

4

2 回答 2

8

这是对它的解释。

http://pastebin.com/XTWnLF3p

该错误是由于代表 UX 主题 DLL 发送的 NineGrid 请求通过 GdiDrawStream 发送的,该 DLL 处理从 XP 及更高版本开始的 Windows 主题。

Webkit 浏览器(与 IE8 一起——但似乎不是 IE9)尝试使用操作系统的本机皮肤在页面上呈现 HTML 元素。在这种情况下,在 drawControl 函数(参见http://www.opensource.apple.com/source/WebCore/WebCore-658.28/rendering/RenderThemeWin.cpp)中,会调用 DrawThemeBackground 来处理 OS 控件的蒙皮。

发送了一个 96 (0x60) 字节的缓冲区(GdiDrawStream 的参数 2 和 3 是大小和缓冲区地址,参数 1 是 HDC)。

绘制 Steam 缓冲区以一个魔法值开始,然后是一系列由 32 字节市场标识的命令。以下是在 Safari 中查看时使用特殊 iframe 发送的流:

44727753 = 'DrwS' = DrawStream Magic

命令缓冲区:

#0: 00000000 <SET TARGET>
    3b01017a // Destination DC (hdc) *** Must match HDC in GdiDrawStream argument 1 ***
    // Destination Clip (ERECTL):
    0000011b // Left
    00000011 // Top
    0000012c // Right
    0089f580 // Bottom               *** Multiply by 2, and you get the "magic" value used in the iframe PoC ***
#1: 00000001 <SET SOURCE>
    058506a3 // Source Surface (pso)  *** Dumped the surface from kernel mode, got a 13x5 32BPP bitmap which is the Luna/Aero scrollbar slider control ***
#2: 00000009 <NINEGRID>
// Destination Clip (ERECTL):          *** Should match the Destination Clip of the Target
    0000011b // Left
    00000011 // Top
    0000012c // Right
    0089f580 // Bottom
// Source Clip (ERECTL):                 *** Should be within the bounds of the surface (which is 13x5 in this case)
    00000000 // Left
    00000000 // Top
    0000000e // Right
    00000001 // Bottom
// NINEGRID_BITMAP_INFO             *** Documented in RDP docs. Should fit within the surface and destination.
    00000001 // Flags (DSDNG_STRETCH)
    0000000a // Left Width
    00000003 // Right Width
    00000000 // Top Height
    00000000 // Bottom Height
    00000000 // Transparent

这是原始转储:

0: kd> dds @r8 l18
00000000`003be664  44727753
00000000`003be668  00000000
00000000`003be66c  2b0108d5   // HDC, this will change from dump to dump
00000000`003be670  0000011b
00000000`003be674  00000011
00000000`003be678  0000012c
00000000`003be67c  0089f580
00000000`003be680  00000001
00000000`003be684  018503c2   // Bitmap Surface, this will change from dump to dump
00000000`003be688  00000009
00000000`003be68c  0000011b
00000000`003be690  00000011
00000000`003be694  0000012c
00000000`003be698  0089f580
00000000`003be69c  00000000
00000000`003be6a0  00000000
00000000`003be6a4  0000000e
00000000`003be6a8  00000001
00000000`003be6ac  00000001
00000000`003be6b0  0000000a
00000000`003be6b4  00000003
00000000`003be6b8  00000000
00000000`003be6bc  00000000
00000000`003be6c0  00000000

您实际上看到的是一个具有特别有趣高度的 iframe,当滚动条被绘制和主题化时,NineGrid 转换中的数学错误会导致越界写入。这个 PoC 可以在 IE 8 中工作,但是 IE 8 有一个众所周知的 CSS 错误,它有一个最大像素限制(大约 1342177),这就是它不会立即显现的原因。

其他高度是可利用的,有些可能足够小,以至于即使 IE 8 也能达到 NineGrid 高度角的情况。

IE9 似乎根本没有使用 UxTheme 对控件进行主题化,并且它的滚动条行为与 IE 8 不同,因此即使不再存在像素限制,PoC 也不起作用。Firefox 未经测试。

不仅 IFrame 易受攻击。使用相同高度的 HTML 进行测试也会导致 Safari 崩溃。

What this means is that any client, local or remote, that does skinning of the controls (i.e.: almost all of them -- even a button on a flash PDF) could result in a NineGrid transform that hits this bug. It's not at all specific to WebKit.

于 2011-12-23T05:10:21.187 回答
1

As a note, MS recently released MS12-008 which fixes this.

于 2012-02-17T16:24:58.447 回答