Windows窗口消息模糊测试:19年后93%的应用仍崩溃

本文重现了2000年NT模糊测试报告,使用相同工具测试现代Windows应用。结果显示93%的应用在畸形窗口消息攻击下仍会崩溃,并发现了一个Windows系统bug。文章深入探讨了窗口消息机制的安全影响和测试方法。

Windows窗口消息模糊测试:19年后93%的应用仍崩溃

快速了解Windows

显示GUI的Windows应用程序由事件驱动:鼠标移动、按钮点击、按键等。事件驱动应用程序在收到事件通知之前不会执行任何操作。一旦收到事件,应用程序会根据事件采取行动,然后等待更多事件。

窗口消息是Windows中的事件通知方法。每个窗口消息都有一个与特定事件关联的数字代码。每个消息都有一个或多个参数(按惯例称为lParam和wParam),用于指定事件的更多详细信息。这些详细信息包括鼠标移动的坐标、按下的键或在窗口中绘制的文本。这些消息可以由程序本身、操作系统或其他程序发送。它们可以随时以任何顺序到达,并且必须由接收应用程序处理。

安全影响

在Windows Vista之前,低权限进程可以向高权限进程发送消息。使用正确的消息组合,可以在高权限进程中获得代码执行。这些"粉碎攻击"自Vista以来已通过UIPI和将系统服务隔离在单独会话中得到很大缓解。

错误处理窗口消息不太可能对现代Windows系统产生安全影响,原因有二:首先,窗口消息无法通过网络发送;其次,在以您已经拥有的相同权限级别崩溃或获得代码执行没有用处。

在某些领域,相同权限的代码执行可能会违反实际的安全边界。一些应用程序结合各种安全原语来创建操作系统中本机不存在的 artificial 权限级别。主要例子是浏览器的渲染器沙箱。浏览器供应商很清楚这些问题并采取措施加以缓解。另一个例子是防病毒产品。

测试方法

我们使用原始NT模糊测试报告中描述的相同核心模糊测试代码和方法来模糊测试集中的所有应用程序。具体来说,在SendMessage和PostMessage两种模式下,模糊测试器使用种子42进行三次50万条消息的迭代,以及使用种子1,337进行三次50万条消息的迭代。

由于时间限制和希望纯粹专注于窗口消息,省略了使用"随机鼠标和键盘输入"方法的模糊测试。

注意事项

在Windows 10上使用模糊测试器需要进行两个小更改:首先是对64位Windows构建模糊测试器的小改动;第二个更改是使模糊测试器能够通过命令行参数定位特定窗口句柄。

在修改模糊测试器时发现了一个严重缺陷:为随机输入的两个主要源(SendMessage和PostMessage的lParam和wParam参数)选择的值仅限于16位整数。

测试应用程序

NT模糊测试报告测试了33个程序。这次重现只测试了28个,因为每个程序只使用一个版本进行测试。

具体替换情况:

  • CD Player → Windows Media Player
  • Eudora → Windows Mail
  • Command AntiVirus → Avast Free Edition
  • GSView → Photos
  • JavaWorkshop → NetBeans IDE
  • Secure CRT → BitVise SSH
  • Telnet → Putty

结果

数字并不特别令人鼓舞,尽管情况正在改善。在原始NT模糊测试报告中,每个应用程序在模糊测试时都会崩溃或冻结。现在,有两个程序(计算器和Avast防病毒软件)在窗口消息模糊测试器中幸存下来而没有不良影响。

参见表1了解所有模糊测试结果以及使用的软件具体版本。

表1:在Windows 10上复制原始NT模糊测试报告的结果

程序 版本 SendMessage PostMessage
Microsoft Access 1901 crash crash
Adobe Reader DC 2019.010.20098 crash ok
Calculator 10.1812.10048.0 ok ok

Windows中的bug?

一个常见问题似乎困扰着多个不相关的应用程序。一些调试显示负责的消息是WM_DEVICECHANGE。当模糊测试器发送该消息时,它甚至会崩溃最简单的应用程序——官方的Windows API HelloWorld示例。

使用HelloWorld示例,我们很快意识到问题只影响32位应用程序,而不影响64位应用程序。一些快速调试显示崩溃发生在wow64win.dll中,这是32位到64位的兼容层。

结论

窗口消息是Windows程序中一个未被充分重视且经常被忽略的不受信任输入源。即使在第一个开源窗口消息模糊测试器部署19年后,93%的测试应用程序在运行相同的模糊测试器时仍然会冻结或崩溃。

窗口消息模糊测试还有很大的改进空间——最简单的方法可能会使93%的应用程序崩溃。甚至可能存在窗口消息跨越实际安全边界的例子。

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