移动安全 安全管理 应用案例 网络威胁 系统安全应用安全 数据安全 云安全
当前位置: 主页 > 信息安全 > 应用安全 >

如何阻止下一次心脏出血漏洞(3)

时间:2014-07-25 13:25来源:TuZhiJiaMi企业信息安全专家 点击:
四、前提条件 很多的技术有重要的先决条件;让我们来讨论下。 4.1 在没有特别要求时内存分配 许多静态技术可以对抗心脏出血漏洞的缺陷,包括使用人工核查来对抗,因为OpenSSL的代码很复杂
Tags漏洞(188)应用安全(1006)心脏出血(8)  

  四、前提条件

  很多的技术有重要的先决条件;让我们来讨论下。

  4.1 在没有特别要求时内存分配

  许多静态技术可以对抗心脏出血漏洞的缺陷,包括使用人工核查来对抗,因为OpenSSL的代码很复杂。代码只有简单了才能安全。

  许多安全软件开发者首先使用“软件质量”工具来检测特别复杂的结构,然后简化这些结构,这就是安全软件的产生过程。理想的静态分析方法由于代码复杂和变得困难,实用工具来检测这些代码的复杂性,简化他们,在使用静态分析方法就变得很有效。我认为他们是对的,但是我没有发现可以支持他们的数据。因此,这似乎是一个合理的想法,但是我很希望有人最终将创建并发布一些科学研究来支持和反驳这个假设。

  在任何情况下,简化的代码是超过运行工具软件的。这是一种心态,应该要有不断的努力来简化代码,不然增加运行能力就会增加软件的复杂性。代码的重构要使它变的更简单和清晰,不是不断的增加新的功能。我们的目标是代码是对的,而不是代码很复杂我们看不出问题。

  过于复杂的代码通常会导致安全漏洞。2006年Debian意外事件通过修改软件来消除valgrind警告来打破OpenSSL的随机数生成器。但是,修改软件的人并不真正的了解它。那个人要求帮助,但是OpenSSL的代码复杂就很难使人找到改变后的漏洞。Cox通过研究发生并得到了以下的结论:“尽量不写偷懒的代码,写井井有条的代码。你会不可避免的写一些偷懒没有组织的代码。如果有人问到这这个问题,就把它作为代码不够好的标志。重新把它变得更简单和容易理解。”

  LibreSSL的开发者使用了OpenSSL代码和专心用来简化代码。LibreSSL-一个OpenSSL的变版,介绍OpenSSL代码库的一些问题。他们正在做许多的明智的事,如去掉代码支持过时的VAX VMS系统。然而,他们删除了人们关心的代码。例如,他们去除美国政府使用的FIPS 140-2的认证,这同时也受到了许多民营企业的支持。在使代码变得简单和使代码在很多的环境中都有效之间存在着冲突,最简单的代码不能实现什么。很显然,许多程序可以变得比现在简单。

  4.2 简化应用程序接口

  虽然这稍微的超出了本文的范围,一个相关的问题就是应用程序接口一般情况下都比较复杂。

  大多数加密库和数据传输库都是很复杂的,他们通常呈现给开发者一个“困惑矩阵的选项和设置”,因此,大量的应用程序和高层次的库使用不正确的库来进行加密,导致了系统的漏洞。大都数的问题在浏览器中工作中出现,但是他们在其他的代码上仍然是一个问题。想要了解更多的信息,请看“最危险的代码世界:在非浏览器软件中验证SSL证书。”

  尽管这在SSL/TLS的使用中是一个技术而不是一个漏洞,但是他们是无关的。加密程序库是创建的复杂接口的一个组件,所以,它仍然是一个故障组件,简化代码。

  一个相关问题是底层库和建立在API加密库的系统的很难使用。C忽略了像asprintf和reallocarray等功能。因此,程序员必须要解决这些漏洞,但是他们的解决方法常常会出现bug,这些bug会导致漏洞。

  4.3 分配和释放内存

  安全的程序必须正常的分配和释放内存,没有特别的分配系统和内存缓存系统。至少,它应该很容易禁用和测试它们来确保禁用了他们的程序。一些技术会减轻心脏出血漏洞的出现,因为OpenSSL的内存分配方式。

  基本问题是OpenSSL包括未分配的内存的应用程序特定的缓存空间。目的就是要加快分配在相同数量的重复指令。在默认情况下,OpenSSL正常分配内存,但是在内存区域没有被使用时是不会解除分配的,在很多情况下,把该区域变成未使用的区域变成空闲的,来使它可以立刻重启。这个缓存列表颠覆了一些操作系统和C的运行的一些的机制,因为他们并不是总得到通知在内存不使用时。

  Theo de Raadt提到:“几年前我们增加利用措施到libc malloc和mmap,这样一来更多的bugs就会暴露出来。这种存储器会导致死机,甚至是核心的崩溃。分析这些bug,之后永久的维护系统。其他的调试工具也会达到这个目的。在很大的程度上说,这基本就没有性能上的损失。但是在那个时候OpenSSL添加了malloc & free的封装,使库存在缓存中。因为一些平台的性能下降,甚至如果你建立防护技术引入malloc() 和free(),这就无效了。在所有平台上,由于选项是默认的,并且Ted的测试表明你不能关掉它。因为他们没有测试它的年龄。所以后来的bug显示了在该层的内存的泄漏内容。如果内存通过free得到了恰当的返回,这就可能被munmap捕捉到,并激发保护程序的崩溃而不是泄漏你的密码。”

  似乎有很多在什么地方出来问题的困惑和OpenSSL的内存分配方法,Chris Rohlf取得了一些有益的验证。我觉得这些验证是很重要的,因为我们必须先用理解这个问题在我们修护它之前。特别是Rohlf指出OpenSSL使用的是标准的malloc() C内存分配方式,当它需要一个全新的内存块时。问题是一旦一个内存块被分配,OpenSSL自身还在自身的管理存储器。Rohlf也指出在很多的环境下是与空闲列表是无关的;一个空闲列表把不同的内存分配在了一起,但是许多典型的内存分配系统也提出了不同的内存分配。然而,Rohlf的典型的内存分配的应用来做同样的事是绝对正确的,关键是OpenSSL的实现阻碍了各种缓解措施。关于OpenSSL的内存分配系统有另一个问题,但是我们首先要介绍下一些基本知识。

  一般的方法就是处理一些内存的分配和释放特例,我们的想法就是缓存和重新对某些对象和缓存器在他们没有被使用时,这中方法可以显著的提高性能。这种方法的具体例子包括专门处理共同的内存分配的大小,或是用未使用的高速缓存来重新使用对象和内存器。有一些具体的技术来做这些,包括创建一个对象池和一个slab分配器。Glib库包括一个称为记忆切片的机制,提高内存的分配性能。许多图形用户界面和程序在使用这些方法时,是没有安全感的。

  事实证明,一些方法可以不用解决一些检测工具如address sanitizer和使用保护页系统。特别是使用fuzz测试的问题,如果这些工具不被禁用,则fuzz测试就会变得没有效果了。的确,fuzz测试可能不能检测到许多超出范围的读操作,在使用这些方法时。

  关于OpenSSL的报告指出OpenSSL的使用是自我管理的一个交大的内存区域的方法然后在进一步细化。这是一个使用slab分配器或是储存器切片时要发生的。使用这个方法就是想要提高性能,在这些情况下使用address sanitizer和保护页系统来抑制检测完全的读溢出。旧的版本称这要发生什么。但是我已经钻研了更多的OpenSSL代码,而这似乎并没有在OpenSSL中的真实性。这对于心脏出血漏洞来说是个好消息。尽管如此,这些类型的分配方案是比较常见的,而且我知道没有人说道这些方法的风险。

  安全性软件必须要避免使用内存缓存系统,尤其是那些与一种分配机制联合在一起形成一个分配请求。如果不是这样的话,他们至少提供一个简单的证据机制来禁用它们,并要使用该机制作为其回归测试套件的一部分。OpenSSL有一个禁用机制,但是不再被使用,并且在任何情况下很少有人能了解这种机制,它可以禁用安全分析工具的很多工程。

  我们还需要修改我们的教育材料,是开发人员和测试人员都知道内存缓存系统会严重妨碍安全分析。在我的演讲中我已经提出了一些材料来开发安全软件,其他人员也一样需要。

  从长远来看,这或许应该是使用C的标准接口在freelists缓存/ slab分配器。如果有标准的接口,你们工具可以很容易的修改和自动调解他们。

  4.4 使用标准的FLOSS许可证

  这是我的推测,我相信如果OpenSSL使用标准的推广的许可证来进行代码审核会有更多的贡献发生。OpenSSL使用的奇怪的变量许可证是GPL和LGPL。因为GPL是一个最常见的FLOSS许可证。在很多情况下这种不相容性是通过围绕一个许可证漏洞的,或是使用许可证除了在软件中通过使用OpenSSL。不过这个诡异的证书意味着很多人更喜欢GPL或LGPL会情不自禁的禁止或是审核OpenSSL。一些人喜欢限制较少的许可证,这些也有很少的帮助,这不是一个标准的证书。

  我确实有一些证据表明非标准证书是一个问题。一个完全独立的软件包GnuTLS在最初是专门创建的。因此使用标准GPL许可证的软件能够轻易的使用SSL/TLS。OpenSSL的LibreSSL转变成了2-clause BSD许可证,当他们写了新的代码,相比与OpenSSL许可证。

  在很长的一段时间了,广泛的使用FLOSS证书对FLOSS项目来说是很重要的。1999年Bruce Perens指出:“如果使用这里被列出的一个,就不用写新的许可证了。”后来Open Source Initiative创建了License Proliferation Project,指出许多许可证“和其他开源代码的许可证是不兼容的,严重的限制了开发人员的方法,开发人员仅仅是扩大开源软件的创新方式。”一个重要结果是OSI直接列出了开源代码许可证的页面,只是Popular Licenses,这是“流行,广泛使用,或是强大的社区。”

  大多数的FLOSS是基于GPL, LGPL, MIT/X, Revised BSD,BSD 2-Clause或是Apache 2.0 licenses。我建议限制FLOSS程序的许可证列表。你可以添加一些;在OSI的流行许可名单包括更多。然而,这里的问题是OpenSSL许可证根本就不是一个公共无可证。更重要的是它是一个广泛使用的不兼容的许可证的非标准证书。如果可能的话,最好用一般通用的许可证代替。

  五、什么会减少心脏出血漏洞的影响?

  什么能减少心脏出血漏洞的影响或是完全消除?毕竟当漏洞出现,你想减少影响。下面有一些方法。

  5.1 一旦标准内存分配器被替代,启用内存分配器的防御。

  许多系统包括减少损坏的内存分配机制,有的有时可以发现问题。这不能对抗问题,但是能够减少影响,例如:

  一个常见的方法就是内存在分配和释放时零出,这就意味着如果数据显示,这不太可能是有趣的事。

  在2014.4.29,David Wagner提出了一个有趣的选择:“使用一个特定的内存分配器,它能够给每个对象一个随机的地址。在一个64位系统上,会有一个48位的地址空间,这一切都在离分配对象远的地方,这个心脏出血漏洞不会透露任何其他对象的信息。这可以被纳入标准内存分配器。注明:我不主张这么做,我不是说这是最好的防御,我只是回应你的要求想法来阻止它。”

  OpenBSD的malloc支持保护页,如前所述。特别是它的G和P选项可以减少和防止信息的泄漏。不幸的是很多的流行malloc不包括这个功能。

  5.2 覆盖了你他们一起做的关键信息

  关键信息包括密码和私有加密密钥。可以肯定这不是被优化掉的,大多数的编译器将会消除这种覆盖,如果你不能避免的话。

  5.3 使用默认的加密方法来做完美的安全

  一个加密系统有完善的保密,当它的非确定性生成器生成一个随机的公钥。当PFS启用,当一些密码暴露时,信息不一定会暴露。因为没有用于所有信息没有单一的密码值。

  5.4 使用权限分离来达到分离关键密码的作用

  它可以帮助从其余的代码中分离加密代码出来,于是即使余下的程序被覆盖,它也不能直接访问私密的密码。

  这就会使用到基本的安全原则上,程序要提供最大限度的私密权利对于他们的工作。这些方法可以通过减少漏洞,如密钥等关键信息的软件的数量,从而减少漏洞的数量和影响。不过,我要列出一个减少风险的方法,不是作为一个完整的对错。某个地方的代码必须有提供访问权限的数据,并且这些代码可能有漏洞。这里有些其他的注意事项:

  David Wagner指出了这一点,并且进一步解释说:“RSA私钥可能已经被移动到另一个单独的过程,只有运行私有密码代码就会转移到这个过程。在Intel系统中,OpenSSL可以使用采用SGX来运行所有的加密计算在独立的沙盒执行环境下。这被认为是在软件加密模块下的,如虚拟TPM,虚拟HSM等。SGX提供了分离关键代码的硬件支持,但是可以使用其他的机制来代替SGX,像进程隔离或是沙箱。有很多的学术著作上保持这加密代码分离的方法,以及一些考虑到了OpenSSL的特别性。” Rutkowska2013里有关于SGX的介绍,在Brumley里有应用OpenSSL的权限分离的讨论。

  Peter Neumann指出在硬件的基础上,沙箱和fine-grained访问控制也会提供强有力的机制来限制权限,从而控制心脏出血漏洞。

  一个学生在我的开发安全软件的课上建议内存在服务器上隔离每个用户。这是一个很有趣的想法。

  5.5 修复SSL/TLS证书的基础设施,尤其是对证书的吊销。

  完整的SSL/TLS的基础设施有很多的问题,包括不值得信任的根证书权限,不良的审核证书和严重损坏的证书吊销过程。作为一个关联点,Qualsys SSL实验室发布了SSL威胁模型。

  在目前而言,让我们特别关注证书吊销的过程,在对心脏出血漏洞的回应时,这是被特别的关注的。心脏出血漏洞使人们有可能为攻击者遗漏私密为他们的证书,这是很糟糕的。理论上,漏洞网址可以部署新的证书和撤销旧的证书来解决私密的曝光。不幸的是,今天的证书吊销机制在根本上没有被打破,少数人会很重视这个问题。因此,今天的攻击者往往会导致网页浏览器来接受他们的证书被撤销。有一个迫切的需要推动这方面的工作,远远超过目前可以使用的机制,更好的创造安全标准,并实现它们爱默认情况下无处不在。我认为应该有一个确定推动X509 OCSP的必备,但解决方法会证明这是我们需要的。

  这是一个很复杂的区域,我会总结这些问题,这里有几个证书撤销的机制,和使用他们的问题:

  证书吊销列表。证书吊销列表是一个吊销证书的大文件。这是最原始的撤销做法。当时的想法是一个程序会下载并检查证书吊销列表在接受证书之前。但是证书吊销列表尚未缩减到今天网络的要求,今天的证书吊销列表是很大的,要频繁的下载更新来保持目前的列表,使他们越来越不和实际。人们已经逐渐远离证书吊销列表,如Firefox 24变成了自动更新证书吊销列表和用户导入证书吊销列表的接口。

  在线证书协议。在这个方法中,程序可以与服务器连接来请求特定证书的状态。在线证书协议应该比证书吊销列表需要更少的网络宽度,接近实时的状态检查。然而,在线证书协议创造了巨大的体积和证书发送机构的响应时间要求,因为他们现在必须提供对应所有客户端在一个真实的时间。在线证书协议也要创建了一个严重的隐私问题:它会导致客户透露给CA,它与客户正在联系。另外,不论在线证书协议和证书吊销列表有一个根本性的问题:如果你不能找到答案会出现什么?在实践中,实现线证书协议和证书吊销列表的系统都默认软件连接失败,也就是说,他们接受证书,在他们没有找到其他的东西。但是软故障使得整个方法没有用,因为攻击者往往可以干扰或去掉这些要求。硬故障时可以正常的工作,和其他人说它也可以为他们工作。然而,切换到硬件故障确实有其自身的严重问题。这个附加的检查减慢了到安全网站的连接,并且很多用户对这个额外的时间很敏感。在线证书协议服务器的故障是很常见的,在连接到网络受到制约的地方时你要暂时不用这个,如果硬故障被广泛使用,之后攻击者可以通过短暂的在线证书协议服务器连接来禁止HTTPS。攻击者甚至可以使用在线证书协议封装,包括已经吊销证书的在线证书协议响应,挫败了Langley2014a和Langley2014b的检查。

  在线证书协议封装。在线证书协议封装试图通过让证书者来查询在线证书协议服务器,不是最终的用户和得到一个签名的时间的反应,是在有效的时间里解决在线证书协议的问题。当客户端随后访问这个网站时,他们会从该网站获得证书和一个附加的封装时间。如果没有收到封装响应,那么客户端可以回退到另一个方法,如标准的在线证书协议。这不是广泛部署的在线证书协议和证书吊销列表,但是一些网络服务器和网络浏览器都支持在线证书协议装订。然而在线证书协议封装本身仍然容易受到攻击过滤;在很多情况下,攻击者可以去除装订的响应,并阻止客户端获得在线证书协议服务器。在这种情况下,在浏览器中的正常的软失效过程中导致整个系统失效。

  证书吊销列表设置。证书吊销列表设置是建立在网络浏览器的短暂的证书吊销列表。例如Chrome浏览器开发人员编译了一天列表,他们认为是“高价值吊销”和使用Chrome的自动更新机制,使这个列表推送到Chrome的安装。Adam Langley,一个谷歌的专家,提倡使用证书吊销列表设置机制,而不是证书吊销列表和在线证书协议。我同意证书吊销列表设置可能是有用的,当一个网络浏览器强行撤销广泛使用的网站证书。但是总体而言,我认为证书吊销列表设置正在从根本上被打破。一个证书吊销列表设置就是一个不完全的黑名单。Langley指出,一个证书吊销列表设置是不完全的,也没有达到足以应付大量的撤销…希望使用证书吊销列表设置,那样我们就能够把撤销的变成重要的和行政的并推动重要的…可悲是,这没有发生。Gibson有一个正确的观点,他指出“互联网证书吊销列表列举出超过两百万撤销和不信任的证书。不过Chrome的证书吊销列表设置目前列出了约24000的吊销证书。两百万中另一种隐式的别Chrome信任。”证书颁发机构安理会已经强烈反对证书吊销列表设置机制作为唯一的证书撤销机制:“心脏出血漏洞是完美典范为什么撤销的是很重要的,即使没有确定的关键妥协。没有人可以肯定的说,他们的服务器的私密被攻击了。大多数撤销正在进行证书吊销列表为“商业原因”,而不是提到证书吊销列表设置。这里很清楚的认为证书吊销列表设置只是一个简单的吊销证书的黑名单。”其他浏览器也有类似的黑名单,而这些可以有效的时间。但是他们不能替代在线证书协议的检查…即使撤销在线证书协议的检查不是100%的准确的。它仍然可以保护用户的比例…关闭撤销检查对每个人来说都是没有保护的。只是要清楚,我不认为证书吊销列表或是在线证书协议运行的良好,我同意证书吊销列表设置可以有一定的效果,尤其是当有一个特定的高调网站证书被曝光。然而,像心脏出血漏洞是不同的,在心脏出血漏洞中,如果他们的私有密钥时网页不能确认被排除了,所以他们需要撤销他们只是确定的…而且由于OpenSSL被广泛的使用,这会硬性到很多的网站。证书吊销列表设置不能解决心脏出血漏洞的问题。

  必备的HTTP头文件。Firefox计划实施一个新的必备HTTP头文件,知道像X.509 OCSP等更好的机制必须封装起来便的可用。这只是增加了一个新的HTTP头文件作为一个HTTPS的连接请求的一部分。如果这个新的头文件是有服务器提供的并且支持浏览器,浏览器将会需要一个封装在线证书协议在该域以及子域。再次,如果这是客户端第一次被访问攻击者就可以颠覆这个了,因为攻击者仍然可以伪造初始连接。有些人混淆了用X.509 OCSP主封装HTTP头文件的方法,他们不是一样的。

  短暂的证书。一种解决方案是部署只能持续很短时间的证书,如,几天而不是年为单位。从理论上讲这就要在今天工作;到期时间是有效测试证书的基础。不过这可能不是扩展,许多系统假设证书的有效期是很长的时间,并且额外的CA的工作可能很容易犯错误。许多的用户使用过期的证书并且忽略了他们的警告。最后,许多机制可以对抗其他证书的问题通过假设的证书很少的改变,所以这些修复能够增加漏洞。

  X.509 OCSP 必备的封装。在这种方法中,该证书具有一个标记,表示该用户端必须要接接OCSP封装,然后OCSP封装被广泛使用。这是一个附加的OCSP封装,但是它可以防止攻击者筛选OCSP封装,因为客户知道什么是错误的。请注意这不只是封装OCSP,这不是一个必要的封装HTTP头文件,人们有时会混淆这些不同的方法。不像必须封装的HTTP头文件的方法,攻击者无法轻易筛选出这一点,因为证书本身指出需要封装。这中方法对短寿命的证书同样有效果,就不会有这些问题。Langley, CASC和其他的公司都推荐使用OCSP必备封装。然而虽然有必须的封装,这没有正式的规范并且这种扩展不被广泛使用。对于这个工作我们需要一个正式的规范,在服务器和浏览器中广泛的使用包括扩展的X.509证书包。

  其他方法。还有其他的方法,尽量处理犯罪嫌疑人的证书,包括TACK和Mutually Endorsing CA结构。再次这些没有被广泛的使用和接受。

  5.6 使软件容易更新

  问题将会发生,组织者必须在必要的时候修复他们。如旧的Android 4.1.4就容易受到心脏出血漏洞的攻击。这是因为Google虽然很快的修复了这个版本,但是手机的制造商很慢的更新手机,手机运行商通常会推迟更新的时间。也到了谈论制造商和运营商不能修复手机的问题,当有安全漏洞要修复时,运行商已经即时的出售了手机。同样,我认为通过FIPS 140-2验证过程需要改变,以便库中的漏洞被发现和更新。

  5.7 存储散列的密码

  当然,继续把散列的数值作为密码,而不是明文或是可逆值,如果要存储密码为明文或是可逆的值,你没有说服人的理由,你就不能使用。

  5.8 一般问题:安全软件教育/培训和减少攻击者的攻击

  我要提到各方面的改善可能会减少一般可利用的漏洞的数量,有时利用这些。这就包括安全软件教育/培训并且要减少攻击者的攻击。

  很多的软件开发人员依然没有受过什么教育和培训来开发软件。然而,几乎所有的软件可以直接连接到网络上,或是可以通过一个网络接收数据。许多开发人员不知道如何设计软件来对抗攻击,一般的漏洞是什么,和如何正确的对抗。事实上,很多开发人员不知道安全软件和软件安全的区别。这些材料是可用的,我在一本书上写了如何开发安全软件,开发人员必须要学习和运用这些知识。

  我们也需要减少经济效益的攻击,经济激励会使人们发现漏洞并要出售给攻击者。在很多情况下人们不会把漏洞告诉防御者,他们可以通过出售这些漏洞给攻击者来得到很多的钱。毕竟人们可以通过出售一个单一的漏洞来合理的挣到100万。赏金根本跟不上当时的情形,我们需要探讨如何减少这些诱惑。例如也许我们应该把漏洞信息卖给不是供应商和政府的人定罪。基本上对于漏洞信息的捐献:有意的消除经济引诱在一个特定的区域来获得一个更好的社会。我认为这不可能防止公民来告诉他的国家软件的漏洞;公民必须把这作为他们的职责。我觉得没有一个政府会禁止购买这些信息。但是额外的限制可能会减少人们积极寻找漏洞,不是修复而是利用他们。显然有一些人会做违法的事,但是有些人会避免做违法的事,这是因为他们怕被捉到。你并不需要停止所有可能,只是改变。也许有更好的办法,如果有的话,请提前说,在任何情况下,我们需要找到一个方法来做物质的工作和不是安全。

  六、应用这些方法

  正如我前面提到的,开发安全软件需要的工具和方法的结合。当有错误时,要弄清楚发生了什么,我们需要了解它们失败的原因,并要试图做的更好。

  这不是一个很好的时机来使用加密库。这些库是很重要的,但是最近发现了很多的问题:

  1、本文的重点是OpenSSL中的心脏出血漏洞。

  2、苹果的iOS遇到了漏洞,这是一个简单的故障来检查无效的证书。这些漏洞可能已经通过各种机制,包括静态死代码检测器,测试覆盖工具,或是无效认证的否定测试。

  3、GnuTLS也不能正确的认证证书,其次,似乎有可能检测到这个在代码公布之前,其中包括否定测试。

  4、OpenSSL CCS的注入。其中一些精心制作的可能会导致密钥的成为弱项。Masashi Kikuchi已经分别描述了他是怎么发现这个漏洞的。他首先想到了使用Coq来证明使用的正确性。他专注于过度的CCS,然后检查如何验证代码转变条件。他发现OpenSSL不能验证失败的情况,并且发现了漏洞。

  5、一个随机数生成器不能在OpenSSL运行,值得注意的是,可以通过它来检查这个错误,所有的基本工程测试已经掌握了这一点。

  许多人依靠加密库但是评估这些要有专业的知识,美国政府已经建立了一套流程来评估加密模块,称为FIPS 140-2。我认为这是个好方法来广阔的评价这些很重要并且难评估的项目。

  这有更重要的事情,虽然符合FIPS 140-2进程,但是不检查加密协议,包括SSL/TLS的实现。相反,当前的FIPS 140-2进程只能计算它在密码库内的算法和检测在密码模块内的方案。我没有说清楚这个旧版本的文本,我希望弄清这些事。作为实施指南的FIPS PUB 140-2和加密模块验证程序的有效性。“该加密模块可以实现在安防行业已知的各种协议。这些协议的例子是IKE, TLS, SSH, SRTP, SNMP和TPM,在NIST SP 800-135rev1列出来。FIPS 140-2以及其附件没有解决方案,只有在加密算法和方案被认可和允许时,这些在操作模式下使用。”

  实际上,OpenSSL坚持使用FIPS 140-2认证,它修复了心脏出血漏洞由于使用了附加的技术。FIPS 140-2进程不能评估正常的OpenSSL代码,只是评估了叫OpenSSL FIPS对象模块的特别的软件模块。OpenSSL FIPS对象模块有一样的接口,并且从OpenSSL代码中衍生出来,但它还是一个单独的模块。开启“FIPS模式”来结束FIPS模块代码,而不是使用常规的OpenSSL代码来实现加密。因此OpenSSL FIPS对象模块可以保持其通过FIPS 140-2的认证,即修复心脏出血漏洞,这是因为FIPS 140-2进程不评估SSL/TLS协议,因为不符合FIPS某块的代码必须要修改。在其他方面不同的情况下发生的。通常情况下,任何的加密模块的改变都不能导致验证的损失,这就需要很长的时间和金钱来得到一个新的验证。亏损的危险就是一个反常的激励:加密模块的开发人员有一个强烈的动机来区分问题。如果这是正确的,我可以肯定OpenSSL开发人员和FIPS的使用者和高兴。这就意味着心脏出血漏洞能够很快的得到修复在符合FIPS时,我确认在2014-05-09理解NIST。

  因此通过设计FIPS 140-2进程中没有通过SSL/TLS来实现的包括加密协议在内,我觉得这公平来询问,但是,如果要注意保密协议。正确的评估加密协议需要相同类型的专业知识和其他的加密代码。很容易创建和运行一个大的测试套件来对抗如SSL/TLS的标准协议。这并不奇怪,验证过程没有发现随机数生成器的失败。我想通过FIPS 140-2进程至少是使用动态测试每一个支持加密随机数的生产器,从而确保他们是随机的,并且可以避免常见的错误。这将不花费很多和提供了一些信心,如果FIPS 140-2进程不能延长审查加密协议,那么事情应该建立来审查这些。一般情况下,我们需要重新测试FIPS 140-2来使它运行的更快更彻底。当前的进程使它很难更新库,如让一个人得到了关于安全和兼容性的结论。

  没有测试过程中可以找到所有的问题,所以期待的完美是不合理的。不过,存在这新的技术来评估保密代码,这就会增加速度减少成本。更重要的是,我们都需要对攻击者的学习来增进当前评估过程来对抗容易忽略的漏洞。我的目标不是来毁掉现有的各种评估进程,评估是一项很难的任务。我的目标是要弄清楚做什么可以改善这些事情,因为加密是最重要的。

  需要更严格和透明的程序来测试加密协议,一个要求对安全漏洞进行更新和公开的更新程序来防止复发。我能够很容易的看到FLOSS项目来创建一个更严格的测试套件,指的是通过密码库的使用和用户的关注程度。

  我想我应该提一下FLOSS。有些人曾经试图宣称心脏出血漏洞在一个FLOSS不能创建好软件的证据。这没有意义,在专有软件中也发现了漏洞,在2013年,Coverity的扫描报告中发现“开源代码的质量优于专有的C/C++项目。”在现实中一些FLOSS程序是安全的,但是专有软件就不是很安全了。FLOSS有些潜在的安全优点,但是他们只是潜在的,你必须要检测特定的软件来确定它是否适合您的需要,包括它的安全性。

  Eric S. Raymond把下面这叫做“Linus’ Law”:“使用一个足够大的β测试和联合的开发基础,几乎所有的问题很快的成型和修复就变得很明显了。”或是不正规的“只要你认真的寻找就会发现漏洞。”但是,这不意味着一些人想要。首先Raymond截然不同的发展FLOSS;他不是在谈论FLOSS和非FLOSS。其次,注意到更小心的措施需要“足够多的联合开发人员”基础;加密学使得得到一个大的开发者基础成为问题,并且非标准的OpenSSL证书有可能抑制了合作开发人员的数量。第三,注意这些文字“几乎每个问题都会很快的形成”,他从来没有声称发现了所有了问题,或是他们很快的被发现。最后,文中指出事实证明传统的方法在发现和对抗这些问题时不会奏效,虽然有很多的工具和方法来分析OpenSSL。相反,系统问题来发现类似的漏洞,因为不同的人使用类似的假设。好的消息是我们可以找到漏洞并且修复这些漏洞,因为漏洞的成因是公开讨论的。在大的设置中,本文代表了人们识别系统的问题来修复他们,从而类似的漏洞会很快的发现和修复。

  本文着重关注如何应对技术。然而这里还有很多的非技术问题。Summer Maynard的“什么能让心脏出血可以教导OSS社区的市场营销”,这就展示了心脏出血是怎么被推销的。市场营销是很重要的;心脏出血是一个很糟糕的漏洞,好的营销加快的反应速度和降低了伤害。项目可以帮助关键的部件,这些有潜在问题的;核心的设施要数百万的美元来资助开源项目,这个项目是核心计算机功能的关键路径,这收心脏出血漏洞启发的。

  七、范例

  那么是不是有做的很好的例子?毕竟容易引起抱怨,但是如果没有人可以做的很好,那么这应该是不可能的。此外,如果没有可以复制的例子,就很难学习怎么做了。

  我要求人们在可靠性和安全性方面来区分强大的FLOSS例子。当然,一个程序会有一个强劲的投入和不安全性。此外,即时是好的系统也偶尔会有问题的。这是一个很好的想法来看这些例子,因为很容易使用类似的方法在你在实际运行中。这有一些人们确定的项目:

  OpenBSD。OpenBSD渴望成为安全领域的第1。他们由一个6-12人的队伍来进行安全审计:“我们不能找到很多的安全漏洞,因为我们正在找软件的基本问题,使用很长时间后人们才会发现安全问题,之后修复这些问题。在系统的任何领域都会发现漏洞。在我们审计中发现了在安全问题中新的类,而且往往这些较早审核的源代码需要重新设计时要考虑到这些漏洞。代码要经过多次的审核,并且由很多人使用不同的方法来审核,另一个安全的审核过程就是他们的积极性。在很多的条件下,我们发现对于开发的决心不是一个问题。在我们的审计过程中,我们发现了很多的问题,并且我们努力解决这些问题,即时没有得到证实。” 他们试图创建并实施对抗这些漏洞的新方法,包括strlcpy()/strlcat(),保护页面,和随机malloc()。他们还在“默认安全”下工作,同时进行全面的披露。

  OpenSSH。OpenSSH是实现SSH协议和密钥连接的工具。OpenSSH是在OpenBSD项目的两个团队开发的。一个团队做基于OpenBSD的开发,其他的团队需要运行这个版本在许多操作系统上运行。OpenSSH使用的是OpenBSD的安全开发流程。OpenSSH的开发人员一直在努力降低OpenSSH被攻击的可能性。他们的方法有防御性程序,使用独立的库来减少复杂性,轻度的改变协议来减少攻击,特权分离,通过改变程序来最大化的缓解在操作系统的攻击。想要了解更多的OpenSSH的权限分离可以查阅Provos2003。

  SQLite。SQLite是通过使用非常积极的测试方法来获得可靠性。该项目的代码行中超过了1000的测试代码和测试脚本。他们的作为包括三个独立开发的测试工具,异常测试,fuzz测试,回归测试,自动资源泄露测试,100%分支测试和MC/DC覆盖测试,数以百万的测试方案,广泛的使用assert()和运行时间检查,Valgrind分析,整数溢出检查,开发者清单。他们没有编译警告,在警告开启或是使用Clang静态分析工具。在2014.5.10,Peter Gutmann告诉我:“我一直使用SQLite完成我专业级软件开发,我谈论了怎么开发和测试它,在受到强烈的影响下。”

  Postfix。我注意到Elaine R. Palmer和Bill Cheswick认为他们对安全和可靠性都全面的了解。Postfix的方法来开发安全软件重点在于存在一个非常有经验的团队,从头开始编写到安全,涉及到一组守护进程分别执行不同任务的集体结构。Postfix使用C和POSIX的安全子集,并结合创建安全的替代品的一个抽象层。例如,它有一个“vstring”创始人的帮助来缓解缓冲区溢出的攻击和“safe open”创始人来阻止竞赛条件。

  GPSD。全球定位系统服务守护进程。这使用了大量的回归测试,使用多个工具的严格的静态测试和可以减少风险的构架方式。他们使用一个自定义的框架来拓展回归测试套件,包括使用诸如valgrind工具。他们的静态分析工具包括splint,cppcheck和Coverity;他们说道:“我们不知道没有比GPSD更强大的套件,包括全部的splint注解,并强烈怀疑没有存在。”或许更重要的是,他们的设计没有缺陷。Eric Raymond说到,“如果移动或是主机不是Windows,GPSD肯定可以运行,在世界上所有的智能手机的GPS监控,DARPA挑战一个重要的航海系统,从无人驾驶汽车开始,还有大多数的无人机和机器人,只有CVE和在十年内没有任何的漏洞。在几个月的时间内没有任何的缺陷报告,GPSD是使用传统C的基础,从而可以使你非常接近不用判断。我得到了疯狂的回归测试和常规的四个静态分析器。”

  这当然不是一个完整的清单,他们中的漏洞会被发现的。尽管如此,它指向用来提高安全性和可靠性的项目,以及他们是如何工作的,让别人找到什么值得模仿。

  八、结论和建议

  有几种方法可以发现心脏出血漏洞,在这漏洞软件发布之前。这不是一个真对OpenSSL开发人员的,他们在一直的努力减少漏洞的数量,包括审计的人数和工具。相反,本文是来帮助改善的,OpenSSL和其他的项目可以通过改变他们如何开发和评估软件来阻止将来类似的漏洞发生。

  我们已经学了一个重要的事情是许多的静态和动态分析方法使用在分析的项目中,也没有找到心脏出血漏洞。这就包括使用自动测试套件,fuzz测试方法,和典型的语句或是分支代码覆盖率的方法。几个源代码的弱点分析仪的开发人员正在改善他们的工具来检测非常类似心脏出血漏洞。我认为我们应该继续使用这些工具,但是和明显不够。想要打造安全软件项目还需要添加一下的一种方法:

  1 彻底的negative测试(动态分析)

  2 带地址检测和标准内存分配的fuzz(动态分析)

  3 在标准内存分配器下编译和使用地址保护或是sanitizer(复合分析)

  4 在各个领域内有验证是使用手动检测(静态分析)

  5 上下文配置的源代码弱点分析仪,包括注释系统(静态分析)

  6 100%分支覆盖率(复合分析)

  7 入侵时间描述(动态分析)

  8 更安全的语言(静态分析)

  9 完全静态分析器(静态分析)

  10 彻底的人工核实和检测(静态分析)

  11 格式化方法(静态分析)

  项目应该保证容易分析。例如简化代码,正常分配和释放内存,使用标准的FLOSS许可证书,这要具有广泛的兼容性。这将会是很好的使用一个编程语言,包括C,有被广泛接受的标准注释符号,从而使注释语言更容易被接受。象C语言是很难得到这样的协议的,但是我觉得要是能够使它标准化,他们就会更广泛的使用。

  还有很多的方法可以减少心脏出血漏洞的影响:

  1 一旦标准的内存分配器被取代,开启内存分配器的防御。在很多系统如Linux上的GNU malloc就没有这种机制,我们要首先进行添加。

  2 覆盖关键信息在处理他们时。

  3 使用完美的缺省的向前安全性的加密算法。

  4 使用权限分离的临界加密用于其它的代码部分。

  5 修复SSL/TLS的证书架构,尤其是默认证书的吊销过程。这就要协调一致的努力才能得到真正的解决方案中的规定,实施和部署;我们要从现在开始。

  6 是软件升级变得简单。

  7 零散的储存密码

  8 一般的问题:安全软件培训和教育,降低攻击动机。

  教学材料的改进和添加,特别是我们需要警告开发人员在内存缓存系统中的潜在的安全问题,在使用C,C++, 或是Objective-C;现在经常用的。当然真是的问题是开发人员学习使用安全软件,尽管几乎所有的程序都在受到攻击。

  现在让我们来谈谈SSL/TLS的实现。在短时间内,我认为FLOSS项目的建立是建立在一个全面的SSL/TLS回归测试套件,使用以下的技术:

  该套件要使用彻底的negative测试,它当然要有测试选项。

  这将会是最好的,如果这个测试套件使用了很长的时间可以达到100%的分支覆盖,以为测试使用了多个实现方法,可以帮助检测缺失的错误输入和错误处理。

  使用带地址检测和标准内存分配器的fuzz和传统的negative测试结合的方法会更好,fuzz测试可以发现许多的安全漏洞,但是传统的fuzz测试就很肤浅,并且测试效果有限,如果他们自然的应用密码协议。结合了fuzz测试和传统测试可以取得更大的进步,在协议上可以做到比单纯的fuzz测试更有效的测试。一个完全的测试工具应该可以测试到细微的错误状态。

  像这样的测试套件可用多种实现方式协议来实现,但是我认为要使用SSL/TLS开始。最近,在很多的SSL/TLS的运行中发现了很多的漏洞,所有这些都可以通过negative测试来实现。如果任何加密库有漏洞,在其他保护下可以泄露数据。这个测试套件可以重启所有的SSL/TLS项目,在任何一个开发人员做出任何的改变,在他们在用户的电脑上显示很长时间以前消除他们。这个套件可以用于潜在的用户和政府,如果使用验证,可以提高供应商额外的测试来添加下一个版本。一个常见的测试套件将使我们更有信心在所有的SSL/TLS中,在开始点这些测试套件会很有用,在开始的地方便的很容易。它还有资金的优势;如果你不知道你是否支持OpenSSL,LibreSSL叉,或是其他的,这不重要-这个套件可以帮助大家。个别的项目要继续使用自己的测试套件,但是显然现在的测试套件是不够的。这也可以扩展到其他的加密协议,依赖一中技术来测试漏洞是不坏注意,包括创建一个共同的严格测试套件;我们要更多的套件才行。但是这可以说是一个好的开始。

  更广泛的说,项目需要检查心脏出血的漏洞以及其他的漏洞,并且要确定他们是有效的。他们也需要检查一个项目,在这个项目做的很好时,来看使用寿命方法来复制。

  这没有更好的办法。然而,这需要更重要的课程学习,要积极的使用套件才能是类似心脏出血漏洞不再发生。

------分隔线----------------------------

推荐内容