为慈善而战:自动化漏洞挖掘在LibOTR中的实践
去年年底,我们利用为DARPA网络大挑战开发的自动化漏洞挖掘技术探索了新应用方向。当其他参赛者正为CGC决赛做准备时,我们开始尝试将漏洞挖掘工具应用于真实的Linux应用程序。
这个故事始于一场赌约:2014年11月4日,Thomas Ptacek(Starfighter)与Matthew Green(约翰霍普金斯大学)打赌,认为安全消息软件常用库libotr在接下来12个月内会出现高危漏洞(如远程代码执行、信息泄露)。Trail of Bits团队决定使用网络大挑战中的自动化漏洞挖掘系统来验证这个赌约。
需要说明的是,这并非正式的安全审计。我们只是想测试自动化漏洞挖掘系统在真实Linux软件上的表现,并可能为慈善事业赢得捐款。
技术背景
我们为网络大挑战构建的自动化漏洞挖掘系统(Cyber Reasoning System, CRS)原本针对DECREE操作系统的二进制代码。虽然DECREE基于Linux,但与标准Linux存在显著差异:没有信号、共享内存、线程、套接字和文件,仅支持7个系统调用。这意味着DECREE与libotr等Linux库既不二进制兼容也不源代码兼容。
经过评估,我们决定将libotr移植到DECREE,而不是为CRS添加完整的Linux支持。移植过程采用通用方法,以便将来测试其他Linux软件。
移植技术方案
libotr移植需要解决两个主要问题:共享库依赖(libotr依赖libgpgerror和libgcrypt)和libc支持。我们使用LLVM一次性解决这两个问题:
- 使用whole-program-llvm将libotr及其所有依赖编译为LLVM位码
- 在位码级别合并所有共享库并进行激进优化
- 通过优化消除未使用的libc调用,减少需要实现的libc数量
- 基于挑战二进制文件中的libc实现,构建适用于DECREE的libc
自动化测试挑战
加密通信应用本身难以自动审计:如果自动化系统能推理密文与明文的关系,加密通信系统就已经被攻破。随机测试(如模糊测试)同样困难,因为接收方会验证每条消息的完整性。
我们选择不修改libotr,而是让CRS模拟中间人(MITM)攻击。由于测试未修改的libotr,CRS无法有效攻击通过消息完整性检查的代码,但仍可攻击消息控制数据、头部以及解密/认证代码中的潜在漏洞。
测试架构
CRS作为中间人位于两个使用libotr通信的应用之间。创建测试应用比移植libotr到DECREE更困难:官方libotr发行版没有示例代码,文档也不完善。
测试受到样本应用使用的libotr功能(如未使用SMP)和我们创建的特殊测试应用的限制。某些漏洞可能只在解密后出现,而加密和认证数据的修改永远不会触发这些漏洞。
测试结果
我们对libotr样本应用运行了48个Xeon CPU持续24小时,未发现任何内存安全违规。这一阴性结果不代表libotr没有漏洞,我们只测试了libotr的子集,且CRS未审计相当部分代码。但未发现明显漏洞是个好迹象。
结论
libotr赌约期限已过,期间未报告任何高危漏洞。我们使用自动化漏洞挖掘工具审计了部分libotr代码,也未发现内存破坏漏洞。在此过程中,我们学会了如何将Linux应用移植到DECREE,并验证了CRS能识别Linux程序中的真实漏洞。
更好的文档、测试和覆盖所有libotr功能的样本应用将简化自动和手动审计。本次实验我们坚持使用未修改的libotr,未来计划修改libotr以支持更轻松的自动化测试。