20.3 独立漏洞扫描器

有许多工具可自动对Web应用程序进行漏洞扫描。这些扫描器的主要优点是,能够在相对较短的时间内测试大量功能,并且能够发现常见应用程序中存在的各种重要漏洞。

Web应用程序漏洞扫描器能够自动执行本书中介绍的各种测试技巧,包括应用程序抓取,查找默认与常见内容,以及探查常见的漏洞。在解析应用程序的内容后,扫描器将浏览它的功能,在每个请求的每一个参数中提交一系列测试字符串,然后分析应用程序的响应,从中查找常见漏洞的签名。接下来,扫描器生成一个报告,描述它发现的每一个漏洞。通常,这份报告中包括用于诊断每一个被发现的漏洞的请求与响应,允许经验丰富的用户对它们进行手动调查,确认漏洞是否存在。

决定是否以及何时使用一个漏洞扫描器的关键在于,理解这些工具的内在优缺点与在开发它们的过程中面临的挑战。这些考虑事项还会影响能否充分利用一个自动扫描器,以及如何解释与是否信任它的扫描结果。

20.3.1 扫描器探测到的漏洞

使用扫描器可以相当可靠地探测到几种常见的漏洞。这些漏洞都有非常明显的签名。有些情况下,这些签名就在应用程序的常见请求与响应中。还有些情况下,如果确定漏洞已经存在,扫描器会发送一个专门设计的请求,以触发它的签名。如果签名出现在应用程序对这个请求的响应中,那么扫描器就可据此推断,漏洞确实存在。

下面列出几个可以通过这种方法探测到的漏洞。

img002 反射型跨站点脚本漏洞。如果用户提交的输入未经过适当的净化,在应用程序的响应中“反射”回来,就会出现这种漏洞。自动扫描器通常会发送包含HTML标记的测试字符串,然后在响应中搜索这些字符串,从而确定许多这种类型的漏洞。

img002 一些SQL注入漏洞可通过某个签名确定。例如,提交一个单引号可能会导致应用程序返回一条ODBC错误消息;或者,提交字符串'; waitfor delay ‘0:0:30’-- 可能会造成时间延迟。

img002 一些路径遍历漏洞可通过提交一个针对某个已知文件(如win.ini或/etc/passwd)的遍历序列,然后在请求中搜索该文件是否出现,从而进行确定。

img002 一些命令注入漏洞可通过注入一个引起时间延迟,或者将某个特殊的字符串“反射”到应用程序的响应中的命令确定。

img002 直接目录列表可通过请求目录路径,然后寻找一个包含看似为目录列表的文本的响应,从而加以确定。

img002 明文密码提交、范围宽泛的cookie、激活自动完成的表单等漏洞可通过审查应用程序提出的常见请求与响应有效确定。

img002 通常,使用不同的文件扩展名请求每个枚举出的资源,可以发现在主要的公布内容中没有提供链接的数据,如备份文件和资源文件。

对上面的许多漏洞而言,有时候,使用一个标准的攻击字符串和签名无法有效探测到相同类型的漏洞。例如,为阻止基于输入的漏洞,应用程序会执行某种使用专门设计的输入即可避开的不完善的输入确认。普通的攻击字符串将被阻止或净化;但是,经验丰富的攻击者能够探查到应用程序实施的输入确认,并找到避开这种确认的方法。其他情况下,标准的攻击字符串可能会触发一个漏洞,但不会生成想要的签名。例如,许多SQL注入攻击并不会导致应用程序向用户返回任何数据或错误消息;同样,路径遍历漏洞也不会让目标文件的内容在应用程序的响应中直接返回。

此外,有几种重要的漏洞并没有明确的签名,使用一组标准的攻击字符串也无法发现它们。通常,自动扫描器并不能发现这种类型的漏洞。下面是一些扫描器无法准确判定的漏洞。

img002 不完善的访问控制。这种漏洞可使用户能够访问其他用户的数据,或者允许低权限用户访问管理功能。扫描器不了解应用程序的访问控制要求,也不能评估使用任何特殊的用户账户发现的各种功能和数据的重要性。

img002 通过修改参数值给应用程序的行为造成影响的攻击。例如,修改一个表示商品价格或订单状态的隐藏字段。扫描器并不了解任何参数在实现应用程序功能过程中所发挥的作用。

img002 其他逻辑错误,如使用负值突破交易限额,或者通过省略一个关键的请求参数避开账户恢复过程的某个阶段。

img002 应用程序功能设计方面的漏洞,如脆弱密码强度规则,从登录失败消息中枚举用户的功能,以及保密性不强的忘记密码提示。

img002 会话劫持攻击。攻击者可在应用程序的会话令牌中找到一个序列,伪装成其他用户。即使扫描器能确定某个参数在连续登录过程中使用了一个可以预测的值,但它仍然不能理解修改该参数导致出现的不同内容的意义。

img002 泄露敏感信息,如用户名列表和包含会话令牌的日志。

一些漏洞扫描器尝试检查上述某些漏洞。例如,某些扫描器尝试以两个不同的用户身份登录,并确定一名用户无须正确授权即可访问的数据和功能,以此确定访问控制漏洞。根据笔者的经验,这些类型的检查通常会生成大量错误警报和漏报。

在前面列出的两组漏洞中,每一组都包含明显的漏洞,也就是那些可被技术尚不熟练的攻击者发现和利用的漏洞。因此,虽然自动扫描器能够探查到应用程序中存在的大部分明显的漏洞,但它还是会遗漏许多这类漏洞,其中包括一些非常明显的漏洞,只要进行手动扫描即可探测到。自动扫描器根本不能提供任何保证,证明应用程序中不存在一些可被攻击者轻易发现和利用的严重漏洞。

同样,对于当前必须经过严格测试的、更注重安全的应用程序而言,其中存在的漏洞更多的是那些出现在第二个列表而不是第一个列表中的漏洞。

20.3.2 扫描器的内在限制

市场上最优秀的漏洞扫描器是由那些认真思考如何探查各种Web应用程序漏洞的专家所设计和执行的。无疑,他们设计的扫描器仍不能有效发现许多类型的漏洞。要设计一个完全自动化 的Web应用程序测试方法,我们面临着各种内在的障碍。只有拥有成熟的人工智能引擎,远远超越当前扫描器性能的系统,才能有效突破这些障碍。

1.Web应用程序各不相同

Web应用程序与网络和基础架构截然不同。通常,后者大多采用标准配置的非定制产品。从理论上讲,我们可以提前为所有可能的目标构建一个数据库,然后创建一个工具探查网络和基础架构中存在的漏洞。但是,我们却不能以这种方式探查定制Web应用程序中的漏洞;因此,任何高效的扫描器必须能够预见意外的情况。

2.扫描器不理解语法

计算机擅长分析应用程序响应的语法内容,能够识别常见的错误消息、HTTP状态码与被复制到Web页面中的用户提交的数据。然而,今天的扫描器并不能理解这些内容的语法意义,也不能根据这些意义做出合理的判断。例如,在更新购物篮的功能中,扫描器能够查看提交给该功能的大量参数。扫描器并不知道哪个参数表示数量,哪个参数表示价格。另外,它也不能判定修改订单的数量并不符合逻辑,而可修改其价格则代表一个严重的漏洞。

3.扫描器不会“即兴”处理

许多Web应用程序使用非标准的机制处理会话与导航,传送和处理数据,例如,通过查询字符串、cookie或其他参数。人类立即能够注意到并解析这些不常用的机制,但计算机会继续遵循它的标准规则。而且,许多针对Web应用程序的攻击需要某种“即兴”处理,例如,部分避开有效的输入过滤,或者利用应用程序行为的几个不同方面为攻击创造条件。通常,扫描器没有能力实施这些攻击。

4.扫描器并无直觉

计算机并不能凭直觉发现最佳的攻击方法。今天的扫描器采用的攻击方法,是对每一项功能尝试每一种攻击。这种方法在所能执行的检查种类以及组合这些检查的方式上存在着诸多限制。在许多情况下,这种方法往往会忽略漏洞的存在,如下所示。

img002 一些攻击需要在一个多阶段处理过程的一个或几个阶段提交专门设计的输入,然后完成整个处理过程,并观察处理结果。

img002 一些攻击需要改变应用程序执行某个多阶段处理的预定顺序。

img002 一些攻击需要以专门设计的方式修改多个参数的值。例如,一个XSS攻击需要在一个参数中插入一个特殊的值,使得应用程序生成错误消息;并在另一个参数中插入被复制到错误消息中的XSS有效载荷。

由于扫描器所使用的探查漏洞的蛮力方法存在的实际限制,它们并不能向每一个参数或者每一个处理阶段提交所有攻击字符串。当然,也没有人能够做到这一点;但是,人类往往能够“察觉”可能存在的漏洞、开发者做出的某种假设以及似乎有什么不太正常的位置。因此,渗透测试员会选择这一小部分可能的攻击进行实际调查,并且通常能够成功发现漏洞。

20.3.3 扫描器面临的技术挑战

前面介绍的自动控制面临的障碍导致创建一个有效的漏洞扫描器必须解决许多特殊的技术 挑战。这些挑战不仅会损害扫描器探查某些类型的漏洞的能力(如前所述),而且会损害它执行解析应用程序内容、探查漏洞等核心任务的能力。

其中一些挑战并非无法克服,如今的扫描器已新增了各种功能,可在一定程度上克服这些挑战。但是,扫描并不是一种完美的解决方案,现代扫描技术的效率因不同应用程序而异。

1.验证与会话处理

扫描器必须能够处理各种应用程序使用的验证与会话处理机制。通常,应用程序的绝大多数功能只有使用通过验证的会话才能访问;如果扫描器不能获得这样的会话,它就会遗漏许多可以探测的漏洞。

当前,扫描器用户通过提供一段登录脚本,或者使用内置的浏览器完成验证过程,帮助扫描器按照特定的步骤获得通过验证的会话,从而解决验证方面的问题。

会话处理方面的挑战更难以解决,包括以下两个问题。

img002 扫描器必须能够与应用程序使用的会话处理机制交互。这可能要求在cookie、隐藏表单字段或URL查询字符串中传送会话令牌。令牌可能在整个会话过程中保持静态,或者根据每个请求而发生变化,或者应用程序可能会采用一种完全不同的定制机制。

img002 如果会话已经失效,扫描器必须能够了解这一情况,并返回到验证阶段获得一个新的会话。造成会话失效的原因很多,例如,因为扫描器请求了退出功能,或者因为扫描器进行了反常导航或提交了某种无效的输入,导致应用程序终止了会话。在最初解析应用程序及随后探查漏洞的过程中,扫描器必须能够探测到这两种情况。如果会话失效,不同的应用程序会表现出不同的行为;而扫描器也只会分析应用程序响应的语法内容。通常而言,这可能是一个难以应对的挑战,应用程序使用非标准的会话处理机制时尤其如此。

公平地讲,今天的一些扫描器能够检测出应用程序采用的绝大多数验证和会话处理机制。但是,仍然存在许多扫描器无法处理的情况。因此,它们可能无法抓取或扫描应用程序的主要受攻击面。由于独立扫描器完全以自动方式运行,用户通常难以察觉这种缺陷。

2.危险的后果

在许多应用程序中,不遵循任何指导而进行无限制的扫描,可能会给应用程序及其包含的数据带来极大的风险。例如,扫描器可能会发现一个包含重设密码、删除账户等功能的管理页面。扫描器盲目地请求每一项功能可能会导致应用程序拒绝所有用户的访问请求。同样,扫描器可能会发现一个可被用于严重破坏应用程序数据的漏洞。例如,在一些SQL注入漏洞中,提交标准的SQL攻击字符串(如or 1=1--)可能会使应用程序的数据遭受无法预料的操作。这时,知道某项特殊功能的作用的人会谨慎行事,但自动扫描器却缺乏这种认识。

3.“个性化”功能

许多时候,纯粹对应用程序进行语法分析并不能准确判定它的核心功能:

img002 一些应用程序虽包含数目庞大的内容,但它们体现的却是一组相同的核心功能。例如,eBay、MySpace与Amazon这些应用程序含有数百万个包含不同URL与内容的不同应用程序页面,但这些页面仅对应少数几个应用程序功能。

img002 如果仅从语法角度分析,一些应用程序可能并没有明确的边界。例如,日历应用程序允许用户导航至任何日期。同样,一些内容有限的应用程序在不同的场合采用易变的URL或请求参数访问相同的内容,导致扫描器继续对应用程序的内容进行不确定的解析。

img002 扫描器本身的操作可能会导致一些似乎是全新的内容出现。例如,提交一个表单可能会使应用程序在界面上显示一个新的链接,访问这个链接可能会获得另外一个作用相同的表单。

在上述任何一种情况下,渗透测试员能够立即“看透”应用程序的请求内容,确定需要测试的核心功能;但不了解语法的自动扫描器却很难做到这一点。

除上述解析和探查应用程序过程中出现的明显问题外,在报告已发现的漏洞过程中也出现了一个相关的问题:纯粹基于语法进行分析的扫描器很可能会重复报告同一个漏洞。例如,一个扫描报告确定了200个XSS漏洞,其中有195个出现在扫描器多次探查的同一项应用程序功能中,因为这个漏洞通过不同的语法内容出现在不同的场合中。

4.其他自动控制挑战

我们在第14章讲过,一些应用程序会实施专门的防御措施,防止自动化客户端程序访问它们。这些措施包括:遇到反常行为时反应性地终止会话,使用CAPTCHA和其他控件确保一些特殊的请求由某一名用户提出。

通常,扫描器的抓取功能面临和Web应用程序爬虫相同的挑战,如定制化“未发现”响应,能够解释客户端代码。许多应用程序对特殊的输入项(例如,用户注册表单中的字段)进行严格的确认。如果爬虫向表单提交无效的输入,并且不能理解应用程序生成的错误消息,那么它就无法通过这个表单访问它之后的一些重要功能。

Web技术的快速发展,特别是各种浏览器扩展组件和其他框架在客户端上的应用,使大多数扫描器都落后于最新的技术发展趋势。这会导致扫描器无法确定在应用程序中提出的所有相关请求,或无法确定应用程序请求所需的准确格式和内容。

此外,当前Web应用程序高度状态化,以及复杂数据在客户端和服务器端上保存并通过这二者之间的异步通信进行更新的特点,都会为大多数倾向于单独处理每个请求的全自动扫描器制造问题。为完全涵盖这些应用程序,通常有必要了解它们采用的多阶段请求过程,并确保应用程序处于所需的状态,以处理特定的攻击请求。我们在第14章介绍了在定制的自动化攻击中实现这一目标的技巧。通常,采用这些技巧需要进行人为干预,以了解相关要求、对测试工具进行适当地配置,并监视它们的性能。

20.3.4 当前产品

近年来,自动化Web扫描器市场有了很大发展,出现了各种创新,并涌现出一系列不同的产品。以下是一些最主要的扫描器:

img002 Acunetix

img002 AppScan

img002 Burp Scanner

img002 Hailstorm

img002 NetSparker

img002 N-Stalker

img002 NTOSpider

img002 Skipfish

img002 WebInspect

虽然大多数成熟扫描器都具备相同的核心功能,但是,在如何检测不同漏洞区域,以及向用户提供的功能方面,这些扫描器之间仍然存在差异。有关不同扫描器的优点的公开讨论大多以供应商之间的口水战而结束。尽管人们进行了各种测试来评估不同扫描器在检测不同类型的安全漏洞方面的性能,但是,这类测试始终仅限于将扫描器用于扫描一小段存在缺陷的示例代码,因此,这些测试结果并不足以推断扫描器在各种实际情况下的性能。

最有效的测试方法,是针对大量源自真实应用程序的示例代码运行扫描器,而不是在分析之前为供应商提供基于示例代码调整其产品的机会。加州大学圣芭芭拉分校的一项此类学术研究声称其“在所测试的工具数量……以及所分析的漏洞类型方面,是最大规模的Web应用程序扫描器评估”。有关此项研究的报告,请从以下URL下载:

www.cs.ucsb.edu/~adoupe/static/black-box-scanners-dimva2010.pdf

这项研究的主要结论如下:

img002 即使是最先进的扫描器,也无法检测出所有类型的漏洞,包括脆弱密码、访问控制不完善和逻辑缺陷。

img002 由于对常用客户端技术支持不完全,以及当前应用程序的复杂状态化特点,就目前的Web漏洞扫描器而言,抓取现代Web应用程序可能是一项严峻的挑战。

img002 价格与性能之间并没有明显的对应关系。一些免费或价格非常低廉的扫描器与那些售价数千美元的扫描器的性能相当。

基于扫描器确定不同类型漏洞的能力,这项研究对扫描器进行了打分。每种扫描器的总得分和价格如表20-1所示。

表20-1 UCSB针对不同扫描器的漏洞检测性能与价格的研究报告

扫 描 器 分 数 价 格
Acunetix 14 4995~6350美元
WebInspect 13 6000~30 000美元
Burp Scanner 13 191美元
N-Stalker 13 899~6299美元
AppScan 10 17 550~32 500美元
w3af 9 免费
Paros 6 免费
HailStorm 6 10 000美元
NTOSpider 4 10 000美元
MileSCAN 4 495~1495美元
Grendel-Scan 3 免费

需要注意的是,近年来,扫描器的扫描能力已有了显著提高,并可能会继续改进。个体扫描器的性能和价格可能会随时间而变化。表20-1中的报告信息于2010年6月公布。

由于有关Web漏洞扫描器性能的公开信息相对较少,因此,在做出购买决策之前,渗透测试员需要自己进行这方面的调查。大多数扫描器供应商都提供详细的产品文档及其软件的试用版本,渗透测试员可以利用这些信息做出产品选择。

20.3.5 使用漏洞扫描器

现实情况下,使用漏洞扫描器的效率高低很大程度上取决于所针对的是何种应用程序。根据应用程序的功能及其包含的漏洞种类,我们上面介绍的扫描器的内在优缺点会以不同的方式影响不同的应用程序。

对于Web应用程序中存在的各种常见漏洞,自动扫描器能够发现其中大约一半的漏洞,它们大多都带有一个标准签名。在扫描器能够探测到的各种漏洞中,尽管会遗漏那些难以发现与不常见的漏洞,但它们能够很好地确认特定的漏洞。总之,进行自动扫描能够确定一个常见应用程序中存在的一些但并非全部明显的漏洞。

如果是一名渗透测试新手,或者需要在有限的时间内攻击一个大型应用程序,那么进行自动扫描的好处极其明显,因为它能够迅速确定一些需要进行深入手动调查的线索,并帮助初步确定应用程序的安全状态以及其中存在的漏洞类型。它还可帮助全面了解目标应用程序,并确定任何需要仔细分析的特殊区域。

如果是一名Web应用程序渗透测试专家,并且希望从目标应用程序中发现尽可能多的漏洞,那么,需要认识漏洞扫描器的内在局限性,并且不能完全相信它们,认为它们能够发现每一个漏洞。虽然扫描结果会有所帮助,并提示手动调查一些特殊的问题;但是,通常我们希望对应用程序的每个功能区域进行测试,查找每一种类型的漏洞,以确信对其进行了全面的扫描。

当使用漏洞扫描器时,必须始终记住以下一些要点,以充分利用这种工具。

img002 了解扫描器能够确定和不能够确定的漏洞类型。

img002 熟悉扫描器的功能,知道如何对其进行配置,对某个应用程序进行有效扫描。

img002 在运行扫描器之前全面了解目标应用程序,以充分利用扫描器的功能。

img002 了解抓取强大的功能和自动探查危险漏洞蕴含的风险。

img002 始终手动核实扫描器报告的所有潜在的漏洞。

img002 还要意识到,扫描器可能会造成极大的混乱,在服务器与IDS防御中留下大量“指纹”。如果想要保持隐秘,不要使用扫描器。

全自动化扫描与用户指导的扫描

在使用Web扫描器时,一个主要的考虑事项,是渗透测试员希望在多大程度上指导扫描器完成各种工作。这方面的两个极端用例如下。

img002 为扫描器提供应用程序的URL,单击“开始”(Go),然后等待结果。

img002 进行手动操作,使用扫描器单独测试每个请求,同时进行手动测试。

独立Web扫描器更适于第一种用例。整合到集成测试套件中的扫描器更适于第二种用例。也就是说,如果需要,可以结合采用这两类扫描器。

如果用户对于Web应用程序安全不甚了解,或需要快速评估某个应用程序,或需要经常处理大量应用程序,则可以通过全自动化扫描了解应用程序的一部分受攻击面。这样做有助于用户在确定更全面测试的效率时做出明智的决策。

如果用户了解Web应用程序安全测试的整个过程,以及全自动化测试的限制,则最好是使用集成测试套件中的扫描器,从而为手动测试过程提供支持,并提高手动测试的效率。这种方法有助于避免全自动扫描器面临的诸多技术挑战。渗透测试员可以使用浏览器指导扫描器进行操作,以确保不会遗漏关键的功能区域。渗透测试员可以直接测试应用程序生成的、其中包含应用程序所需的正确内容和请求格式。由于能够完全控制测试过程,因此能够避开危险功能、识别重复功能,并避开自动扫描器可能会遇到困难的任何输入确认。此外,由于可以收到有关扫描器活动的直接反馈,因而可以确保避免与验证和会话处理机制有关的问题,并确保正确处理多阶段过程和有状态功能造成的问题。通过以这种方式使用扫描器,可以覆盖一系列可以自动进行检测的重要漏洞,从而能够查找需要智慧和经验才能发现的漏洞类型。