在进行软件安全评估时,如果您可以访问已编译应用程序(例如 C++)的源代码,您是否会使用任何自动化技术或手动对已编译版本进行任何分析?模糊测试是唯一适用于这种情况的技术,还是查看二进制文件还有其他潜在优势?
代码分析:二进制与源代码
这取决于情况——应用程序的类型、部署模型,尤其是您的威胁模型等。
例如,某些编译器可以大幅更改一些微妙的代码,引入细微的缺陷 - 例如绕过某些检查,这些检查确实出现在代码中(满足您的代码审查)但不在二进制文件中(未通过实际测试)。
还有某些代码级别的 rootkit——你提到了 C++,但也有一些用于 .NET 和 Java 的托管代码 rootkit——它们会完全避开你的代码审查,但会出现在部署的二进制文件中。
此外,编译器本身可能具有某些 rootkit,它们允许将后门插入到您的应用程序中。(查看原始 rootkit的一些历史- 编译器在登录脚本中插入了后门密码;当从“干净”代码重新编译时,它还会将此后门插入编译器本身)。同样,源代码中缺少但存在于二进制文件中。
也就是说,对二进制文件进行逆向工程当然更加困难和耗时,如果您已经拥有源代码,在大多数情况下将毫无意义。
我想强调这一点:如果你有源代码,甚至在你通过代码审查、渗透测试、模糊测试、威胁建模等清理所有其他漏洞之前,甚至不要打扰RE。甚至然后,只有当它是一个高度敏感的应用程序或非常明显时才会打扰。
边缘情况很难找到,而且很少见,你的努力可以更好地花在其他地方。
另一方面,请注意,有一些静态分析产品专门扫描二进制文件(例如 Veracode),所以如果您使用其中一个,那并不重要......
@AviD 实事求是,完全同意二进制文件/编译器组件的根工具包。
如果您是一位知识渊博的 sec 专业人士,撇开 AviD 提出的有效观点不谈,大多数漏洞很可能出现在您的源代码中。拥有丰富的安全编程知识以及如何完成逆向工程应该为您提供修复/防止源代码中大多数漏洞的最佳方法。另外,如果编译器/二进制文件存在漏洞,很多时候作为开发人员,除了使用另一种编译器/语言(这通常不是一个可行的选择)外,您无能为力。
除了与安全相关的原因之外,还有很多原因可以查看最终的二进制文件。通过调试器、反汇编器或分析器和仿真器(如 Valgrind)(可以验证已编译程序的各个方面)。
程序的安全性和正确性通常齐头并进。
对我来说,它首先是对代码进行 linting(即使用 PCLINT),然后构建二进制文件,使用 fuzzer 和 memcheck(来自 Valgrind)验证这些,这在鲁棒性和可靠性方面给了我非常好的结果。在这种情况下,只有 PCLINT 可以访问源代码。
二进制和源代码分析给出了一些不同的观点,因此应该同时应用它们。然而,二元分析对人类来说可能是令人生畏的。并不是说在源代码级别分析不能令人沮丧,但在汇编级别分析应用程序逻辑并不是最好的选择。在二进制分析中,您正在处理实际上发生的事情,而不能以其他方式处理。如果在源代码中你可以做出一些假设,这里是确定的状态。
但是,应针对已编译的应用程序运行诸如模糊测试之类的测试,以至少在某种程度上确保应用程序的健壮性。代码覆盖率取决于 fuzzing 的方法、应用程序的细节和其他一些因素——这里解释的太多了,这就是 fuzzing 的艺术。甚至微软也开发了 fuzzing 工具并将它们应用到 SDL 中。这是 Codenomicon 的一篇论文,作为对流程的深入了解:http: //www.codenomicon.com/resources/whitepapers/codenomicon-wp-sdl-20100202.pdf