如果您没有听说过这段代码在 Safari 中运行时会在 x64 位 Windows 7 上导致 BSoD 崩溃
<iframe height='18082563'></iframe>
所以很自然地,问题是它究竟是如何发生的,为什么 18082563 而不是“1808256 4”?
最佳答案
这是对它的解释。
该错误是由于 NineGrid 请求通过代表 UX 主题 DLL 发送的 GdiDrawStream 发送的,该 DLL 处理从 XP 及更高版本开始的 Windows 主题。
Webkit 浏览器(以及 IE8,但似乎不是 IE9)尝试使用操作系统的 native 外观在页面上呈现 HTML 元素。在这种情况下,在 drawControl 函数中(参见 http://www.opensource.apple.com/source/WebCore/WebCore-658.28/rendering/RenderThemeWin.cpp),调用 DrawThemeBackground,它处理操作系统控件的皮肤。
发送一个96(0x60)字节的缓冲区(GdiDrawStream的参数2和3是大小和缓冲区地址,参数1是HDC)。
Draw Steam 缓冲区以一个魔法值开始,后面是一系列由 32 字节市场标识的命令。这是在 Safari 中查看时使用特殊 iframe 发送的流:
44727753 = 'DrwS' = DrawStream 魔法
命令缓冲区:
#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 崩溃。
这意味着任何客户端,无论是本地的还是远程的,对控件进行换肤(即:几乎所有控件——甚至是 Flash PDF 上的按钮)都可能导致 NineGrid转换命中此错误。它根本不是特定于 WebKit 的。
关于windows - 为什么此 iframe 标记会导致 x64 Windows 上的 Safari 崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8591770/