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

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

时间:2014-07-25 13:24来源:TuZhiJiaMi企业信息安全专家 点击:
一、引言 基于OpenSSL的心脏出血漏洞被认为是CVE-2014-0160的严重问题,OpenSSL被广泛的应用于SSL和TLS插件上。本文用对心脏出血漏洞的解释来说明这个漏洞是怎么被利用的。 本文中研究了抗心脏出
Tags漏洞(188)应用安全(1006)心脏出血(8)  

  一、引言

  基于OpenSSL的心脏出血漏洞被认为是CVE-2014-0160的严重问题,OpenSSL被广泛的应用于SSL和TLS插件上。本文用对心脏出血漏洞的解释来说明这个漏洞是怎么被利用的。

  本文中研究了抗心脏出血漏洞及其相似漏洞的专用工具和技术。我首先通过简单的测试来分析为什么很多的工具和技术不能发现这些漏洞,这样可以使我们更能了解到为什么之前的技术不能发现这些漏洞。我还要概括总结要点来减少这些的问题。本文不介绍如何编写安全软件,你可以从我的书《Secure Programming for Linux and Unix HOWTO 》或是其他的著作中学习到这点,本文中认为您能开发软件。

  我的目的是为了帮助防止类似漏洞的出现,从而提高安全软件的开发能力。正如Orson Scott Card’s Ender’s Game中的虚幻人物Mazer Rackham所说的“这里没有老师,只有敌人…只有在敌人那里你才能了解到自己的弱点。”让我们来了解这些漏洞,然后可以避免相似的漏洞再次出现。

  二、为什么这个漏洞不能更早的被发现?

  这个OpenSSL漏洞是由一个很熟悉的问题引起的,这个关键的问题就是缓冲区读溢出,由于不正确的输入导致。这些都是很常见的问题,很多的工具是专门用来查找这方面的问题,会使用很多工具对OpenSSL进行定期检查。

  Kupsch和Miller专门查找了心脏出血漏洞,在这个漏洞被发现之前,使用了很多的方法也没有发现这个漏洞,虽然很多人和工具都用来查找类似的漏洞。他们进一步认识到“心脏出血漏洞对当前的辅助软件提出了重大的挑战,而且我们不知道是否有工具能在这个漏洞被发现之前被使用。”我会强调一些其它的问题和我自己的一些观点。

  2.1 静态分析

  在没有执行这个程序时的静态分析。

  最常用来寻找漏洞的静态分析工具是source code weakness analyzers,source code security analyzers, static application security testing,static analysis code scanners 和 code weakness analysis tools。每个源代码分析工具是通过使用类型匹配的方法来寻找漏洞的。有很多的报告可以评估这些工具。

  然而,在之前的时间里使用静态分析工具没有发现这个漏洞:

  1、Coverity:Coverity没能在心脏出血漏洞公布之前发现这个漏洞。他们正在通过努力来提高他们的工具的质量,从而在将来能够发现相似的漏洞,使用了一些有趣的新启发方法。

  2、HP/Fortify: HP/Fortify已经公布了一些心脏出血漏洞的描述,但是我没有任何的证明能说明他们的静态分析工具在漏洞公布前就发现了这个漏洞,在漏洞被公布后,他们确实是更改了他们的动态测试软件包,但是和之前的不同。在专门讨论这个问题时,他们没有证据让我相信他们的工具真的在心脏出血漏洞被公布之前就发现了这个漏洞。

  3、Klocwork: Klocwork在正常的配置下没有能够侦测到这个漏洞。

  4、Grammatech: Grammatech 的CodeSonar同样没有侦测到这个漏洞。他们也是通过实验来提升能力,以便在以后能够发现相似的漏洞。

  最主要的争议就是这些工具都不能保证能够发现所有的漏洞,甚至不能保证发现特定类型的漏洞。很糟糕的是这些术语很混乱,所以我们首先要搞清这些术语的意思。

  本文中在分析软件时,使用的工具不能找到所有的漏洞,但是我找到了这个分析软件的不足。在以前的文章中,很多人使用unsound来描述那些不能找到所有漏洞的来查找漏洞的工具。例如Bessey等人在分析Coverity的静态分析工具,并且说:“像PREfix产品,我们也使用unsound。”我们的产品并没有证明说这是没有错误的,而是尽我们的能力来发现这些问题。这项研究工作中存在很大的争议,虽然它几乎已经成为商业软件和研究项目的实际工具基础。一个unsound术语会导致混乱,因为人们使用program checkers,它使用术语unsound来代替不同的意思。在一个博客上解释了为什么相同术语会有两种相互矛盾意思。“大多数的program checkers来证明定律的程序。特别情况下,主要的目的是在某个方面来证明程序的正确性。一个定律的证明是来证明这个定律的正确与否…人民在程序检查过程中习惯了使用这种做法,所以他们没有考虑bug的存在。但是一个bug的发现者不是要证明这个程序是不对的,而是用来证明有bug存在,使得他们报告了发现的bugs,它们就都变成了真正的bug,如果没有错误,将会忽略bug,因为他们不能证明是否正确。”

  本文中我使用了NIST SAMATE SATE V Ockham Sound Analysis标准来消除混乱,在NIST SAMATE用语中,工具是不能发现所有漏洞的,从而证明程序是不完备的。下面来说明NIST是怎么区分程序的可靠性和完整性:“一个网站的代码可能会出问题,一个有bug的网站会有一系列问题,这就是说一些输入会导致问题。一个没有bug的网站不会出现一些列问题,就是说它是安全的或是没有漏洞的…这些可以从一个网站的报告中得知。或者说,一个网站有特殊的问题或是一个网站没有问题…可靠就意味着每一个发现都是正确的。没有必要使用工具产生每个网站的报告;这是完整的。”

  为什么那么多的源代码分析工具是不完整的?首先,大多数的程序语言不是很容易能被分析的。其次,大多数的软件使用静态分析工具来分析也是很不简单的。最后,完整的分析工具要求更多的人来应用在程序上。相反,不完整的分析工具能够立刻应用到程序上。他们成功的使用启发的方法来鉴定漏洞和在有限的时间里来完善分析。但是,这里会有重要的警告:不完整的代码分析工具常常会漏掉漏洞。

  心脏出血漏洞是一个鲜明的使用不完全的启发方法不能发现的重要漏洞的例子,不能发现这个重要漏洞的最主要原因就是OpenSSL代码很复杂;多个层次的间接寻址和超出了工具的分析能力,从而不能发现漏洞。局限性和深层次存在的原因是C, C++和Objective-C都很难使用静态分析;像指针更难使用静态管理。这并不是意味着静态分析工具就是没用的,静态分析工具能够测试软件在大量的输入后的表现,工具的启发原理会限制错误报告的出现次数。但是更重要的是不完整的静态分析工具使用了启发原理后,在分析大的漏洞时会出现错误。

  2.2 动态分析

  动态方法就是使用特定的输入来运行一个程序并试着发现漏洞。

  动态分析局限性是它不能使用时间表来测试任何程序。如在一个琐碎的程序中加入了64bit的整数,会有2128种可能的输入,测试这些输入就要使用13.5十万亿亿年的时间。甚至大规模的并行计算也不能解决这个问题。现实中的程序要比这复杂的多,因此动态方法不能体现一个程序的安全性;他们只能显示在测试中存在漏洞。

  但是这并是意味着动态方法就是没有用的。动态方法在提升安全性上是很有用的,但是要了解到他们的局限。

  让我们来分析我们广泛使用的两种方法,但是不能发现心脏出血漏洞: mostly-positive测试和fuzzers。

  2.2.1 mostly-positive自动测试套件

  一个方法是开发一个强大的自动化测试套件。Eric S. Raymond和一些其他人在研究心脏出血漏洞时,他的表述为:“我认为很多人都认为这个测试套件不能很好的工作…我以前学到了尽量去推进传统方法来完成你不能达到的程度。”我同意他的观点,一个好的自动化测试套件是很强大的,特别是应用于非安全性缺陷时。如果你没有或是开发一个,就完全的停止,我们表示同意。

  但是,测试套件能否发现心脏出血漏洞要依靠你是怎么开发的这个套件。很多的开发人员都开发了测试套件,这个套件主要是我说的“mostly-positive”测试套件,它可能不能发现心脏出血漏洞。后面我将会讨论negative测试,这种测试方法可能会有作用,但是我们要知道为什么一般的测试方法不能做到。

  很多的开发者和组织者专门测试了正确的输入时会发生什么。当你这样思考时就更有意义;一般的使用者都会抱怨在正确的输入时是否会没有正确的输出,并且大多数的使用者不会测试在不正确的输入时程序会有什么结果。如果你的目的是很快的分辨出问题,在大多数的情况下,在正确的输入时人们会努力控制能够预测的错误条件。很多的开发人员不能思考到当入侵者发送精心设计的输入来利用程序时会发生什么。

  我会使用mostly-positive测试套件的方法来测试在正确的输入时会发生什么。不幸运的是,在很大程度上,今天的软件入侵测试套件都是mostly-positive。都在关注开发mostly-positive测试套件的测试。

  1、Test-driven development(TTD)是一个软件开发过程,“开发者写了一个自动测试工具来提升和增加新的功能,之后使用最少数量的代码来通过测试,和最终生成新的代码的接受标准。”通常情况下这些测试是用描述一个新功能要做什么,而不是他们不能做什么。

  2、当很多的标准链接在一起,交互式测试就会决定他们是否能够链接和分享数据。交互式测试能够很好的帮助开发者来提高一个协议标准。但是其他的实施方法也能遵守这个规则,其他的实施方法不能够完成“什么不发生”的测试。

  mostly-positive测试实际上对于安全软件来说是没有用的。mostly-positive测试一般不能测试正确的事物。对于心脏出血攻击和其他的攻击,攻击者发送数据用不是平时用的格式。TTD和交互式测试都是好工具…但是你需要加强他们来改善安全软件。

  代码覆盖工具对漏洞的发现没有任何的帮助。一个开发者可能会运行代码覆盖工具来看下哪些程序没有被测试,之后增加测试来达到大部分的代码被测试。当测试套件测试了80%-90%的代码时,很多人会很高兴;一般很少会达到100%的覆盖。测试覆盖工具有某种安全价值,例如,他们有时能够侦测到等待出发者的恶意软件,他们也能够核查是否有特别的程序能够正确的运行。但是使用典型的代码覆盖工具测试到100%的覆盖,不能对抗心脏出血漏洞。心脏出血漏洞缺少恰当的输入验证。基本上,一个代码覆盖工具不能注意到丢失的代码;只能注意到没有测试的代码。

  我要说在OpenSSL里也不会有例外出现,又如在苹果的iOS设备上运行SSL/TLS得到了错误的结果时,也能通过mostly-positive来证实它的测试。在这个漏洞中,SSL/TLS库接受了有效的证明。然而,没有人验证这个库能拒绝某些无用的验证。如果你只是测试是否有效的数据会产生有效的结果,你就不能发现安全漏洞,因为大多数的攻击都是在基于程序没有准备好的时候输入。

  如果你开发的套件能使用我在下面描述的方法,你能够通过一个好的测试套件来发现这个漏洞。首先,让我们来研究fuzzing。

  2.2.2 Fuzzers 和fuzz测试

  Fuzz测试是一个随机输入,之后发送到程序测试去看是否出现不渴望的过程。进行fuzz测试的软件叫Fuzzers。

  Fuzz测试同传统的测试不同,在传统的测试过程中,你会有一个给定的输入组,并且你知道每个输入对应的输出情况。传统测试会随着测试数据的增加而变得更复杂,因为你要预测渴望的输出结果。决定输出想要的输出结果是一个Oracle机制。使用一个Oracle的数据作为输入的问题被叫做Oracle problem。

  Fuzz测试处理不同的Oracle problem,因为它只是在试图侦探能使程序崩溃的问题。这就是使它在Fuzz测试中输入更多的测试数据,即使输出测试更不准确。Fuzzing测试方法是1988年Barton Miller在University of Wisconsin开发的。在http://pages.cs.wisc.edu/~bart/fuzz/ 上有更多的有关fuzz测试的信息。

  Fuzzers经常用来发现安全漏洞,因为他们能够测试大量不可想象的输入。特别是,Fuzzers常用来发现输入验证的问题,心脏出血漏洞就是在输入验证错误的基础上产生的。但是典型的Fuzzers不能发现心脏出血漏洞,因为:

  1、心脏出血漏洞是由于缓冲区读入溢出,而不是缓冲区写入溢出的漏洞。大多数的Fuzzers只是发送大量的数据和寻找程序的崩溃。但是,当缓冲区写入溢出常常会导致崩溃,缓冲区写入溢出在正常的环境里是不会崩溃的。在Fuzzing过程中,甚至会使用一些对策来解决写入溢出,而不是读入溢出,如canary-based保护方法和非执行堆栈。可靠性不是很大的问题,因为存在方法是出入溢出导致崩溃,或使用其他的测试工具来测试…这会给我们带来第二个问题。

  2、OpenSSL包括它的内存分配路径,并且除非使用特别的调试方法,不然我们会经常使用他们。更糟糕的是这些特别的方法不能正常工作。特别是,OpenSSL使用它自身的应用程序管理缓存来提高性能时,而不是简单的依靠内存管理路径。这种应用程序管理缓存可以阻止许多典型的缓存例程,包括测试工具如electric fence、valgrind和address sanitizer。这就意味着使用fuzz测试来测试缓存的路径问题时,测试会忽略一些特殊的情况。

  因为加密技术能在很大程度上减少fuzz测试的无效性,除非fuzzer有密码和专门用来袭击的密码库。有一些fuzzing不能在OpenSSL和一些密码库下严格执行的推测应该是正确的,然而,没有什么能阻止密码被fuzzers获取。除此之外,心脏出血漏洞甚至在没有密码的情况下被发现。因此,就是在读出溢出和OpenSSL使用自身的内存缓存分配路径的联合使用时,使fuzzing变的无效。

  三、用什么来对抗类似心脏出血的漏洞?

  这里有部分在先前可以对抗心脏出血漏洞的软件和工具,我会特别的介绍一些好用并且免费的自由开源、源代码软件。

  首先是一些说明:

  不要只用一种工具或一种技术来开发安全软件。开发安全软件要集合很多的方法,最开始要知道怎么开发安全软件。大多数的组织最初是使用简洁清晰的方法来开发安全软件,启用和注意编辑器的警告标志,使用源代码弱点分析工具,让多人进行研究,运行fuzzers,使用大量的自动入侵工具套件。如果你只是使用一种技术,你只能对抗上一次攻击而不是这次。例如,会大量的忽略掉警告标志,即使是警告标志不能发现心脏出血。那就是说,当攻击成功时,最重要的是怎么完善软件,攻击者可能如使用一样的方法来入侵软件。更好的改进也能对抗其他的攻击。

  这不存在一种类型的工具和技术的列表,不同的工具有不同的用途。可以在[BAH2009 ] [ NIST ]上了解更多关于各个类型的工具和技术。我创建了这个特别的列表,但是我要尽量清楚我的意思。

  先前没有一个明确和完整的用来发现心脏出血漏洞的工具和技术的列表,我很想做一个,我希望得到更好的建议。

  以上是一些说明,先前是什么在对抗这个漏洞的,为了完成这个,我已经大致的完成了这个列表,用最简单的方式介绍他们。这是最粗略的,会有一些问题;欢迎来改进。使用更多的方法来对抗其他类似漏洞,不只是心脏出血。使用动态和静态分析法来识别在括号里的副标题。

  3.1 使用negative测试(动态分析)

  negative测试会得到错误的结果。例如,对于一个设置了密码的系统来说,在知道有效的用户名和密码时,要通过很多次的回归测试才能登录成果。negative测试会显示很多无用的用户名和密码,其他的无效的输入会阻止用户登录。

  通过negative测试方法创建了一系列的使用错误输入的测试。我指的是每个类型的输入,因为不能测试每一个输入,在动态测试中能得到解释。在回归测试工件中要包含无效数值来测试每一个输入,每个状态/协议转换,每个使用说明书等等。这就会立刻发现心脏出血漏洞,因为心脏出血漏洞包含一个不正确数据的长数值。这也会发现其他类似CVE-2014-1266的错误,如在苹果iOS上使用SSL/TLS会得到的错误。在CVE-2014-1266中,iOS存在接受无效认证的问题。很多的测试中存在有效的认证…但是,没有足够的测试来测试无效的认证。

  在大多数情况下只有negative测试对安全还有点用途,之前,我注意到重要的是如何创建测试套件。对于阅读本文来说是明显的,特别是,当我怀疑Eric S. Raymond在讨论测试的优势时使用这些类型的测试。但是这对于软件的开发者来说是明显的,大多数的开发者和组织者都是在使用mostly-positive test套件。很多的开发者很难像攻击者一样的思考,只是错误的通过广泛的测试不可能发现的原因。

  通过negative测试的就是起初的半自动的过程,您可以开发出可以执行计算机可处理的规范,并生成大量测试结果的工具…之后看看是否可以控制它。

  另一个使用negative测试的重要条件就是是否有一个标准,可能合作开发一个独立的普通测试工件作为FLOSS项目。之后可以通过快速测试所有当前和以后要执行的方法,并且阻止使用者遇到问题。我强烈的推荐使用SSL/TLS协议开发一般目的测试工件;不然会减少效果,这会增加应用的安全性。单独的应用也需要使用附加测试来补充单一测试,但是一般的大测试套件是很有用的。

  软件测试是一个完整的领域。存在着不同类型的测试方法和测试范围标准。我只能在本文中总结测试。更一般的信息可以看下Paul Ammann and Jeff Offutt 的Introduction to Software Testing。但是要理解这个:只用使用有效的输入来测试来发现这多的问题,如心脏出血漏洞。

  我不知道在整个negative测试中依靠什么,或是其他什么单独的技术,对于安全来说。动态的方法很自然,在真实输入空间只能测试一个微不足道的部分。但是这种方法很容易发现安全漏洞。

  3.2 地址核对和标准内存分配在fuzzing

  不幸运的是一般的fuzz测试方法在这种情况下是不能很好使用,但是我们可以学习简单的过程。如果可以使fuzzing对一系列的地址进行有效果的、容易的核对和使用。这种类型的工具能侦测到在执行过程中读溢出和加写溢出,并且常常发现其他的存储问题。

  许多的工具能够完成对地址的核对;每一种工具都有两面性。但是,如果你没有使用其他的什么工具,我强烈的建议你尝试下address sanitizer。

  address sanitizer简单有效;它只是一个在LLVM/clang和gcc中建立的附加的标志。address sanitizer没有什么神奇的;它只是擅长侦测缓冲区的读写溢出问题,释放后使用或是双重释放。它也能侦测到use-after-return和存储泄漏。它不能发现所有的存储问题,但是这是一个很好的工具。它的表现超出平均的73%,使用2x-4x的存储。这种表现一般和测试环境是无关,在侦测这些问题时它很少被提到,在测试过程中Chromium和Firefox网页浏览器都使用的address sanitizer。要了解更多可以去看USENIX 2012或是address sanitizer网页。

  还有其他的工具能够侦测内存的使用和分配地址的问题。很多人使用guard pages来检测读和写在缓存。Valgrind被广泛使用和广受欢迎;valgrind在检测内存时能发现很多的问题包括在堆栈中读溢出。另一个广泛使用的工具是electric fence。在运行不同的fuzzer时可以使用不同的工具。

  一般情况下,使用fuzz测试时你必须打开你能打开的所有的探测设备。第一个fuzzer侦测时使用这种机制“没有改变的程序崩溃或是死掉?”并且很多的fuzzer还只能做这个。你必须要加强程序的访问,并且要开发尽可能多的访问。你可以增加额外的核对来确保中间和最终程序语句的正确。要不是心脏出血漏洞的出现,你至少应该打开无效的内存访问探测器,如address sanitizer。

  许多的工具包括address sanitizer和基于程序的guard page,要求这些程序具有测试正常分配和释放内存的能力。特别是,程序没有必要使用符合分派准测的机制。至少,这个程序应该可以轻松地使用正常分配方法用于fuzz测试。

  一个相对的方法是concolic测试,CREST就是一个基于C的concolic测试的自动测试过程工具。但是CREST目前只能用于象征性为线性整数的运算,所以它能在这种情况下工作。更一般的是现在的concolic测试工具不可能发现心脏出血漏洞。如果哪个人说他确认concolic测试发现了心脏出血漏洞,请让我知道。

  大家一直都在为fuzzers是否比negative测试复杂而争论不休,但是这只是我的推理。negative测试的一个优点是它很容易入手;假设你已经有了一个测试套件,你就可以开始negative测试。更重要的是negative测试能快速给出一个模糊导致问题的答案,他们要求计算能力很少的开发者使用每一种方法来获得重复测试套件。相反,fuzz测试要求更好的计算能力和对结果的解释;计算能力不算什么,这会影响到对开发者的反馈速度。一个潜在的更快negative测试的反馈能够是开发者更快的实现检测和修复;今天最大的问题就是开发者的时间,而不是计算时间;一个最好的机制能减少开发过程的复杂度。你也可以在某个特定的协议下,使用negative测试套件;你能够在每个测试设备和实施方法中轻松的重新使用测试套件。当然,这不存在什么冲突;最好使用fuzz测试和negative测试两种方法。

  3.3 编辑内存分配标准和使用address guard或是sanitizer

  如果在对抗来自潜在的漏洞攻击,在未知的环境里你现在就要使用一个程序怎么办呢?

  一个方法就是使用侦测在分配的内存的最后区域来实现读的机制,但是使用这种方法你不能改变测试怎么运行;这个观点就是你实际上用的在一个分配要求下的多重分配机制。

  存在运行时间侦测漏洞的多种机制;这就是一些例子:

  1、Address sanitizer。你要重复调试一个程序时可以使用它。在LLVM/clang和gcc编辑器上Address sanitizer就是一个标志,这相对与C程序的软件简单的多,这占了平均运行的73%,和2x-4x的存储。这不是你想只能手机上做的,很多繁忙的网站不欢迎这些。现在的计算机比过去的有更好的能力和存储,一些环境中就会被接受…这就是你能够立刻对抗未知攻击的可能性。Address sanitizer在侦测一长系列潜在问题上很有作用,包括大量无效的缓冲区访问。Address sanitize不是在所有的编辑器里都无效;这要在其他的如C, C++, 和Objective-C编辑器中来添加它。

  2、Intel Memory Protection Extensions。MPX新增了叫边界寄存器的寄存器来控制指针的边界,使用新的指令来运行和使用边界。MPX使用Skylake架构,但是在2014年这些CPU不能和公众见面。这要更长的时间被广泛的得到使用,那不能组成non-Intel系统。

  3、内存分配保护页面。一些系统内存分配能够在分配一个用来组织读和写的内存后,添加一个未定的保护页面。这些能否会禁止和阻止心脏出血漏洞,这些取决于它是如何实施的。OpenBSD的malloc的实施支持保护界面。在OpenBSD中,G选项会导致“使用保护页面后的每个页面分配到的数据大小过大,这些会导致访问错误。”这会与P选项进行组合来移动一个页面内的分配。OpenBSD机制可以启动特定的程序,甚至是特定的默认情况下,在整个系统中启动,这样就可以在更多的环境下得到保护。OpenBSD的malloc机制有一个弱点:即使开启G和P两个启动项,少量的分配不会立刻完成保护页面。如果OpenBSD的保护界面机制能够在较少量的分配后立刻插入一个保护页面,我认为会更好,即使这可能会对速度和内存大小有很大的影响。但是即使是这样,开启G和P就意味着所有大于半页的分配会立刻跟随一个保护页面,并且分配一个半页或是更少将会泄漏半页。这就会明显的减少泄漏规模,相比于原来心脏出血漏洞攻击时泄露的64K。内存分配必须要对齐,所以保护页面可能泄漏一些字节的信息,这就取决于如何实施的。我怀疑Address sanitizer要比增加保护页面的分配快,但是添加保护页面不要求更多的程序来进行重新编译,这就是它的优势。不幸运的是GUN的libc中malloc不能有附加的这些功能。

  当然,这种方法假设你有一个能启动(1)的内存保护机制和(2)内存保护机制也会在这种机制下工作。很多的机制可以对抗缓存写溢出,不是缓存读溢出,心脏出血漏洞就利用了读溢出。例如:GUN的libc中的malloc()可以选择MALLOC_CHECK_。这就是防止写溢出的方法,但是我不认为它能对抗类似心脏出血的读溢出。同样,Dmalloc’s fence-post检测“在程序从这个区域中读取时不能注意到,只有在写入时才会有通知。”我觉得GUN的libc和一些类似的运行过程中也要增加类似OpenBSD的malloc的保护页面机制,从而对抗读溢出。

  这是一个可以减少伤害的方法,而不是一个消除个问题的办法。从安全的角度来看这种方法把缺少保密变成了缺少实用。然而在很多的情况下这是一个很好的协议。一旦受到攻击,这个方法就会使问题变成可视化的,一旦问题可视化后就变的很好改正了。

  这个方法很容易和honeypot或honeynet联系在一起。在honeypot或honeynet系统上设置这些硬化的方法。如果攻击者试图破坏软件,这个软件不会崩溃,并且会记录下攻击者的重要日志和追踪记录。Forensics就会侦测到一些专门利用一日0攻击。我认为通过一些日志记录结合入侵侦测系统来进行追踪;在硬化密码库中发生了崩溃,就会特意的记录下。这就会使普遍的侦测利用一日0攻击更加的容易。分布核心基础设施组织和在互联网上其他组织都可以建立这些类保护我们。

  虽然这种方法并不能完全解决这个问题,但是他能提供一个有力的缓解功能。一些发行者或组织可能需要在特定情况下使用这些措施,或至少使这些措施变得更容易。

  修改代码不会很复杂,并且重新编译也是很简单的。不过,在很多的设备上性能的欠佳都体现的很显著,可能是你失去了硬件后的性能。特别是在使用Address sanitizer时,你会失去一半的速度。因此,我指望使用这种复杂的解决方法,就要考虑到硬件的消耗。在很多的情况下,会影响到运行,在智能手机上就会降低运行速度和电池的寿命,对于当前流行的服务器的话,也会减慢反应速度和增加电量的消耗。如果将来的CPU能支持Address sanitizer,对速度的影响就会显著的降低了。我希望CPU制造商能考虑下这点。

  3.4 关注各个领域的手动检测验证

  漏洞的代码是人为审查的,显然只有一个人来审查是不行的。

  然而,大量的工作就要有专门的人来检查每个领域,为确保得到有效的验证,有时会在计算机安全中得到一个不好的名字。我怀疑的原因之一就是有时候,那些部署清单的人在做什么,之后也不能很好的利用它。但是出色的飞行员经常使用仪表盘,他们知道是做什么的。如果补丁是他们使用清单上工具后的唯一成果,“必须证明每一个不可信的数据字段进行验证,”之后这个漏洞被反击。

  列入人为检查/审计的一部分,和一些简单的方法不同。然而,这确实要就检测人能了解所有的补丁,它不能依靠以前的代码来得到帮助。

  3.5 对文件包括注解系统的配置源代码的弱点分析

  传统的源代码弱点分析是找不到心脏出血漏洞,因为他们使用的是通用的启发式方法,代码复杂,在这种情况下不能很好的起到作用。它总是你能看到的最简洁的代码,但是基于你要完成的任务总是会有一些复杂性,真实情况下人类是不能达到完美的简约。Coverity公司正在开发一些新的,他们认为能够检测到心脏出血漏洞的启发方法…并且对他们是有好处的。至少有一个人已经使用了类似的启发方式。事实上,我希望所有的代码分析工具都能得到改善,从而发现他们以前不能发现的漏洞。但通用的启发方式在某个特定的时间点只能达到这个程度,你能做的更好吗?

  回答是肯定的,它叫做为上下文配置的源代码弱点分析工具。基本思想是,你开始使用一个恶源代码弱点分析工具,之后你在提供更多的你要分析的程序的信息。这种方法比仅仅运行源代码弱点分析工具需要更多的时间,而这些额外的信息通常要和一个特定的工具联系在一起。然而,提供你需要的程序的信息,源代码弱点分析工具可以能更好的工作。

  Klocwork已经表示这种方法对心脏出血漏洞是很有效的。

  现在让我们来谈谈注释系统。在很多的地方来为静态分析工具提供这种额外的信息。一个常用的方法就是对程序添加额外的注释机制,在修改程序时会使用他们。这些注解可能在更改的代码中进行添加,添加在注释中,或是加在单独的文件里。使用C的工具或是注解包括Microsoft’s SAL、splint、Deputy、Oink/CQual++、cqual、和Frama-C ANSI/ISO C。你可以很容易得出添加这些信息确实是一个不同的技术。

  认真的使用这些额外的注解来对抗漏洞就要有很大的工作量,如果从现存的代码来说。对于C来说存在许多不同的不兼容的注释系统。对于他们来说是没有什么标准的,这会进一步的阻碍他们的使用。毕竟,它需要添加注释和这些注释会把你锁到一个特定的工具中;Microsoft SAL会有更多的问题,没有FLOSS的应用和这只能在Windows上使用。我认为如果针对每个主要的编程语言包括C在内,任何一种单一被广泛接受的标准注释符号,注释系统将会更加广泛的应用。当没有这么个符号时,像C语言等语言就会很难得到那样一个协议。Peter Gutmann已经写了一些他的经历。

  但是,注解系统是由一些好处的,注解系统能够发现简单的漏洞,不用在转变成不同的语言。他们也很少去转变成不同的语言,当然,这并不冲突;你可以切换语言,使用一种新的语言在注释系统中。

------分隔线----------------------------
  • 上一篇:没有了
  • 下一篇:没有了

推荐内容