定制攻击自动化

本章不再介绍任何新的漏洞,而是分析向Web应用程序实施攻击的一个关键问题——如何使用自动控制加强并促进定制攻击。我们所讨论的技巧可用于整个应用程序以及攻击过程的每一个阶段,包括最初的解析过程到实际的应用。

每一个Web应用程序都各不相同。渗透测试员需要使用各种手动操作与技巧向应用程序实施有效攻击,以理解它的行为,并探查其中存在的漏洞。同时还必须发挥想象,利用自己的经验与直觉。通常,测试员应当根据已经确定的特殊行为,以及应用程序允许与其交互并对其进行控制的特定情形,实施本质上定制或自定义的攻击。手动实施定制可能极其费力,而且容易出错。为此,最成功的Web应用程序黑客往往会努力简化他们的定制攻击,设法将其自动化,使其更简单、快捷、高效。

本章将讨论一种实现定制攻击自动控制的公认方法。这种方法结合了人类智慧及计算机蛮力的优点,常常会造成破坏性的后果。本章还将介绍使用自动化技巧时遇到的各种障碍,以及避开这些障碍的方法。

应用定制自动化攻击

在以下3种情况下,定制自动化攻击技巧有助于渗透测试员向Web应用程序实施攻击。

枚举标识符。大多数应用程序使用各种名称与标识符指代数据和资源,如账号、用户名和文档ID。测试员需要经常浏览数目庞大的潜在标识符,才能枚举出那些有效或值得进一步研究的标识符。在这种情况下,可以使用完全定制的自动技巧来分析一组可能的标识符,或者遍历应用程序所使用的标识符的语法范围。

使用页码参数获取特殊内容的应用程序就是一个典型的示例:

在浏览应用程序的过程中,会发现大量有效的PageNo值;但是,要确定每一个有效值,必须循环查找整个语法范围,而手动操作根本无法做到这一点。

获取数据。通过提出专门设计的特殊请求,利用各种Web应用程序漏洞,测试员就可以从应用程序中提取到有用的或敏感的数据。例如,个人资料页面可能会显示当前用户的个人与银行交易信息,并指出该用户在应用程序中的权限。通过一个访问控制漏洞,就可以查看任何用户的个人资料页面,但一次只能获得一名用户的资料。要获得所有用户的资料,可能需要提交成千上万个请求。这时,就可以使用一个自动化定制攻击截获所有数据,而不是进行手动操作。

获取有用数据的一个示例是对前面描述过的枚举攻击的扩展。这时不必确认到底哪些PageNo值为有效值;相反,可以利用自动化攻击来从获得的每个页面中提取出HTML标题标签(title tag)的内容,迅速扫描所有页面,查找有用的数据。

Web应用程序模糊测试。当描述探查常见Web应用程序漏洞时,能够见到大量的示例,在这些示例中,探查漏洞的最佳方法是提交各种反常的数据和攻击字符串,然后检查应用程序的响应,查找任何表示可能存在漏洞的异常现象。在大型应用程序中,在进行初步解析过程中,已经确定一些需要探查的特殊请求,每个请求都包含各种不同的参数。手动检查每一个参数既费时又费力,而且可能会忽略大部分受攻击面。但是,使用定制自动攻击技巧,就可以立即生成大量包含常用攻击字符串的请求,迅速访问服务器的响应,找到所有值得进一步研究的参数。这种技巧常被称为模糊测试(fuzzing)。

我们将详细讨论这三种情形,并说明如何利用定制自动攻击技巧显著提高攻击效率。

枚举有效的标识符

在描述各种常见漏洞与攻击技巧的过程中,我们提到,应用程序经常使用名称或标识符指代各种数据;渗透测试员的任务是查明它使用的部分或全部有效的标识符。以下是一些需要枚举出标识符的情况。

应用程序的登录功能返回详尽的错误消息,指出登录失败是因为用户名不存在或密码错误。在这种情况下,可以遍历一组常见的用户名,并尝试用每一个用户名登录,从而将攻击范围缩小至那些已知有效的用户名。然后测试员就可以使用得到的用户名列表,实施密码猜测攻击。

许多应用程序使用标识符指代应用程序处理的各种资源,如文档ID、账号、雇员号码和日志记录。通常,应用程序会泄露一些确定特殊标识符是否有效的方法。因此,遍历应用程序使用的标识符的语法范围就可以获得所有这些资源。

如果应用程序生成的会话令牌可以预测,那么,以应用程序发布的一些令牌为基础进行推断,就可以劫持其他用户的令牌。根据这个过程的准确程度,可能需要测试大量令牌才能确定每一个有效的值。

基本步骤

设计一个枚举有效标识符的定制自动攻击的第一步是查找一个具有以下特点的请求/响应对。

请求的参数中包含所针对的标识符。例如,在一个显示应用程序页面的功能中,请求中可能包含参数PageNo=10069。

当改变这个参数的值时,服务器对这个请求的响应也会发生相应变化。例如,如果请求一个有效的PageNo,服务器可能返回一个包含指定文档内容的响应。如果请求一个无效的值,它可能会返回一个常见的错误消息。

确定一个适当的请求/响应对后,接下来应向应用程序提交大量自动请求,循环浏览所有潜在的标识符,或者遍历已知应用程序使用的标识符的语法范围。然后,监控应用程序对这些请求的响应,查找表示提交有效标识符的“触点”。

探测“触点”

改变请求中的参数值后,响应的许多特征会发生系统性的改变,它们是实施自动攻击的基础。

HTTP状态码

根据请求提交的参数值,许多应用程序系统性地返回各种不同的状态码。在枚举标识符的攻击中,最常见的状态码包括以下几种。

200,默认状态码,表示请求成功提交。

301或302,重定向到另外一个URL。

401或403,请求未获授权或被禁止。

404,被请求的资源未发现。

500,服务器在处理请求时遇到错误。

响应长度

应用程序中的动态页面常常使用一个页面模板建立响应(其长度固定),并在这个模板中插入针对每个响应的内容。如果针对每个响应的内容不存在或无效(例如,请求了一个错误的文档ID),那么应用程序就会返回一个空白响应。这时,响应长度就是证明文档ID是否有效的一个可靠指标。

在其他情况下,响应长度不同可能表示发生错误或存在其他功能。根据我们的经验,在绝大多数情况下,HTTP响应码与响应长度就足以确定反常的响应。

响应主体

应用程序返回的数据中常常包含可用于探测“触点”的字面量字符串或模式。例如,如果请求一个无效的文档ID,响应中可能包含字符串Invalid document ID。有时,即使HTTP响应码没有变化,但由于响应中包含动态内容,总体响应长度会发生改变。因此,在响应中搜索一个特殊的字符串或模式可能是确定“触点”的最佳方法。

Location消息头

有时候,应用程序会以一个HTTP重定向(状态码为301或302)响应访问某个特殊URL的请求,重定向的目标则取决于在请求中提交的参数。例如,如果提交正确的报告名称,一个查看报告的请求可能会导致一个目标为/download.jsp的重定向;否则,重定向就指向/error.jsp。HTTP重定向的目标在Location消息头中指定,这种方法同样也可用于确定“触点”。

Set-Cookie消息头

有时候,应用程序可能会以同样的方式响应一组请求,唯一例外的是有些时候它会设定一个cookie。例如,每个请求都会遇到相同的重定向,但如果证书有效,应用程序就会设定一个包含会话令牌的cookie。客户端访问重定向得到的内容取决于是否提交了有效的会话令牌。

时间延迟

少数情况下,无论提交的参数是否有效,服务器响应返回的实际内容可能完全相同,但是它返回响应的时间可能稍有不同。例如,如果使用一个无效的用户名登录,应用程序可能会立即通过一个并不包含太多信息的常规消息做出响应。但是,如果提交的是有效的用户名,应用程序就需要进行各种后端处理来确认用户提交的证书,其中一些处理可能要进行大量计算,如果发现证书错误,再返回相同的消息。如果远程检测到这种时间差异,就可以用它来确定攻击中的“触点”。(其他类型的软件,如旧版的OpenSSH中也常常发现这种漏洞。)

 提示 选择“触点”指标的主要目的是找到一个或一组(如果结合在一起)完全可靠的“触点”。但是,在一些攻击中,提前并不知道什么是“触点”。例如,当渗透测试员针对登录功能实施攻击,尝试枚举用户名时,并没有一个有效的用户名可帮助他确定应用程序在遇到“触点”时的行为。在这种情况下,最好是监控应用程序中刚刚描述的各种特征,寻找其中出现的任何异常现象。

编写攻击脚本

假设已经确定以下URL,如果提交一个有效的PageNo值,它将返回200响应码;否则它就返回500响应码:

这个请求/响应对满足实施自动攻击并且枚举有效页面ID所需要的两个条件。

在这样简单的情况下,可以立即创建一段定制的脚本,实施一次自动攻击。例如,下面的bash脚本从stdin读取一组潜在的页面ID,使用netcat工具请求一个包含每个ID的URL,同时记录服务器响应的第一行,其中包含HTTP状态码:

用一个适当的输入文件(input file)运行这段脚本,得到以下输出,可以迅速从中确定有效的页面ID:

 提示 Cygwin环境可用于在Windows平台上运行bash脚本;此外,UnxUtils套件中包含大量有用的GNU实用工具的Win32端口,如head和grep。

使用一段Windows批处理脚本也可以达到相同的目的。下面的示例使用curl工具生成请求,并通过findstr命令过滤输出:

虽然这些简单的脚本非常适于执行一些不太复杂的任务,如循环浏览一组参数值及在服务器响应中解析某个属性,但是,在许多情况下,可能需要使用比命令行脚本更强大、更灵活的工具。我们首选一种适当的高级面向对象的语言,它必须便于处理基于字符串的数据,并提供支持套接字和SSL的API。满足这些标准的语言包括Java、C#和Python。下面将深入分析一个使用Java的示例。

JAttack

JAttack是一个简单但功能强大的工具,通过它,任何人只要懂得一些编程基础知识,就可以使用定制自动技巧向应用程序实施强大的攻击。这个工具的完整源代码可从本书的同步网站(http://mdsec.net/wahh)下载。但是,比源代码更重要的是使用这个工具的基本技巧,下面将对此进行简要说明。

不要把请求仅当做一个非结构化的文本块处理,而是要利用该工具理解请求参数的概念:它是一个可被操控,并以特殊方式附加在请求上的命名数据。请求参数可能出现在URL请求字符串、HTTP cookie或POST请求主体中。下面创建一个Param类保存相关细节。

许多时候,请求中包含不希望在某个特定的攻击中修改的参数;但为了成功实施攻击,仍然需要包含这些参数。可以使用attack字段标记某个参数是否可在当前攻击中进行修改。

要以一种特定的方式修改某个参数的值,JAttack工具必须理解攻击有效载荷的概念。在不同类型的攻击中,需要创建各种有效载荷源(payload source)。首先建立一个所有有效载荷必须执行的界面,提高这个工具的灵活性:

nextPayload方法可用于监控有效载荷源的状态,直到它的全部有效载荷用完后才返回true。reset方法返回有效载荷源起始点的状态。getPayload方法返回当前有效载荷的值。

在枚举文档的示例中,想要修改的参数包含一个数字值,因此首先在PayloadSource界面中执行一个类,生成数字有效载荷。可通过这个类指定想要测试的数字范围:

了解请求参数与有效载荷源的概念后,我们已经拥有足够的资源,能够生成请求并处理服务器的响应。首先,对攻击进行一些配置:

这个配置包含目标的基本信息,创建一个叫做PageNo的请求参数,并指定10060~10080为数字有效载荷源的范围。

为了循环浏览一系列的请求并针对多个参数,需要保持某种状态。使用一个简单的nextRequest方法监控请求引擎的状态,它在浏览完所有请求后返回true值。

这个有状态的请求引擎将追踪当前正针对哪个参数,以及在其中插入了什么攻击有效载荷。接下来使用这些信息建立一个完整的HTTP请求。它包括在请求中插入每种类型的参数,并增加任何必要的消息头:

 注解 如果自己编写代码生成POST请求,那么,和在前面的代码中一样,就需要在其中包含一个有效的Content-Length消息头,指定每个请求中HTTP主体的实际长度。如果提交的是无效的Content-Length,大多数Web服务器或者将提交的数据截短,或者等待再提交更多的数据。

要送出请求,需要与目标Web服务器建立网络连接。使用Java之后,建立TCP连接、提交数据并读取服务器响应的任务都变得极其简单。

获得服务器对每个请求所做出的响应后,需要解析这些响应,提取出相关信息,确定攻击中的“触点”。首先记录两个有用的数据——响应第一行的HTTP状态码与响应的总长度:

现在已经为实施攻击做好准备。最后只需要一些包装器代码轮流调用前面提到的每一个方法并指出其结果,直到提出所有请求,nextRequest方法返回false:

整个过程就是这样!为编写并运行这些代码,需要下载Sun公司的Java SDK与JRE,然后运行下面的脚本:

根据我们在示例中的配置,这个工具输出如下结果:

如果网络连接与处理能力一切正常,JAttack每分钟能够提出数百个请求,并输入相关细节,帮助迅速确定需要进一步研究的有效文档标识符。

尝试访问

http://mdsec.net/app/

看起来,似乎刚刚描述的攻击并不比前面只需要几行代码的bash脚本实例更复杂。但是,JAttack的设计形式允许对它进行任意修改,从而实施更加强大的攻击,合并多个请求参数、各种有效载荷源,并对响应进行任何复杂的处理。下面几节将对JAttack的代码进行一些修改,使其实现更强大的功能。

获取有用的数据

当攻击应用程序时,定制自动化技巧的第二个主要用途是,通过专门设计的特殊请求,以一次一个数据的速度获取信息,从而提取出有用的或敏感的数据。如果已经确定一个可供利用的漏洞(如访问控制缺陷),并能够通过为一个未授权的资源指定标识符的方式来访问这个资源,那此时往往就会出现这种情况。但是,即使应用程序完全按设计者预计的方式运行,也可能会出现这种情况。在下面这些情况下,渗透测试员可以使用自动化技巧获取数据。

一个网上零售应用程序允许注册用户查看他们的待办订单。但是,如果能够确定其他用户的订单号,就可以查看他们的订单信息,就像查看自己的订单一样。

忘记密码功能的实施取决于用户配置的质询。可以提交任意用户名并查看相关质询。通过遍历一组枚举或猜测出来的用户名,就能够获得大量用户密码质询,从而确定那些最容易猜测的质询。

一个工作流程应用程序包含一项功能,可显示某一用户的基本账户信息,包括他在应用程序中的权限。通过遍历应用程序使用的用户ID,渗透测试员就能够列出所有的管理用户,并以此为基础进行密码猜测和其他攻击。

使用自动化技巧获取数据的基本步骤与枚举有效标识符的步骤基本类似,其不同之处在于,现在不仅对一个二进制结果(“触点”或“错失”)感兴趣,还要设法从每个响应中提取有用的内容。以下面的请求为例,它由登录用户提出,以显示其账户信息。

虽然只有通过验证的用户能够访问此应用程序功能,但由于存在访问控制漏洞,任何用户只需简单修改uid参数,即可查看其他所有用户的详细资料。在另一个漏洞中,披露的详细资料还包括用户的完整证书。由于用户的uid参数值相对较小,因此,攻击者能够轻易推测出其他用户的标识符。

当应用程序显示一个用户的资料时,页面源代码会将个人信息包含在下面的HTML表中:

根据应用程序的行为,攻击者可直接实施定制自动攻击,获取所有应用程序用户的个人信息,包括证书等。

为实施攻击测试,我们快速对JAttack工具进行一些改进,使它能够提取并记录服务器响应中的特殊数据。首先,将攻击配置数据添加到源代码的字符串列表内,通过它们确定想要提取的有用内容:

然后把下面的代码添加到parseResponse方法中,以在每个响应中搜索上述列表中的每一个字符串,并提取字符串后到圆括号位置的内容:

这就是对这个工具的代码进行的全部修改。为配置JAttack针对我们感兴趣的实际请求,需要对它的攻击配置进行如下更新:

这个配置指示JAttack向相关URL提出包含2个必要参数的请求:包含当前会话令牌的cookie和易受攻击的用户标识符。其中只有一个参数会通过我们指定的uid号范围进行修改。

现在再运行JAttack,得到以下结果:

可见,这次攻击成功截取了一些顾客的个人资料。通过扩大攻击的数值范围,我们可以提取应用程序所有用户的登录信息,很有可能还包含管理员。

尝试访问

http://mdsec.net/auth/498/

注意,如果对此实验室示例运行JAttack代码,则需要根据应用程序发布的值调整攻击配置中使用的URL、会话cookie和用户ID参数。

 提示 以制表符分隔格式输出的数据可轻易加载到Excel之类的电子表格软件中,以对其进行进一步处理或整理。许多时候,通过以上方法获取的数据可用作其他自动攻击的输入。

常见漏洞模糊测试

定制自动化技巧的第三个主要用途并不包含利用任何已知的漏洞枚举或提取信息,而是使用各种旨在造成反常行为的、专门设计的攻击字符串来探查应用程序中是否存在任何常见的漏洞。因为以下原因,与前面描述的攻击相比,这种类型的攻击更加缺乏针对性。

无论每个参数的正常功能是什么,或者应用程序希望收到何种类型的数据,在这种攻击中,往往需要提交与测试应用程序每个页面的每一个参数相同的攻击有效载荷。这些有效载荷有时叫作模糊测试字符串(fuzz string)。

事先并不知道如何确定“触点”。与其监控应用程序的响应,在其中查找特殊的指标,还不如系统性地截取尽可能多的数据并对其进行审查,确定攻击字符串在应用程序中触发反常行为的情形,然后再做深入调查。

当探查各种常见的Web应用程序漏洞时,一些漏洞会通过特别明显的应用程序行为表现出来,这些行为包括特定的错误消息或HTTP状态码。有时可以根据这些漏洞签名来探查常见的漏洞;而且,自动化应用程序漏洞扫描器也使用这种方法来确定绝大多数的漏洞(请参阅第20章了解相关内容)。然而,从理论上讲,向应用程序提交的任何测试字符串都会产生某种可以预料的行为,在特定的条件下,表明应用程序存在某种漏洞。为此,经验丰富的攻击者使用定制自动化技巧,就比单单使用全自动化工具更有效率。这类攻击者会对应用程序响应中的每一个相关细节进行全面分析;他能够从应用程序设计者与开发者的角度考虑问题。此外,他能够发现并调查请求与响应之间不寻常的联系,而当前还没有任何工具能够做到这一点。

功能复杂的大型应用程序中包含大量动态页面,且每个页面都能接受各种参数,这时,使用自动化技巧查找漏洞就非常有用。手动测试每一个参数,并追踪应用程序对相关请求响应中的有关细节,是一个几乎无法完成的任务。使用自动化工具代替完成需要手动执行的任务,是在这种应用程序中探查漏洞的唯一实用的方法。

确定上一个示例中的访问控制不完善并对其加以利用后,我们还可以实施模糊测试攻击来检查各种基于输入的漏洞。作为对受攻击面的初步测试,我们决定在每个参数中轮流提交以下字符串。

′,如果存在SQL注入漏洞,某些情况下,提交这个字符串将造成一个错误。

;/bin/ls,如果存在命令注入漏洞,提交这个字符串可能导致无法预料的行为。

../../../../../etc/passwd,如果存在路径遍历漏洞,提交这个字符串可能生成一个不同的响应。

xsstest,如果这个字符串被复制到服务器的响应中,那么应用程序就容易受到跨站点脚本攻击。

我们将对JAttack工具进行扩展,通过创建一个新的有效载荷源,生成这些有效载荷,如下所示:

 注解 任何探查应用程序安全漏洞的重要攻击都需要使用许多其他攻击字符串,以确定其他薄弱环节和前面提到的漏洞的其他变化形式。我们将在第21章提供一个更加全面的列表,列出在对Web应用程序进行模糊测试时需要的所有字符串。

为使用JAttack进行模糊测试,还需要扩展它的响应分析代码,使其能够提供更多与应用程序响应有关的信息。显著提高这种分析能力的一个简单办法,就是在每个响应中搜索指示出现某种反常行为的常见字符串和错误消息,并记录它们在工具的输出结果中出现的每一种情况。

首先,在攻击配置数据中添加想要搜索的字符串列表:

然后插入下面的parseResponse方法,以在响应中搜索前面提到的每一个字符串,并记录任何发现的字符串:

 提示 事实证明,枚举应用程序中的标识符时,在JAttack中合并这种搜索功能往往非常有用。通常,在应用程序的响应中是否存在某个特殊的表达式是出现“触点”的最可靠指标。

我们可以利用这些代码建立一个基本的Web应用程序漏洞测试器。当实施具体的攻击时,测试员只需用相关的请求细节对JAttack进行配置,指示它攻击每一个参数。代码如下所示:

配置这些细节后就可以开始实施攻击。在几秒钟内,JAttack就已经向所有请求参数提交了攻击有效载荷。而手动提交至少需要几分钟时间,审查并分析应用程序收到的响应则需要更长时间。

接下来再对JAttack的输入结果进行手动检查,尝试确定任何表示漏洞存在的反常行为。分析下面这段输出摘录:

对于修改SessionId参数的请求,应用程序返回一个始终为相同长度的重定向响应。这种行为并不表示存在任何漏洞。这并不奇怪,因为在登录时修改会话令牌通常会使当前会话失效,用户将被重定向到登录页面。

uid参数更有意思。对这个参数的任何修改都会导致一个包含字符串exception的响应。这些响应的长度可变,表明不同的有效载荷会导致不同的响应,因此这些响应可能并不是常规的错误消息。而且,可以看到,提交单引号时,应用程序的响应包含字符串quotation,这可能是SQL错误消息的一部分,说明应用程序可能存在SQL注入漏洞,我们应进行手动测试来确认这一点(请参阅第9章)。此外,我们还发现,应用程序的响应回显了有效载荷xsstest。因此应进一步探查这种行为,以确定是否可以利用该错误消息实施跨站点脚本攻击(请参阅第12章文解相关内容)。

尝试访问

http://mdsec.net/auth/498/

整合全部功能:Burp Intruder

JAttack由不到250行的简单代码构成,然而,当对一个向应用程序提出的请求进行模糊测试时,它在几秒钟内就能发现至少两个严重的安全漏洞。

尽管它的功能强大,但是,只要开始使用JAttack这样的工具实施自动化定制攻击,渗透测试员就立即可以发现其他更有用的功能。按现在的情况,需要在工具的源代码中配置每一个目标请求,然后重新编译它。但最好是从一个配置文件中读取这些信息,然后在运行时动态构建攻击。实际上,最好的办法是建立一个友好的用户界面,可通过它在几秒钟内配置上述攻击。

许多时候,渗透测试员还需要以更加灵活的方式生成有效载荷,并使用比我们创建的有效载荷源更高级的源。而且,通常还需要支持SSL、HTTP验证、多线程请求、自动跟随重定向,并对有效载荷内的不常见字符进行自动编码。有时,一次只修改一个参数可能觉得限制过大;攻击者可能希望同时在两个参数中注入不同的有效载荷来源。为便于参考,最好是保存应用程序的全部响应,这样就可以立即检查一个有用的响应,了解发生了什么状况,甚至手动调整对应的请求并重新提出这个请求。除了不断修改和提出同一个请求,有时需要处理多阶段进程、应用程序会话和预请求令牌。同样,最好是将这个工具与其他有用的工具(如代理服务器与爬虫)整合起来,避免来回剪切和粘贴信息。

Burp Intruder是唯一能够执行所有这些功能的工具。它专门为通过最少的配置实施各种自动化定制攻击而设计,并且在输出结果中提供大量细节,帮助迅速确定“触点”和其他反常现象。它还可与其他Burp Suite工具完全整合。例如,可以在代理服务器中拦截一个请求,将它提交给Intruder进行模糊测试,并在几秒钟内确定前面示例中描述的各种漏洞。

下面描述Burp Intruder的基本功能与配置,然后分析使用它执行自动化定制攻击的一些示例。

安置有效载荷

Burp Intruder使用一个类似于JAttack的概念型模型,在请求的特定位置安置有效载荷,并使用一个或几个有效载荷来源。然而,它的功能并不仅限于将有效载荷字符串插入到请求参数值中;有效载荷可安置在参数值的某个局部位置或参数名中,也可以安装在请求消息头或主体的任何位置。

确定以某个特殊请求作为攻击对象后,Burp Intruder使用一组标记定义每个有效载荷位置,指明插入有效载荷的起始点与结束点,如图14-1所示。

图14-1 安置有效载荷

在某个位置插入有效载荷时,标记之间的任何文本将被有效载荷重写。如果没有插入有效载荷,就提交标记间的文本。为便于一次测试一个参数,同时将其他参数保持原样,这样做是必要的。这一做法与对应用程序进行模糊测试时完全相同。单击auto按钮将指示Intruder在所有URL、cookie和主体参数值中设定有效载荷位置,从而将在JAttack中需要手动操作的任务自动化。

sniper攻击类型是最常见的一种攻击类型,它的作用与JAttack的请求引擎相同:一次针对一个有效载荷位置,在那个位置提交所有有效载荷,然后转向下一个位置。其他攻击类型允许使用几个有效载荷,以不同的方式一次针对几个位置进行攻击。

选择有效载荷

准备攻击的下一个步骤是选择将要在指定位置插入的有效载荷。Intruder包含大量用于生成攻击有效载荷的内置功能。

预先设置与可配置的数据列表。

根据任何语法模式对有效载荷进行定制迭代。例如,如果应用程序使用ABC45D形式的用户名,那么可以使用定制迭代器遍历所有可能的用户名。

字符与大小写替换。根据最初的有效载荷列表,Intruder可修改单个的字符及其大小写,以生成它们的变化形式。这项功能在对密码实施蛮力攻击时非常有用,例如,字符串password可修改为p4ssword、passw0rd、Password、PASSWORD等。

数字可用于遍历文档ID、会话令牌等。数字可为十进制或十六进制、整数或分数、按顺序排列、逐步递增或完全随机。当知道一些有效值的大小,但无法确定推断这些值的任何可靠模式时,在一个指定的范围内生成随机数字可用于搜索“触点”。

某些情况下,日期和数字有着相同的用途。例如,如果登录表单要求输入出生日期,那么就可以使用这项功能对指定范围内的所有有效值实施蛮力攻击。

可使用非法Unicode编码,通过提交恶意字符的编码形式避开一些输入过滤。

字符块可用于探查缓冲区溢出漏洞(请参阅第16章了解相关内容)。

蛮力功能可用于生成一个特殊字符集在指定长度范围内的所有排列组合。许多时候,由于它能生成大量的请求,使用这种功能是我们能够依赖的最后一个办法。例如,对仅包含小写字母字符的6位数密码进行蛮力攻击,将生成300多万个排列组合;仅通过远程访问应用程序几乎不可能提交如此数目庞大的请求。

“字符打乱”和“位翻转”功能,可用于系统化地操纵参数的现有值的各个部分,以探查应用程序如何处理各种难以察觉的修改(请参阅第7章)。

除有效载荷生成功能外,还可以配置一些规则,在使用有效载荷值之前对每个值进行任意处理。这包括字符串和大小写修改、各种编解码方案以及散列操作。这样做有助于在各种非常规情况下构建有用的有效载荷。

默认情况下,在请求中插入字面量字符会使请求失效,Burp Intruder会对这些字符进行URL编码。

配置响应分析

在实施攻击前,渗透测试员应当确定想要分析的服务器响应属性。例如,当枚举标识符时,可能需要在每个响应中搜索一个特殊的字符串;在模糊测试时,攻击者也许希望扫描大量常见的错误消息等。

默认情况下,Intruder会在它的结果表中记录HTTP状态码、响应长度、服务器设定的任何cookie以及收到响应的时间。和JAttack一样,还可以配置Burp Intruder对应用程序的响应进行其他一些自定义分析,以帮助确定表明存在漏洞或值得深入调查的数据。可以指定在响应中搜索的字符串或正则表达式;可以设定自定义字符串,控制从服务器的响应中提取数据;还可以指示Intruder检查每个响应是否包含攻击字符串本身,以帮助确定跨站点脚本和其他响应注入漏洞。

确定有效载荷位置、有效载荷来源以及需要对服务器响应进行哪些分析后,渗透测试员就可以实施攻击。下面简要说明如何使用Intruder实施一些常见的自动化定制攻击。

攻击1:枚举标识符

假设正以一个支持匿名用户自我注册的应用程序为攻击目标。创建一个账户,登录应用程序,访问最少量的功能。在这个阶段,应用程序的会话令牌是一个明显的攻击对象。连续进行几次登录,会得到以下令牌:

按照第7章描述的步骤分析这些令牌后会发现:很明显,令牌中几乎有一半的内容没有发生变化;但是,令牌的第二部分实际上并未被应用程序处理。完全修改这个部分并不会使令牌失效。而且,虽然这些令牌并不严格按顺序排列,但最后一部分明显以某种方式向上递增。根据这些信息,渗透测试员也许能够对应用程序实施会话劫持攻击。

要利用自动技巧实施这个攻击,需要找到一个可用于探查有效令牌的请求/响应对。通常,任何访问应用程序通过验证的页面的请求都可用于这种目的。假设以每名用户登录后显示的主页为攻击对象:

由于已经知道会话令牌的结构及应用程序如何处理令牌,因此,只需令牌的最后一个部分就可实施攻击。实际上,根据前面确定的令牌序列,最有效的初步攻击只需修改令牌最后的几位数字。因此,用Intruder配置唯一一个有效载荷位置,如图14-2所示。

图14-2 设定一个定制的有效载荷位置

有效载荷需要遍历最后三位的所有可能值。令牌使用的可能是十六进制字符集:0~9与a~f。因此,配置一个有效载荷来源生成0x000~0xfff之间的所有十六进制数字,如图14-3所示。

图14-3 配置数字式有效载荷

在枚举有效会话令牌的攻击中,通常可以直接确定“触点”。在当前的示例中已经确定:如果提交一个有效的令牌,应用程序会返回一个HTTP 200响应;否则就返回一个退回登录页面的HTTP 302重定向。因此,测试员不必为攻击配置任何定制的响应分析。

实施攻击后,Intruder将迅速循环提出所有请求。攻击结果在一个表格中显示,可以单击表的列标题,根据该列的内容对结果进行分类。按状态码分类可帮助轻松确定已经发现的有效令牌,如图14-4所示。

图14-4 分类攻击结果以迅速确定“触点”

攻击取得成功。现在渗透测试员可以选择任何返回HTTP 200响应的有效载荷,用这个有效载荷代替会话令牌最后的三个数字,从而劫持其他应用程序用户的会话。然而,对结果表进行仔细分析后会发现:由于应用程序向不同用户显示的主页几乎完全相同,因而大多数HTTP 200响应的长度也大致相同。然而,其中有两个响应要更长一些,表示应用程序向它们返回了一个不同的页面。

可以在Intruder中双击其中一个结果,以HTTP源代码或HTML格式完整显示服务器的响应。之后会发现,与主页相比,较长的主页中包含大量菜单选项。据此推测,这两个劫持的会话似乎属于更高权限的用户。

尝试访问

http://mdsec.net/auth/502/

 提示 事实证明,响应长度往往是一个明显的指标,指出值得进一步调查的反常响应。在上面的示例中,一个长度不同的响应会让测试员发现在设计攻击时未曾预料到的管理员会话令牌。因此,即使其他属性提供了一个可靠的“触点”指标(如HTTP状态码),还是应始终检查响应长度列,以确定其他有用的响应。

攻击2:获取信息

进一步浏览到应用程序的已通过验证的区域,我们注意到应用程序在URL参数中使用索引号来标识用户请求的功能。例如,以下URL用于显示当前用户的“用户资料”页面:

这种行为提供了一个极好的机会,可用于搜集之前尚未发现及未获得正确授权的功能。为此,可以使用Burp Intruder遍历一系列可能的pageid值,并提取出所发现的每个页面的标题。

在这种情况下,通常较为明智的做法,是在某个已知包含有效值的数值范围内开始内容搜集。为此,可以将有效载荷位置标记设置为针对pageid的最后两位数,如图14-5所示,并生成00到99范围内的有效载荷。

图14-5 安置有效载荷

攻击者可以配置Intruder使用“提取Grep”功能以可用的方式截取所有这些信息。其运作方式与JAttack的提取功能类似——只需指定想要提取的数据之前的表达式,如图14-6所示。

图14-6 配置“提取Grep”功能

实施此攻击将迅速遍历pageid参数最后两位的所有可能值,并显示每个响应中的页面标题,如图14-7所示。从图中可以看出,一些响应似乎包含有用的管理功能。此外,一些响应为指向其他URL的重定向,这需要进一步调查。为此,可以配置Intruder实施攻击,以提取这些重定向的目标,或者自动访问这些重定向,并显示最终的响应中的页面标题。

图14-7 遍历功能索引值并提取每个生成的页面的标题

尝试访问

http://mdsec.net/auth/502/

攻击3:应用程序模糊测试

除利用日志功能提取有用的信息外,当然还可以探查应用程序中是否存在常见的漏洞。为确保测试合理,攻击者应该测试所有的参数和请求,从登录请求开始。

为迅速对前面的请求进行模糊测试,必须在所有请求参数中设定有效载荷位置。只需单击position选项卡上的auto按钮即可完成这项操作,如图14-8所示。

图14-8 配置Burp Intruder对登录请求进行模糊测试

和使用JAttack实施模糊测试攻击一样,接下来需要手动检查结果表,确定任何值得深入调查的反常现象,如图14-9所示。与前面的攻击中一样,可以单击列标题,以各种方式对响应进行分类,从而迅速确定有用的数据。

图14-9 对一个请求进行模糊测试得到的结果

对测试结果进行初步分析可以得出结论,应用程序似乎易于受到SQL注入。在有效载荷位置1和2提交一个单引号后,应用程序会返回另一个响应,其消息中包含字符串quotation和syntax。这种行为明确表示,需要进行手动调查才能确定和利用其中的漏洞。

尝试访问

http://mdsec.net/auth/502/

 提示 可以右键单击任何看似有用的结果,将响应发送至Burp Repeater工具。这个工具允许手动修改请求,然后多次重新发布这个请求,以测试应用程序如何处理不同的有效载荷、探查避开过滤的方法或者实施具体的攻击。

实施自动化的限制

本章目前介绍的各种技巧在许多应用程序中都可以使用,而不会出现任何问题。但是,在其他情况下,可能存在各种导致无法实施定制自动化攻击的障碍。

通常,实施自动化的限制主要分为以下两类。

会话处理机制,这类机制会防御性地终止响应意外请求的会话,采用因请求而异的反CSRF令牌之类的临时参数值(请参阅第13章了解相关内容),或涉及多阶段过程。

CAPTCHA控件,这类控件旨在阻止自动工具访问特定应用程序功能,如注册新用户账户的功能。

我们将讨论以上每一种情形,并介绍通过优化自动工具或查找应用程序的防御缺陷,从而突破实施自动化的限制的方法。

会话处理机制

许多应用程序采用会话处理机制和其他有状态功能来防止自动测试。以下是一些可能会形成限制的情形。

测试请求时,应用程序会出于防御或其他目的,终止用于测试的会话,剩下的测试也随之失效。

某个应用程序功能使用必须随每个请求提供的不断变化的令牌(例如,为防止请求伪造攻击)。

所测试的请求在多阶段过程中显示。只有在首先提出一系列其他请求,应用程序进入适当的状态时,该请求才会得到正确处理。

基本上,通过针对应用程序使用的各种机制来优化自动化技巧,通常可以突破这类妨碍。如果在JAttack代码中写入自己的测试代码,就可以直接突破特定的会话处理或多阶段机制。但是,这种方法可能较为复杂,并且不能有效地移植到大型应用程序中。实际上,如果在处理每一个新问题时都需要编写新的定制代码,这本身就是实施自动化的一大限制,这种方法甚至不如较慢的手动技巧。

Burp Suite的会话处理支持

幸好,Burp Suite提供了一系列功能,可用于尽可能轻松地处理所有这些情形,以便于渗透测试员继续进行测试,而由Burp在后台无缝处理各种限制。这些功能基于以下组件:

cookie库;

请求宏;

会话处理规则。

我们将简要介绍如何组合使用这些功能来克服实施自动化的限制,从而在上述各种情形下继续进行测试。有关详细的帮助信息,请参阅Burp Suite的在线文档。

cookie库

Burp Suite维护自己的cookie库,用于追踪浏览器和Burp自己的工具使用的应用程序cookie。渗透测试员可以配置Burp自动更新cookie库的方式,还可以直接查看和编辑其内容,如图14-10所示。

图14-10 Burp Suitecookie库

就其本身而言,该cookie库并不执行任何操作,但Burp的其他会话处理支持组件需要用到它追踪的关键值。

请求宏

宏是预先定义的一个或多个请求。宏可用于执行各种会话相关的任务,包括:

提取应用程序页面(如用户的主页),以检查当前会话是否仍然有效;

执行登录,以获取新的有效会话;

获取令牌或nonce,以在其他请求中用作参数;

在多阶段过程中扫描请求或对其进行模糊测试时,需要提前执行一些请求,以便于应用程序进入将接受目标请求的状态。

使用浏览器可以录制宏。在定义宏时,Burp会显示Burp Proxy的历史记录视图,从中可以选择定义宏所需的请求。这时可以选择以前提出的请求,或重新录制宏并从该历史记录中选择新项目,如图14-11所示。

图14-11 在Burp Suite中录制请求宏

可以为宏中的每个项目配置以下设置,如图14-12所示:

图14-12 为宏项目配置cookie和参数处理方式

是否应将cookie库中的cookie添加到请求中;

是否应将在响应中收到的cookie添加到cookie库中;

对于请求中的每个参数,是应使用预设值,还是使用宏内以前的响应获取的值。

在某些多阶段过程以及应用程序大量使用反CSRF令牌的情况下,从宏内以前的响应获取参数值的功能特别有用。在定义新宏时,Burp会通过识别某些参数,尝试自动查找任何此类关系,这些参数的值可以从以前的响应中(表单字段值、重定向目标、链接中的查询字符串)确定。

会话处理规则

用于定义会话处理规则的工具是Burp Suite的主要会话处理支持组件,该工具使用cookie库和请求宏来克服实施自动化的特定限制。

每个规则由范围(规则的应用范围)和操作(规则执行的操作)组成。对于Burp提出的每个出站请求,将确定哪些定义的规则在请求的应用范围内,并按顺序执行所有规则的操作。

每个规则的范围可以基于所处理的请求的以下任何或全部特性进行定义,如图14-13所示:

图14-13 配置会话处理规则的范围

提出请求的Burp工具;

请求的URL;

请求中参数的名称。

每个规则可以执行一项或多项操作,如图14-14所示,包括:

图14-14 配置会话处理规则的操作

从会话处理cookie库中添加cookie;

设置特定的cookie或参数值;

检查当前会话是否有效,并根据结果执行相应的子操作;

运行宏;

提示用户在浏览器中执行会话恢复。

所有这些操作都可以进行灵活配置,并且能够以任意方式组合使用,处理几乎全部会话处理机制。利用运行宏并根据结果更新指定cookie和参数值的功能,渗透测试员可以在注销后重新登录应用程序。利用指示在浏览器中执行会话恢复的提示,渗透测试员可以处理需要键入物理令牌中的数字或破解CAPTCHA拼图的登录机制(将在下一节介绍)。

通过使用不同范围和操作创建多个规则,可以定义一系列Burp将应用于不同URL和参数的行为。例如,已知某应用程序经常终止响应意外请求的会话,并且大量使用一个__csrftoken反CSRF令牌。如果要测试该应用程序,可以定义以下规则,如图14-15所示。

图14-15 一组会话处理规则,可用于处理应用程序使用的会话终止机制和反CSRF令牌

对于所有请求,从Burp的cookie库中添加cookie。

对于指向应用程序的域的请求,验证应用程序的当前会话是否仍处于活动状态。如果是,则运行宏重新登录到该应用程序,并使用生成的会话令牌更新cookie库。

对于指向包含__csrftoken参数的应用程序的请求,首先运行宏来获取有效的__csrftoken值,然后在提出请求时使用该值。

要将Burp的会话处理功能应用于实际的应用程序,通常需要进行复杂的配置,并且易于出错。Burp提供了一项追踪功能,可用于解决会话处理配置问题。此功能将显示Burp对某个请求应用会话处理规则所执行的所有步骤,以便于查看Burp到底如何更新和提出请求,并确定配置是否按预期方式运行。会话处理追踪功能如图14-16所示。

图14-16 Burp的会话处理追踪功能,可用于监控和调试会话处理规则

对测试目标应用程序所需的规则和宏进行配置和测试后,渗透测试员可以正常继续手动和自动测试,就好像测试限制并不存在一样。

CAPTCHA控件

CAPTCHA控件用于防止攻击者自动使用某些应用程序功能。注册电子邮件账户和发表博客文章之类的功能通常使用此类控件,以减少垃圾信息。

CAPTCHA是Completely Automated Public Turing test to tell Computers and Humans Apart(全自动区分人类和计算机的图灵测试)的缩写。通常,这些测试采用一个包含外形扭曲的单词的拼图,用户必须读取并在提交表单的字段中输入该单词。此类拼图还包括识别特定的动物或植物、图像方向等。

对人类而言,解决CAPTCHA拼图相当容易,但对计算机而言却非常困难。由于突破这些控件会给垃圾邮件发送者带来经济利益,因而相关机构不断增加CAPTCHA拼图的难度,导致人类越来越难以读取这些拼图,如图14-17所示。由于人类与计算机解决CAPTCHA拼图的能力相当,因此,作为针对垃圾邮件的一项防御措施,这些拼图可能会逐渐失效,并可能会被废弃。它们还会造成当前并未完全解决的访问性问题。

图14-17 一个CAPTCHA拼图

CAPTCHA拼图可以通过各种方式进行破解,仅一部分拼图适用于执行安全测试。

攻击CAPTCHA控件

要了解如何避开CAPTCHA控件,最有效的方法是了解此类拼图如何被传送至用户,以及应用程序如何处理用户的答案。

令人惊奇的是,有大量CAPTCHA控件以文本形式向用户披露拼图答案。披露答案的形式包括:

拼图图像通过URL加载,而拼图答案却为该URL的参数,或将图像名设置为CAPTCHA答案;

拼图答案存储在隐藏表单字段中;

拼图答案出现在HTML注释或其他位置(用于调试目的)。

在这些情况下,攻击者可以通过脚本攻击轻松获取包含拼图答案的响应,并在下一个攻击请求中提交该答案。

尝试访问

http://mdsec.net/feedback/12/

http://mdsec.net/feedback/24/

http://mdsec.net/feedback/31/

CAPTCHA控件的一个更常见的漏洞在于,攻击者可以在某次手动解决拼图,然后在多个请求中重复提交其答案。正常情况下,每个拼图应仅用一次,应用程序应在收到提交的答案后废弃该拼图。如果不这样做,攻击者就可以一次性以正常方式解决拼图,然后使用其答案不限数量地自动提出请求。

尝试访问

http://mdsec.net/feedback/39/

 注解 一些应用程序有意提供破解CAPTCHA的代码路径,以便于某些授权自动进程使用。通常,在这些情况下,无须提交相关参数名就可以避开CAPTCHA。

自动破解CAPTCHA拼图

理论上,计算机可以破解大多数CAPTCHA拼图;实际上,许多主流拼图算法都以这种方式被破解。

对于包含扭曲单词的标准拼图,破解拼图的过程如下:

(1)删除图像噪声;

(2)将图像分割成单个字母;

(3)识别每个部分包含的字母。

采用最新技术,计算机能够相当有效地删除图像噪声,并识别已被正确分割的字母。这时,将图像分割成字母是最重要的挑战,特别是在字母重叠并且高度扭曲的情况下。

对于可以轻松分割成字母的简单拼图,可以使用某种自行编写的代码来删除图像噪声,并将文本传送到现有的OCR(光学文字识别)库中来进行识别。对于非常难以分割的复杂拼图,各种研究项目已经成功破解了一些知名Web应用程序的CAPTCHA拼图。

对于其他类型的拼图,则需要针对拼图图像的特点采用不同的方法。例如,对于要求识别动物或物体方向的拼图,则需要使用实时图像数据库,以便于在多个拼图中重复使用。但是,如果这个数据库非常小,攻击者就可以通过手动破解数据库中的拼图来达到成功实施攻击的目的。即使为了使每一幅重复使用的图像在计算机看来会有所不同,应用程序对图像应用了噪声和其他扭曲,但攻击者通常会采用模糊图像散列和彩色直方图比较,将给定拼图中的图像与已手动破解的图像进行匹配。

Microsoft的Asirra拼图使用一个包含数百万幅猫和狗图像的数据库,这些图像来自现实世界中可领养的宠物目录。我们在下一节将讲到,在庞大的经济利益的刺激下,即使这样的数据库也可能会被攻击者快速破解。

值得注意的是,在所有这些情况下,要有效破解CAPTCHA控件,攻击者并不需要完全准确地破解拼图。例如,即使某个攻击仅正确破解了10%的拼图,但该攻击仍然能够非常有效地实施自动安全测试,或传送垃圾邮件(视具体情况而定)。通常,与手动攻击相比,即使自动攻击需要提交十倍以上的请求,后者实施起来仍然更加快捷和轻松。

尝试访问

http://mdsec.net/feedback/8/

使用人类破解者

有时,需要破解大量CAPTCHA拼图的犯罪分子会采用一些并不适用于执行Web应用程序安全测试的技巧,如下所示。

攻击者可以使用某个貌似善意的Web站点诱使人类CAPTCHA代理破解目标应用程序传递的拼图。通常,攻击者会利用竞赛奖励或免费访问色情内容来吸引用户。用户填写注册表单后,将会看到一个从目标应用程序实时提取的CAPTCHA拼图。用户破解该拼图后,攻击者会将其提供的答案提交给目标应用程序。

攻击者可以向发展中国家的人类CAPTCHA工蜂支付费用,由后者破解大量拼图。一些公司提供这种服务,每破解1000个拼图付费不到1美元。

小结

攻击一个Web应用程序所需执行的绝大多数任务必须根据应用程序的行为以及与它交互和控制它的方法来确定。为此需要经常进行手动操作,分别提交专门设计的请求并审查应用程序对这些请求的响应。

从概念上讲,我们在本章中描述的技巧非常简单。它们包括利用自动技巧使上述定制任务更加轻松、快捷、高效。事实上,渗透测试员可以对想要执行的任何手动操作自动化:使用计算机的处理能力与可靠性能攻击目标程序的漏洞与弱点。

在某些情况下,在直接应用自动化技巧时,可能会遇到各种障碍。但是,多数情况下,这些障碍都可以通过优化自动化工具或查找应用程序防御机制中的缺陷加以克服。

虽然概念上非常简单,但有效使用自动化定制攻击仍然需要运用经验、技能,并发挥想象。有各种工具可帮助渗透测试员实施攻击,或者他们也可以编写自己的工具。但任何工具也替代不了人类的智慧,思考方式的不同是真正熟练的Web应用程序黑客与纯粹爱好者之间的最大区别。掌握本书其他各章描述的所有技巧后,读者应该回过头来温习本章的主题,练习如何将自动化定制攻击方法应用于那些技巧中。

问题

欲知答案,请参考http://mdsec. net/wahh。

(1)指出使用自动技巧在应用程序中枚举标识符时用到的3个标识符“触点”。

(2)对于下面的每一类漏洞,指出一个可用于确定该漏洞的模糊测试字符串:

(a)SQL注入

(b)OS命令注入

(c)路径遍历

(d)脚本文件包含

(3)当对一个包含各种不同参数的请求进行模糊测试时,为何要在保持其他参数不变的情况下轮流针对每一个参数进行测试?

(4)假设在一个试图对登录功能实施蛮力攻击以找到其他账户证书的自动攻击中,无论提交的是有效证书还是无效证书,应用程序都返回一个指向相同URL的HTTP重定向。在这种情况下,使用什么方法探查“触点”最为可靠?

(5)当使用自动攻击从应用程序中获取数据时,想要的信息常常位于一个静态字符串之后,渗透测试员可以轻易截获这些数据。例如:

但是,在其他情况下发现事实并非如此,需要的信息之前的数据可能会发生变化。这时该如何设计一个自动攻击来满足需要?

浙ICP备11005866号-12