自从软件诞生起,软件的安全性一直就是每一个程序员不可回避的问题。面对“如何开发出具有高安全性软件”与“如何利用软件漏洞进行攻击”,安全防护人员和黑客,就像中国武侠中的白道高手与黑道高手一样,在相互的较量中提升自己的功力。随着计算机语言的不断进化和互联网时代的到来,软件所面临的安全性问题也在发生着巨大改变。如果将最初的单机病毒攻击成为软件安全的第一纪,网络攻击称为第二纪的话,那我们现在正处在软件安全的第三纪 -- 应用攻击。Gartner 的数据显示,75% 的黑客攻击发生在应用层。而来自 NIST 的数据更为惊人,有 92% 被发现的漏洞属于应用层而不是网络。
图 1. 来自 Gartner 和 NIST 的数据
在这些软件安全问题中,由于没有在软件设计和开发的过程中引入安全开发和测试的情况占了很大比例。其实,从 1968 年软件工程诞生以来,人们一直企图在软件开发生命周期(SDLC)中引入安全开发的理念和方法,并由此出现了安全开发生命周期(Secure Development Lifecycle)。在本文中,我们就将结合示例来讨论一下如何能够在软件开发生命周期中进行软件安全开发和测试的问题。
图 2. 安全开发生命周期示意图#p#
软件安全的“闻问望切”—基于黑盒的渗透测试
无论是在传统的瀑布模型开发还是在方兴未艾的敏捷软件开发中,软件测试都是重中之重。基于黑盒的渗透测试,是一种有效地将软件安全性测试引入软件开发生命周期(SDLC)中的方法。目前,许多软件厂商都有针对各自技术研发出的渗透测试产品,如 IBM 的 AppScan、HP 的 WebInspect 等。说到渗透测试,就不能不提到由 Barton Miller 和 Lars Frederickson 等人在 1990 年提出的 Fuzz 技术。传说在 1989 年一个雷电交加的夜晚,Barton Miller 用 Modem 连接自己的主机时,一个闪电过后,电路中的高低位互换了,Miller 由此想到了利用“crash、break、destroy”的方式来进行软件测试的技术——fuzz。著名的 Fuzz 工具有 Fuzzing 网络协议的 SPIKE、大桃子 Peach等等。Fuzz 技术自上世纪 90 年代初期起,慢慢的广泛应用于系统平台测试,应用软件测试和网络安全测试中。
下面我们将展示如何针对一个 Web 应用进行基于安全漏洞检测的渗透测试。在这里我们选用 IBM Rational AppScan Standard Edition V7.8 (以下简称 AppScan)作为测试工具。
首先,我们在 AppScan 里建立一个新的扫描。AppScan 提供了许多预定义的扫描模板来帮助工程师建立针对不同 Web 应用和 Web Service 的扫描。
图 3. 用 Rational AppScan 模板创建扫描
在这个示例中,我们将对架设在笔者本地的 Tomcat V5.5 服务器上一个名为 AltoroMutual 的电子商务系统进行安全渗透测试。
图 4. 扫描 URL 配置
完成指定扫描的起始 URL 后,我们将一个拥有普通用户权限的用户名和密码输入到 AppScan 的自动登录选项中。AppScan 还支持通过录制并在测试时播放的方式进行登录。
图 5. AppScan 扫描登录配置#p#
在 AppScan 中,测试策略的选择会对不同的 Web 应用和 Web Service 产生影响。在本示例中我们仅选择了针对 Web 应用和 Tomcat 应用服务器的具体中高漏洞等级的自定义测试策略。其实当我们打开每一个具体的测试策略时,会发现 AppScan 在其中定义了包括针对 Java、.NET、PHP 等不同类型网站测试类型种类和相应安全问题严重程度的级别。
图 6. AppScan 安全测试策略配置
图 7. AppScan 安全测试策略的详细内容
通过设置 URL 入口、登陆方式和测试策略,AppScan 可以快速完成 Web 应用扫描的配置,从而开始漏洞检测。其实,除了上述几种设置,我们在图 7 左侧还可以发现更为完善的测试配置项,比如对参数和 Cookie 的设置,对扫描访问的 URL 深度和广度进行配置,对需要填充的表单如何填写等等。
图 8. 进行扫描中与发现的部分安全问题
AppScan 的扫描分为二部分,首先是进行探索,将发现的 URL 进行记录;其次进入实际的测试步骤,将利用之前我们设定的测试策略进行渗透测试。下图是 AltoroMutual 应用经过 AppScan 黑盒测试发现的部分安全问题。在 AppScan 主窗口左上方显示的 AltoroMutual 被扫描出的网站 URL 结构图,每个 URL 上发现的安全漏洞被标注在该 URL 后。左下方的仪表板显示了安全问题的汇总,由于我们设定只针对中高级别的安全问题进行显示,所以 Low Level、Info Level 的问题数量为 0。右上方将扫描出安全问题的种类和相应的 URL 一一罗列出来,而在其下方是每一个安全问题的详细描述、修复建议和问题复现。
图 9. AppScan 扫描完成后的主窗体#p#
一般来讲,基于黑盒的渗透测试具有较高的测试准确率,但是我们依旧需要对扫描出的安全问题进行分析和甄别,从而给出合理的安全级别和修复建议。在本例中,我们具体分析一下 AltoroMutual 应用中存在的跨站脚本攻击(XSS)问题。
点击存在 XSS 问题的 URL“http:// www.2cto.com /altoromutual/sendFeedback”中“name”,可以看到产生这个 XSS 问题的详细信息,我们通过查看“请求 / 响应”来对该漏洞进行复现和判断其严重程度。点击“请求 / 响应”的标签后,我们发现 AppScan 发送了如下的内容给 AltoroMutual。利用将“1234>%22%27><img%20src%3d%22javascript:alert(14404)%22>”插入到 cfile=comments.txt&name 后,实施 XSS 攻击。
图 10. AppScan 向服务器端发送的带有跨站脚本攻击的数据
通过点击“在浏览器中显示”的方式,我们可以得以在 AppScan 内嵌浏览器中将这个跨站脚本攻击问题复现。
图 11. 在 AppScan 内置浏览器中进行 XSS 问题复现
通过上面的扫描示例我们不难看出,基于黑盒的渗透测试确是有较为高的准确率。在软件开发生命周期中,渗透测试可以帮助测试人员、QA 人员在 FVT、UAT 等阶段发现软件安全问题。
但是,渗透测试的全面性和覆盖率一直都是困扰着众多软件安全测试人员的问题。而且对于开发人员来说,他们更为关心如何能够在软件开发的早期阶段就能引入安全性的分析,让他们能够根据漏洞分析的提示,尽可能早地将安全问题 Fix 在开发阶段,这就引入了基于白盒的源代码安全分析。
如果把检测软件漏洞比作去医院看病,那渗透测试就如同中医的“闻问望切”一般,通过给软件把脉,将病例病因一一道来。而基于白盒的源代码分析,更像是西医的内观外治,先做完 X 片、B 超,然后对症下药。
其实长久以来,基于黑盒的渗透测试和基于白盒的源代码分析到底谁更为有效的问题一直争论不下,以至于还有了灰盒测试(Gray Box)的出现。接下来就让我们一起通过示例看看白盒黑盒孰优孰劣。#p#
给软件拍一张 X 光片—基于白盒的源代码分析
源代码分析技术由来已久,Colorado 大学的 Lloyd D. Fosdick 和 Leon J. Osterweil 1976 年的 9 月曾在 ACM Computing Surveys 上发表了著名的 Data Flow Analysis in Software Reliability,其中就提到了数据流分析、状态机系统、边界检测、数据类型验证、控制流分析等技术。随着计算机语言的不断演进,源代码分析的技术也在日趋完善,在不同的细分领域,出现了很多不错的源代码分析产品,如 Klocwork Insight、Rational Software Analyzer 和 Coverity、Parasoft 等公司的产品。而在静态源代码安全分析方面,Fortify 公司和 Ounce Labs 公司的静态代码分析器都是非常不错的产品。2009 年 7 月底,IBM 发布收购要约,将 Ounce Labs 纳入 Rational 产品线。在本示例中,我们选用 Ounce Labs 的安全分析器(Ounce Security Analyst 6.1)和 Rational Software Analyzer 来分别对示例代码进行静态源代码安全分析和代码质量分析。
为了保持示例一致性,我们选用 AltoroMutual 应用的源代码进行静态分析。首先,我们用Ounce Security Analyst 6.1 进行源代码安全分析。
Ounce 的安全分析器(Ounce Security Analyst)支持多种部署方式,可以独立运行,也可以通过 Plug-in 的方式运行在软件开发人员的集成开发环境中。在软件开发生命周期(SDLC)中,对于开发人员,更多的是希望在日常的开发过程中能够进行源代码的安全分析和检查,因此在本文的示例中我们选择将 Ounce 安全分析器(Ounce Security Analyst)通过插件的方式 Plug-in 到基于 Eclipse 的 IBM Rational AppScan Developer Edition 7.8.1 中来使用。
图 12. Ounce Labs 在 RADE 中的插件
下面我们在装有 Ounce Security Analyst 的 Rational AppScan Developer Edition 中,将 AltoroMutual 的源文件导入,我们发现 Plug-in 后的 Rational AppScan Developer Edition 上会多了一个名称为 Ounce 的菜单。
图 13. 在 RADE 中将 AltoroJ 项目编译通过
对于一般的静态安全分析而已,保持代码在做静态安全分析前的可编译性是一项非常重要的工作。因此建议软件开发人员在进行静态安全分析前首先保证自己的代码是编译通过的。我们首先将 AltoroMutual 的源代码进行编译,然后在 Ounce 菜单中选择对 AltoroMutual 源代码进行扫描。
下图中所示的是进行扫描之后的情况。在 Rational AppScan Developer Edition 的控制台中,我们看到 Ounce Security Analyst 总共扫描了 AltoroMutual 项目的 97 个源文件,在 10625 行代码里发现了 742 个安全问题,总共用时 62 秒。
图 14. 利用 Ounce Security Analyst 进行源代码扫描#p#
将视图切换到 Ounce Labs Perspective 后,打开 Assessment Summary,我们可以查看发现的漏洞类别与数量。
图 15. 扫描发现的 Top10 的漏洞类别与数量
扫描完成后,Ounce Security Analyst 会在发现安全漏洞的源文件上加上小红叉作为标示,帮助开发人员快速对漏洞进行定位。左下方的漏洞描述与修复建议可以帮助开发者进行修复。SmartTrace 直观的将函数调用关系通过图示的方式展示出来,点击 SmartAudit 中的 item 开发者可以直接跳转到存在漏洞的代码行上进行工作。
图 16. Ounce Security Analyst 安全分析视图
针对前例中 AppScan 通过渗透测试扫描出来的 XSS 问题,我们来看看 Ounce 安全分析器是如何发现并定位该漏洞的。打开 XSS 的漏洞列表,我们从 FeedbackServelet.java 文件中发现这个 XSS 问题是由于在“request.setAttribute("message_feedback", name);”这行代码中没有对 name 的输入值进行检测,允许了在 name 中包含跨站脚本攻击中经常使用的特殊字符,从而导致跨站脚本攻击问题。
图 17. 针对 XSS 问题的源代码分析#p#
其实在某些时候,软件的安全问题也同样包含了软件的质量问题,例如在架构中不够良好的设计会导致系统的拒绝服务攻击,SQL 链接在异常时候的不当处理导致连接池资源没有释放等等。Rational Software Analyzer 是一个基于 Eclipse 技术的软件分析工具,我们可以利用 Rational Software Analyzer 来对软件代码的质量和各种指标进行度量。
在示例中,我们选用 Rational Software Analyzer 7.0.1 来对相同的 AltoroMutual 项目进行代码质量扫描。首先,我们还是将 AltoroMutual 项目创建到 Rational Software Analyzer 的 workspace 中,并对该项目进行源代码分析的配置(如下图)。
图 18. 用 Rational Software Analyzer 进行代码质量分析的配置
通过扫描,我们可以从代码体系结构、软件度量、代码复审、数据流分析 4 个方面得到关于代码质量的问题数据。
图 19. Rational Software Analyzer 中对于软件度量的分析结果
在下图 Rational Software Analyzer 的数据流分析结果中,我们可以看到由于 SQL 链接在异常时不能释放而导致的资源泄漏问题。
图 20. Rational Software Analyzer 中基于数据流分析发现的资源泄漏问题
相似的,在 Ounce 中也可以发现这样既是安全也同样存在质量因素的漏洞。
图 21. Ounce 中针对相同资源泄漏问题的分析
总结
在本文中,我们通过对 Web 应用 AltoroMutual 进行渗透测试和源代码安全扫描,来对比黑盒动态测试和白盒静态分析在发现软件安全漏洞方面的功效,并利用 Rational Software Analyzer 在代码质量方面进行了粗浅的分析和与安全扫描的对比。
通过上述示例,我们发现源代码静态分析在代码扫描的覆盖率、发现安全问题的数量上有着不错的表现,并且能够找到大部分通过渗透测试发现的安全问题。但这并不能说静态分析在软件安全检测方面要优于渗透测试。静态分析的高覆盖率和扫描器的不同设置也导致了相对较高的误报率,而且静态代码的非运行性会导致了很多跟运行环境相关的安全漏洞通过静态安全分析无法发现。相对于此,渗透测试刚好可以弥补静态分析的这些劣势,虽然渗透测试发现安全问题的数量不如静态分析那么多,但是渗透测试的准确率和针对运行时态的实时检测都是其优势所在。所以渗透测试在软件开发生命周期中是不可或缺的一个环节。同样,我们看到软件的质量问题在源代码分析中也不能忽视。因此,一个理想的选择是:在整个软件开发生命周期中的不同阶段,针对不同的人员,引入相应的安全策略,制定合理的开发流程,从而达到提高软件安全性的目的。