Fuzzing In The Year 2000
Artem Dinaburg
March 28, 2019
这是我们努力在现代系统上重现原始模糊测试研究的第二部分。如果您还没有阅读,请先阅读第一部分。这次我们通过在Windows上重现Justin E. Forrester和Barton P. Miller于2000年发表的“使用随机测试对Windows NT应用程序鲁棒性的实证研究”(又称“NT模糊测试报告”)的结果来处理模糊测试。
NT模糊测试报告测试了Windows NT和Windows 2000早期发布版上的33个应用程序,以检查它们对畸形窗口消息以及随机生成的鼠标和键盘事件的敏感性。由于Miller博士发布了模糊测试器代码,我们使用与原作者完全相同的工具来在现代Windows应用程序中查找错误。
结果几乎相同:19年前,100%的测试应用程序在使用畸形窗口消息进行模糊测试时崩溃或冻结。今天,93%的测试应用程序在面对相同的模糊测试器时崩溃或冻结。未崩溃的应用程序中包括我们的老朋友Calculator(图1)。我们还在Windows中发现了一个错误(但不是安全问题)。
图1: bruised but not beaten. 最近开源的Windows Calculator是两款测试应用程序之一,在面对2000年的窗口消息模糊测试器后没有冻结或崩溃。模糊测试后Calculator被调整大小以展示模糊测试会话的痕迹。
Windows快速介绍
那么什么是窗口消息,为什么它们会使程序崩溃?
显示GUI的Windows应用程序由事件驱动:鼠标移动、按钮点击、按键等。事件驱动的应用程序在收到事件通知之前不会执行任何操作。一旦收到事件,应用程序会根据事件采取行动,然后等待更多事件。如果这听起来很熟悉,那是因为这种架构在node.js等平台中正在复兴。
窗口消息是Windows中的事件通知方法。每个窗口消息都有一个与特定事件关联的数字代码。每个消息都有一个或多个参数,通常称为lParam和wParam,用于指定事件的更多细节。例如,这些细节包括鼠标移动的坐标、按下的键或在窗口中绘制的文本。这些消息可以由程序本身、操作系统或其他程序发送。它们可以在任何时间和任何顺序到达,并且必须由接收应用程序处理。
安全影响
在Windows Vista之前,低权限进程可以向高权限进程发送消息。使用正确的消息组合,可以在高权限进程中获得代码执行。这些“shatter攻击”自Vista以来通过UIPI和将系统服务隔离在单独会话中已得到很大缓解。
错误处理窗口消息不太可能对现代Windows系统产生安全影响,原因有两个。首先,窗口消息不能通过网络发送。其次,在您已经拥有的相同权限级别下崩溃或获得代码执行没有用处。NT模糊测试报告的作者可能已经意识到这一点。他们没有提出安全声明,但正确指出窗口消息处理期间的崩溃意味着缺乏严格的测试。
在某些领域,相同权限的代码执行可能会违反实际的安全边界。一些应用程序结合各种安全原语来创建操作系统本身不存在的 artificial 权限级别。主要的例子是浏览器的渲染器沙箱。浏览器供应商很清楚这些问题,并采取措施来缓解它们。另一个例子是防病毒产品。它们的控制面板以普通用户权限运行,但受到产品其他部分的保护和防篡改。
测试方法
我们使用原始NT模糊测试报告中描述的相同核心模糊测试代码和方法来模糊测试我们测试集中的所有应用程序。具体来说,在SendMessage和PostMessage两种模式下,模糊测试器使用种子42进行三次500,000条消息的迭代,以及使用种子1,337进行三次500,000条消息的迭代。我们在执行每种方法的一次迭代后看到了结果。
由于时间限制和希望纯粹专注于窗口消息,省略了使用“随机鼠标和键盘输入”方法的模糊测试。我们鼓励您也复制这些结果。
注意事项
在Windows 10上使用模糊测试器需要进行两个小更改。第一个是在64位Windows上构建模糊测试器的小更改。第二个更改是使模糊测试器能够通过命令行参数 targeting 特定窗口句柄。模糊测试特定句柄是模糊测试通用Windows平台(UWP)应用程序的快速解决方案。窗口消息模糊测试器面向模糊测试属于特定进程的窗口,但UWP应用程序都通过同一进程显示其UI(图2)。这意味着模糊测试器无法 targeting UWP应用程序的主窗口。
图2:UWP应用程序窗口都属于同一进程(ApplicationFrameHost.exe)。为了模糊测试这些应用程序,原始NT模糊测试器被修改为允许模糊测试用户指定的窗口句柄。
在修改模糊测试器时,发现了一个严重缺陷:为两个主要随机输入源选择的lParam和wParam参数值(SendMessage和PostMessage的参数)仅限于16位整数。这两个参数在32位Windows上是32位,在64位Windows上是64位。问题出现在Fuzz.cpp中,其中设置了lParam和wParam值:
|
|
rand()函数返回范围在[0, 216]内的数字,大大限制了测试值的集合。在评估期间故意保留了这个错误,以确保结果与原始工作准确可比。
测试应用程序
NT模糊测试报告测试了33个程序。这次重现只测试了28个,因为每个程序只使用一个版本进行测试。自2000年以来,Windows软件生态系统发生了巨大变化,但也存在惊人的保守性。Microsoft Office套件包含与原始测试相同的程序。Netscape Communicator演变为现在的Firefox。Adobe Acrobat更名为Adobe Reader,但仍然很强大。甚至Winamp在2018年发布了新版本,允许与原始NT模糊测试报告进行公平比较。然而,一些遗留软件已经随着上个千年而消失。以下列出更改及其原因:
- CD Player ⇨ Windows Media Player:Windows Media Player已包含CD Player功能。
- Eudora ⇨ Windows Mail:Qualcomm现在制造基带,而不是电子邮件客户端。由于Eudora不再存在,测试了默认的Windows电子邮件客户端。
- Command AntiVirus ⇨ Avast Free Edition:Command产品不再可用。它被最受欢迎的第三方防病毒供应商Avast取代。
- GSView ⇨ Photos:GSView应用程序不再维护。它被默认的Windows照片查看器Photos取代。
- JavaWorkshop ⇨ NetBeans IDE:JavaWorkshop IDE不再维护。NetBeans似乎是一个很好的免费替代品,符合测试精神。
- Secure CRT ⇨ BitVise SSH:Secure CRT仍然存在,但需要很长的网络表单才能下载试用版。BitVise SSH提供了快速下载。
- Telnet ⇨ Putty:telnet应用程序仍然存在于Windows上,但现在它是一个控制台应用程序。为了模糊测试GUI应用程序,我们用Putty(一个流行的Windows开源终端模拟器)替换了telnet。
- Freecell和Solitaire从Windows应用商店中的Microsoft Solitaire Collection应用程序运行。
具体应用程序版本出现在结果表中。所有模糊测试都是在64位Windows 10 Pro版本1809(OS Build 17763.253)上完成的。
结果
如NT模糊测试报告中所述,结果不应被视为安全漏洞,而是软件鲁棒性和质量的衡量标准。
“最后,我们的结果形成了一个定量起点,从中可以判断软件鲁棒性的相对改进。”
来自Justin E. Forrester和Barton P. Miller的“使用随机测试对Windows NT应用程序鲁棒性的实证研究”
数字并不特别令人鼓舞,尽管情况正在改善。在原始NT模糊测试报告中,每个应用程序在模糊测试时要么崩溃要么冻结。现在,两个程序Calculator和Avast Antivirus在窗口消息模糊测试器中幸存下来,没有不良影响。我们赞扬Avast和Windows Calculator团队考虑了错误的窗口消息。Calculator团队因开源Calculator并向大家展示如何构建高质量的UWP应用程序而获得额外赞誉。参见表1了解我们所有的模糊测试结果以及使用的软件具体版本。
表1:在Windows 10上复制原始NT模糊测试报告的结果。19年后,很少有应用程序正确处理畸形窗口消息。
程序 | 版本 | SendMessage | PostMessage |
---|---|---|---|
Microsoft Access | 1901 | crash | crash |
Adobe Reader DC | 2019.010.20098 | crash | ok |
Calculator | 10.1812.10048.0 | ok | ok |
Windows Media Player | 12.0.17763.292 | crash | crash |
Visual Studio Code | 1.30.2 | crash | ok |
Avast Free | 19.2.2364 | ok | ok |
Windows Mail | 16005.11231.20182.0 | crash | crash |
Excel | 1901 | crash | ok |
Adobe FrameMaker | 15.0.2.503 | crash | crash |
Freecell | 4.3.2112.0 | crash | crash |
GhostScript | 9.26 | crash | ok |
Photos | 2019.18114.17710.0 | crash | crash |
GNU Emacs | 26.1 | crash | crash |
IE Edge | 44.17763.1.0 | crash | crash |
NetBeans | 10 | crash | crash |
Firefox | 64.0.2 | crash | crash |
Notepad | 1809 | crash | ok |
Paint | 1809 | crash | crash |
Paint Shop Pro 2019 | 21.1 | crash | crash |
Powerpoint | 1901 | crash | ok |
Bitvise SSH | 8.23 | crash | crash |
Solitaire | 4.3.2112.0 | crash | crash |
Putty | 0.70 | freeze | freeze |
VS Community 2017 | 15.9.5 | crash | crash |
WinAmp 5.8 | 5.8 Build 3660 | crash | ok |
Word | 1901 | crash | ok |
Wordpad | 1809 | crash | crash |
WS_FTP | 12.7.0.1903 | crash | crash |
Windows中的一个错误?
不幸的是,我们的好奇心占了上风,我们不得不做一个例外。一个常见的问题似乎困扰着多个不相关的应用程序。一些调试显示 responsible 消息是WM_DEVICECHANGE。当模糊测试器发送该消息时,它甚至会崩溃最简单的应用程序——官方的Windows API HelloWorld示例(图3)。
图3:32位HelloWorld.exe在面对窗口消息模糊测试器时崩溃。这不应该发生,因为程序非常简单。这意味着问题 somewhere 在Windows中。
使用HelloWorld示例,我们很快意识到问题只影响32位应用程序,而不是64位应用程序。一些快速调试显示崩溃发生在wow64win.dll中,即32到64位兼容层。我对问题的快速(可能错误)分析显示,wow64win.dll!whcbfnINDEVICECHANGE函数会将wParam视为目标程序中DEV_BROADCAST_HANDLE64结构的指针。该函数将该结构转换为DEV_BROADCAST_HANDLE32结构以与32位应用程序兼容。崩溃发生是因为模糊测试器生成的wParam值指向无效内存。
将wParam视为本地指针是一个坏主意,尽管它可能是一个 intentional 设计决策,以确保可移动设备通知与遗留32位Windows应用程序一起工作。无论如何,感觉 wrong 的是,可以在不显式调试的情况下崩溃另一个应用程序。我们向MSRC报告了这个问题,尽管没有跨越安全边界。他们确认该错误不是安全问题。我们希望在未来版本的Windows中看到这个 admittedly obscure 问题的修复。
结论
窗口消息是Windows程序中一个未被充分重视且经常被忽略的不受信任输入源。即使在第一个开源窗口消息模糊测试器部署19年后,93%的测试应用程序在面对完全相同的模糊测试器时仍然冻结或崩溃。一些应用程序优雅地处理这些畸形输入的事实是一个令人鼓舞的迹象:这意味着在某些组织中存在避免这些错误的框架和 institutional 知识。
窗口消息模糊测试还有很大的改进空间——最简单的方法可能使93%的应用程序崩溃。甚至可能有窗口消息跨越实际安全边界的例子。如果您进一步探索这个领域,我们希望您能分享您的发现。
如果您喜欢这篇文章,请分享: Twitter LinkedIn GitHub Mastodon Hacker News
页面内容
A Quick Introduction to Windows
Security Implications
Testing Methodology
Caveats
Tested Applications
Results
A Bug in Windows?
Conclusion
最近帖子
We built the security layer MCP always needed
Exploiting zero days in abandoned hardware
Inside EthCC[8]: Becoming a smart contract auditor
Detecting code copying at scale with Vendetect
Building secure messaging is hard: A nuanced take on the Bitchat security debate
© 2025 Trail of Bits.
Generated with Hugo and Mainroad theme.