来自 资讯 2021-12-14 06:24 的文章

防cc_如何防护cc_方法

防cc_如何防护cc_方法

当我听说Heartbleed(OpenSSL中的漏洞导致了多年来最严重的安全漏洞)的那一刻,我下载了源代码并运行了CodeSonar,看它是否能找到缺陷。不幸的是,对代码的深入研究证实了我的怀疑,即通过代码到有问题的语句的路径很长,并且涉及到通过许多级别的间接访问数据。其中也有很多函数指针调用,这也没有帮助。代码的复杂性似乎难以精确分析。我想知道确切的原因,但令人心痛的故事还在发展,我们正忙着完成codesonar4,所以我把它放在一边几天。(James Kupsch和Bart Miller对静态分析工具为何会出现心血问题进行了很好的描述,可以在这里找到。)寻找心血几天后,ddos软件防御,johnregehr在他的博客上发表了一篇文章。他一直带着他的学生们浏览OpenSSL的Coverity扫描,游戏ddos防御盾,并指出该工具也没有发现它。然而,Coverity的andychou接着讨论了他们的工具如何使用启发式来检测心血。它寻找字节交换操作作为被操作的值来自网络连接的指示器,然后将这些值标记为被污染。有了这些知识,他们的工具在对memcpy()的错误调用中报告了一个受污染的缓冲区访问。我真希望我自己也能想到这个启发,因为它是一个非常聪明的例子,说明了用一点领域知识来教育一个静态分析工具可以获得很大的回报。我们很快就可以确认CodeSonar可以使用同样的启发式方法来发现这个bug,但是它让我有点困扰,因为它觉得这是一种脆弱的解决问题的方法。为了健壮并适用于其他代码基,该工具一般需要能够可靠地识别字节交换语句。在OpenSSL中用于进行字节交换的宏不是标准宏,因此匹配宏的名称对该程序很好,但对于其他程序则不行。另一种方法是匹配宏扩展到的语句。可能有十几种或更多可行的方法来进行字节交换,但要使其有效,静态分析工具必须事先知道所有这些方法,或者有其他方法来推断字节交换正在进行。如果代码是为big-endian平台编译的,其中字节交换是不可操作的呢?或者如果序列化的表单是其他不需要字节交换的表单?一定有更好的办法。找到让人心痛的"正确"方式我们一直在CodeSonar中实现一个新的警告类,污染缓冲区访问,原则上,它包括心血。这个检查器被设计成以"正确"的方式来检测这些bug,也就是找到污染源的位置,并通过代码跟踪污点,直到它到达触发bug的点。心血越来越大,我请团队成员德鲁·德哈斯和大卫·维泰克,看看我们未完成的原型实现能否检测到它。OpenSSL不是一个特别大的程序,但它相当复杂,因此为了保持可管理性,我们将重点放在分析显示问题的代码子集上。经过几天的调查,我们发现:我们确认分析正确地解析了间接函数调用,并且污染信息正通过这些调用传播。这是一个关键因素,因为malloc()和read()的调用(其中缓冲区的大小是确定的)都是通过函数指针进行的。污染传播可能很棘手。有许多明显的方式,污染可以传播,但我们错过了一些微妙的。我们有许多可调参数,允许用户在分析性能与彻底性之间进行权衡。这些默认的设置偏向于更好的性能,因此分析没有探究它所需要的一切。这些都是可以解决的问题,所以我们回去工作了。昨天,德鲁给我发了一封邮件,主题如下:主题:由CodeSonar探测到的心血果然,CodeSonar在调用memcpy()时报告了一个受污染的缓冲区访问。下面是显示该路径最后一部分的屏幕截图:这并不是完美的;解释是指memcpy()的形式参数,家庭防御ddos,而不是实际参数,但这对我们来说相当容易清理。注意红色下划线-这表示变量有问题。我们跟踪不同种类的污点,这个颜色表示文件描述符的污点。这可以追溯到在调用read()时污染源的位置。我们学到了什么?我还要强调的是,这项工作还处于试验阶段。上面的截图来自对OpenSSL子集的分析,虽然我们在完整版本中也检测到了它,防御ddos攻击的几大有效方法,但我们仍在努力寻找合适的技术和参数组合,以可靠地找到它,具有合理的性能和精度,并生成一个用户可以相对容易理解的报告。尽管在这方面还有很多工作要做,但是很明显,检测到这个bug的原因是正确的。关键是,我们用来实现这个新的检查器的技术是开发出来的,并且在发现心血之前已经接近可用性,DDOS防御能力,这是它们通用性的一个证明。像这样的挑战性问题对这个行业是有好处的。虽然有些人可能会抱怨我们在马已经跑掉后关上了马厩的门,但事实是,几乎可以肯定,马厩里还剩下很多马。心血不太可能是存在的最后一个严重的安全漏洞。拥有真正重要的bug的非常具体的例子是促使像我们这样的工具供应商不断改进技术的原因。这些改进应该有助于我们避免下一个重大的安全漏洞。