Web应用程序黑客的方法论来自书本 The Web Application Hacker’s Handbook
漏洞的许多重要类别是由用户的意外输入触发的,并且可以出现在应用程序中的任何位置。
探测应用程序中这些漏洞的有效方法是使用一组攻击字符串来模糊每个参数到每个请求。
7.1 模糊测试所有请求参数(Fuzz All Request Parameters)
7.1.1
查看您的应用程序映射练习的结果,并识别提交服务器端应用程序处理的参数的每个不同的客户端请求。相关参数包括URL查询字符串中的项目,请求正文中的参数和HTTP cookie。还应包括观察到的对应用程序行为有影响的任何其他用户输入项,例如Referer或User-Agent标头。
7.1.2
要模糊化参数,可以使用自己的脚本或现成的模糊化工具。例如,要使用Burp Intruder,请将每个请求依次加载到工具中。一种简单的方法是在Burp Proxy中拦截请求,然后选择Send to Intruder操作,或右键单击Burp Proxy历史记录中的项目,然后选择此选项。使用此选项可使用请求的内容以及正确的目标主机和端口来配置Burp Intruder。 它还会自动将所有请求参数的值标记为有效负载位置,以准备进行模糊测试。
7.1.3
使用有效负载选项卡,配置一组合适的攻击有效负载,以探测应用程序中的漏洞。您可以手动输入有效负载,从文件中加载它们,或选择预设的有效负载列表之一。对应用程序内的每个请求参数进行模糊处理通常需要发出大量请求并检查结果是否存在异常。如果攻击字符串集太大,可能会适得其反,并产生大量的输出供您查看。因此,明智的方法是针对一系列常见漏洞,这些漏洞通常可以在对特定制作的输入的异常响应中容易地检测到,并且通常在应用程序中的任何位置而不是特定功能类型中显现出来。这是一组合适的有效载荷,可用于测试一些常见类别的漏洞:
SQL Injection
'
'--
'; waitfor delay '0:30:0'--
1; waitfor delay '0:30:0'--
XSS and Header Injection
xsstest
"><script>alert('xss')</script>
Path Traversal
../../../../../../../../../../etc/passwd
../../../../../../../../../../boot.ini
..\..\..\..\..\..\..\..\..\..\etc\passwd
..\..\..\..\..\..\..\..\..\..\boot.ini
Script Injection
;echo 111111
echo 111111
response.write 111111
:response.write 111111
File Inclusion
http://<your server name>/
http://<nonexistent IP address>/
7.1.4
前面所有有效载荷均以其原义格式显示。字符 ?
, ;
, &
, +
, =
,和空格
需要进行URL编码,因为它们在HTTP请求中具有特殊含义。默认情况下,Burp Intruder对这些字符执行必要的编码,因此请确保未禁用此选项。要在早期定制后将所有选项恢复为默认值,请选择Burp-> Restore Defaults。
7.1.5
在Burp Intruder的Grep函数中,配置一组合适的字符串以在响应中标记一些常见的错误消息。比如:
error
exception
illegal
invalid
fail
stack
access
directory
file
not found
varchar
ODBC
SQL
SELECT
111111
请注意,包含字符串111111来测试成功的脚本注入攻击。步骤7.1.3中的有效负载涉及将此值写入服务器的响应中。
7.1.6
还选择“有效负载Grep”选项以标记包含有效负载本身的响应,表明潜在的XSS或标头注入漏洞。
7.1.7
在您指定的第一个文件包含有效负载中主机上设置Web服务器或netcat侦听器。这可以帮助您监视由于成功的远程文件包含攻击而导致从服务器收到的连接尝试。
7.1.8
发起攻击。完成后,查看结果以发现异常响应,表明存在漏洞。检查HTTP状态代码,响应长度,响应时间,配置的表达式的外观以及有效负载本身的外观是否存在差异。您可以单击结果表中的每个列标题,以按该列中的值对结果进行排序(然后按住Shift单击以对结果进行反向排序)。这使您可以快速识别与其他结果不同的任何异常。
7.1.9
对于模糊测试结果指示的每个潜在漏洞,请参考此方法的以下部分。它们描述了您应针对每种类型的问题采取的详细步骤,以验证漏洞的存在并成功利用它。
7.1.10
配置Burp Intruder对单个请求执行模糊测试后,您可以在应用程序中的其他请求上快速重复相同的测试。只需在Burp代理中选择每个目标请求,然后选择“Send to Intruder”选项。 然后立即使用现有攻击配置在Intruder中发起攻击。这样,您可以在单独的窗口中同时启动大量测试,并在每个测试完成工作时手动查看结果。
7.1.11
如果您的映射练习发现了任何带外输入通道,可以将用户可控制的输入引入到应用程序的处理中,则应该在这些输入通道上执行类似的模糊测试。提交旨在在Web应用程序中进行处理时触发常见漏洞的各种精心设计的数据。根据输入通道的性质,您可能需要为此创建一个自定义脚本或其他工具。
7.1.12
除了您自己对应用程序请求的模糊处理之外,如果您有权访问自动化的Web应用程序漏洞扫描程序,还应该针对目标应用程序运行它,以提供与自己的发现进行比较的基础。
7.2 测试SQL注入(Test for SQL Injection)
7.2.1
如果步骤7.1.3中列出的SQL攻击字符串导致任何异常响应,请手动探测应用程序对相关参数的处理,以确定是否存在SQL注入漏洞。
7.2.2
如果返回了任何数据库错误消息,请调查其含义。使用第9章中的SQL Syntax and Error Reference
部分可帮助解释某些常见数据库平台上的错误消息。
7.2.3
如果在参数中提交单引号引起错误或其他异常行为,请提交两个单引号。如果此输入导致错误或异常行为消失,则该应用程序可能容易受到SQL注入的攻击。
7.2.4
尝试使用常见的SQL字符串连接器函数来构造与某些良性输入等效的字符串。如果这引起与原始良性输入相同的响应,则该应用程序可能很容易受到攻击。例如,如果原始输入是表达式FOO,则可以使用以下项目执行此测试(在第三个示例中,请注意两个引号之间的空格):
'||'FOO
'+'FOO
' 'FOO
与往常一样,请确保对HTTP请求中具有特殊含义的字符(例如+
和空格
)进行URL编码。
7.2.5
如果原始输入为数字,请尝试使用与原始值等效的数学表达式。例如,如果原始值为2,请尝试提交1 + 1或3-1。如果应用程序以相同的方式响应,则可能会受到攻击,特别是如果数字表达式的值对应用程序的行为产生系统性影响时。
7.2.6
如果前面的测试成功,则可以通过使用特定于SQL的数学表达式构造特定值来进一步确保涉及SQL注入漏洞。如果可以通过这种方式系统地操纵应用程序的逻辑,那么几乎可以肯定它很容易受到SQL注入的攻击。例如,下面的两个项都是相当于数2:
67-ASCII('A')
51-ASCII(1)
7.2.7
如果使用waitfor
命令的模糊测试用例中的任何一个导致应用程序响应之前出现异常的时间延迟,这是一个强烈的迹象,表明数据库类型是MS-SQL
,应用程序很容易受到SQL注入
的攻击。手动重复测试,在waitfor参数中指定不同的值,并确定响应所花费的时间是否与该值有系统地变化。请注意,您的攻击有效负载可能被插入到多个SQL查询中,因此所观察到的时间延迟可能是所指定值的倍数。
7.2.8
如果应用程序容易受到SQL注入的攻击,请考虑哪些攻击是可行的,哪些攻击可能有助于实现目标。执行下列任何攻击所需的详细步骤请参阅第9章:
- 修改
WHERE
子句中的条件来更改应用程序的逻辑(例如,通过注入or 1=1--
绕过登录)。 - 使用
UNION
操作符注入一个任意的SELECT
查询,并将结果与应用程序的原始查询结合起来。 - 使用特定于数据库的SQL语法对数据库类型进行指纹识别。
- 如果数据库类型是
MS-SQL
,应用程序在其响应中返回ODBC
错误消息,则利用这些消息枚举数据库结构并检索任意数据。 - 如果无法找到直接检索任意注入查询结果的方法,请使用以下高级技术来提取数据;
- 检索数字形式的字符串数据,一次一个字节。
- 使用带外信道。
- 如果您可以基于一个任意条件导致不同的应用程序响应,那么可以使用苦艾酒一次提取一位任意数据。
- 如果可以根据单个任意条件触发时间延迟,则可以利用这些延迟一次检索一位数据。
- 如果应用程序正在阻塞执行特定攻击所需的某些字符或表达式,请尝试第9章中描述的各种绕过输入筛选器的技术。
- 如果可能,通过利用数据库中的任何漏洞或强大的功能,升级对数据库和底层服务器的攻击。
7.3 XSS和其他响应注入测试(Test for XSS and Other Response Injection)
7.3.1 识别反映的请求参数(Identify Refl ected Request Parameters)
7.3.1.1
通过单击有效负载Grep列对模糊测试的结果进行排序,并识别与步骤7.1.3中列出的XSS有效负载相对应的任何匹配项。在这些情况下,XSS测试字符串在应用程序的响应中未经修改地返回。
7.3.1.2
对于每一种情况,检查应用程序的响应,以找到提供的输入的位置。如果出现在响应体中,则测试XSS漏洞。如果输入出现在任何HTTP报头中,测试报头注入漏洞。如果它用于302响应的Location头,或者如果它用于以其他方式指定重定向,请测试重定向漏洞。请注意,相同的输入可能被复制到响应中的多个位置,并且可能存在不止一种类型的被反射的漏洞。
7.3.2 对受影响的XSS进行测试(Test for Reflected XSS)
7.3.2.1
对于响应体中出现请求参数值的每个地方,请查看周围的HTML,以确定可能的方法来构建输入,以执行任意的JavaScript。例如,您可以将<script>
注入到现有的脚本中,或者将精心设计的值放入标记属性中。
7.3.2.2
使用第12章中描述的不同方法来击败基于签名的过滤器,这可以作为使用精工输入来执行JavaScript的不同方法的参考。
7.3.2.3
尝试向应用程序提交各种可能的攻击,并监视其响应,以确定是否对输入进行了过滤或消毒。如果您的攻击字符串未修改就返回,请使用浏览器最终验证您是否成功执行了任意的JavaScript(例如,通过生成警报对话框)。
7.3.2.4
如果您发现应用程序正在阻塞包含您需要使用的某些字符或表达式的输入,或者正在对某些字符进行HTML编码,请尝试第12章中描述的各种过滤器旁路。
7.3.2.5
如果您在POST请求中发现了一个XSS漏洞,那么仍然可以通过一个包含所需参数的表单和一个自动提交表单的脚本的恶意网站来利用这个漏洞。然而,如果漏洞可以通过GET请求传递,则可以使用更广泛的攻击传递机制。尝试在GET请求中提交相同的参数,看看攻击是否仍然成功。您可以使用Burp代理中的更改请求方法操作来为您转换请求。
7.3.3 测试HTTP头注入(Test for HTTP Header Injection)
7.3.3.1
对于响应标头中出现请求参数值的每个位置,请验证应用程序是否接受包含URL编码的载波返回(%0d
)和换行(%0a
)字符的数据,以及这些字符是否在其响应中未经清除。(注意,您要查找的是实际出现在服务器响应中的换行字符本身,而不是URL编码的对应字符。)
7.3.3.2
如果在提供精雕细琢的输入时,服务器的响应标头中出现了新行,则应用程序很容易受到HTTP标头干扰。这可以用来执行各种攻击,如第13章所述。
7.3.3.3
如果您发现在服务器的响应中只返回了两个换行字符中的一个,那么仍然可以根据上下文和目标用户的浏览器来设计一个可用的漏洞。
7.3.3.4
如果发现应用程序阻塞了包含换行字符的输入,或者在响应中对这些字符进行了消毒,请尝试以下输入项来测试过滤器的有效性:
foo%00%0d%0abar
foo%250d%250abar
foo%%0d0d%%0a0abar
7.3.4 开放重定向测试(Test for Open Redirection)
7.3.4.1
如果反射的输入用于指定某种重定向的目标,则测试是否可以提供导致任意重定向到外部网站的精心设计的输入。如果是这样,就可以利用这种行为为钓鱼式攻击增加可信度。
7.3.4.2
如果应用程序通常将一个绝对URL作为参数的值传输,请修改URL中的域名,并测试应用程序是否将您重定向到不同的域。
7.3.4.3
如果该参数通常包含一个相对URL,则将其修改为另一个域的绝对URL,并测试应用程序是否将您重定向到该域。
7.3.4.4
如果应用程序在执行重定向之前对参数进行一些验证,以防止外部重定向,这通常容易受到旁路的影响。尝试第13章中描述的各种攻击来测试过滤器的健壮性。
7.3.5 存储攻击测试(Test for Stored Attacks)
7.3.5.1
如果应用程序存储用户提供的输入项,然后在屏幕上显示这些输入项,那么在对整个应用程序进行模糊化之后,您可能会看到在响应不包含这些字符串的请求时返回了一些攻击字符串。请注意发生这种情况的任何实例,并标识正在存储的数据的原始入口点。
7.3.5.2
在某些情况下,用户提供的数据只有在您完成一个多阶段的过程时才能成功地存储,这在基本的模糊测试中是不会发生的。如果您的应用程序映射测试发现了此类功能,请手动遍历相关流程,并测试存储的数据是否存在XSS漏洞。
7.3.5.3
如果您有足够的访问权限来测试它,那么请仔细检查来自低权限用户的数据最终在更多权限用户的会话中呈现在屏幕上的任何管理功能。此类功能中任何存储的XSS漏洞通常都会导致此类问题
直接到权限升级。
7.3.5.4
测试存储用户提供的数据并将其显示给用户的每个实例。探测这些攻击,以确定XSS和前面描述的其他响应注入攻击。
7.3.5.5
如果您发现一个漏洞,其中一个用户提供的输入显示给其他用户,确定最有效的攻击有效负载,您可以实现您的目标,如会话劫持或请求伪造。如果存储的数据只显示给它的原始用户,那么尝试找到链接您所发现的任何其他漏洞的方法(例如破坏访问控制),从而将攻击注入到其他用户的会话中。
7.3.5.6
如果应用程序允许上传和下载文件,请始终探测此功能,以防存储的XSS攻击。如果应用程序允许HTML、JAR或文本文件,并且不验证或清理它们的内容,那么它几乎肯定是脆弱的。如果它允许JPEG文件,但不验证它们是否包含有效的图像,那么它可能很容易受到针对Internet Explorer用户的攻击。测试应用程序对其支持的每种文件类型的处理,确定浏览器如何处理包含HTML而不是普通内容类型的响应。
7.3.5.7
在一个用户提交的数据显示给其他用户,但是应用程序的过滤器阻止您执行存储的XSS攻击的每个位置,检查应用程序的行为是否使它容易受到现场请求伪造的攻击。
7.4 操作系统命令注入测试(Test for OS Command Injection)
7.4.1
如果在步骤7.1.3中列出的任何命令注入攻击字符串导致应用程序响应之前出现异常的时间延迟,这是应用程序容易受到OS命令注入攻击的强烈指示。重复测试,手动地在-i
或-n
参数中指定不同的值,并确定响应所花费的时间是否与此值有系统地变化。
7.4.2
使用发现的任何一个成功的注入字符串,尝试注入一个更有趣的命令(比如ls
或dir
),并确定是否可以将该命令的结果检索到浏览器。
7.4.3
如果您无法直接检索结果,您可以使用其他选项:
-
您可以尝试打开一个带外通道回到您的计算机。尝试使用TFTP将工具复制到服务器,使用telnet或netcat将反向shell创建回计算机,使用mail命令通过SMTP发送命令输出。
-
您可以将命令的结果重定向到web根目录中的一个文件,然后可以使用浏览器直接检索该文件。例如:
dir > c:\inetpub\wwwroot\foo.txt
7.4.4
如果您找到了一种注入命令和检索结果的方法,您应该确定您的特权级别(通过使用whoami或类似的命令,或尝试将无害的文件写入受保护的目录)。然后,您可能会试图升级特权,获得对敏感应用程序数据的后门访问权,或者攻击其他可以从受攻击的服务器访问的主机。
7.4.5
如果你相信你的输入被传递给操作系统命令,但袭击字符串上市不成功,是否可以使用<
和>
字符直接文件内容的命令输入或直接命令年代输出到一个文件。这可能使您能够读取或写入任意文件内容。如果您知道或能够猜测正在执行的实际命令,请尝试注入与该命令相关的命令行参数,以有用的方式修改其行为(例如,通过在web根目录中指定输出文件)。
7.4.6
如果发现应用程序正在转义执行命令注入攻击所需的某些关键字符,请尝试将转义字符放在每个此类字符之前。如果应用程序没有转义转义字符本身,这通常会导致绕过此防御措施。如果您发现空白字符被阻塞或清除了,那么可以在基于unix的平台上使用$IFS
来代替空格
。
7.5 路径遍历测试(Test for Path Traversal)
7.5.1
对于所执行的每个模糊测试,请查看步骤7.1.3中列出的路径遍历攻击字符串生成的结果。您可以单击Burp入侵者中的有效负载列的顶部,按有效负载对结果表进行排序,并对这些字符串的结果进行分组。对于接收到不寻常的错误消息或长度异常的响应的任何情况,请手动检查响应,以确定它是否包含指定文件的内容或发生异常文件操作的其他证据。
7.5.2
在映射应用程序的攻击面时,您应该注意到任何支持基于用户提供的输入读取和写入文件的功能。除了对所有参数进行模糊化之外,还应该非常仔细地手动测试此功能,以确定存在的任何路径遍历漏洞。
7.5.3
如果参数包含文件名、文件名的一部分或目录,请修改参数的现有值以插入任意子目录和单个遍历序列。例如,如果应用程序提交这个参数:
file=foo/file1.txt
尝试提交这个值:
file=foo/bar/../file1.txt
如果应用程序的行为在这两种情况下是相同的,那么它可能是脆弱的,您应该继续下一步。如果行为不同,应用程序可能会阻塞、剥离或清除遍历序列,从而导致无效的文件路径。尝试使用第10章中描述的编码和其他攻击来绕过过滤器。
7.5.4
如果之前在基本目录中使用遍历序列的测试成功,请尝试使用附加的序列跨出基本目录并访问服务器操作系统上的已知文件。如果这些尝试失败,应用程序可能会在授予文件访问权之前执行各种筛选或检查。您应该进一步了解所实现的控件以及是否存在任何绕过。
7.5.5
应用程序可能正在检查被请求的文件扩展名,并只允许访问某些类型的文件。尝试使用空字节或换行攻击和已知的已接受的文件扩展名来绕过过滤器。例如:
../../../../../boot.ini%00.jpg
../../../../../etc/passwd%0a.jpg
7.5.6
应用程序可能正在检查用户提供的文件路径是否以特定目录或主干开始。尝试将遍历序列附加到已知的已接受的主干之后,以绕过过滤器。例如:
/images/../../../../../../../etc/passwd
7.5.7
如果这些攻击不成功,请尝试组合多个旁路,最初完全在基本目录中工作,以理解适当的过滤器和应用程序处理意外输入的方式。
7.5.8
如果您成功地获得了对服务器上任意文件的读访问权,请尝试检索以下任何文件,这可能使您能够升级您的攻击:
- 操作系统和应用程序的密码文件
- 服务器和应用程序配置文件,以发现其他漏洞或微调不同的攻击
- 包含可能包含数据库凭据的文件
- 应用程序使用的数据源,如MySQL数据库文件或XML文件
- 源代码服务器可执行的页面,执行代码审查,以搜索错误
- 可能包含用户名和会话令牌等信息的应用程序日志文件
7.5.9
如果您成功地获得了对服务器上任意文件的写访问权,请检查以下攻击是否可行,以便升级您的攻击:
- 在用户的启动文件夹中创建脚本
- 修改in.ftpd之类的文件以在用户下次连接时执行任意命令
- 将脚本写入具有执行权限的web目录并从浏览器调用它们
7.6 脚本注入测试(Test for Script Injection)
7.6.1
对于您所执行的每个模糊测试,单独检查字符串111111
的结果(也就是说,前面不包括测试字符串的其余部分)。您可以通过点击111111
Grep字符串的标题来对包含该字符串的所有结果进行分组,从而在Burp Intruder中快速识别这些结果。在有效负载Grep列中查找没有进行检查的。确定的任何情况都可能容易受到脚本命令注入的影响。
7.6.2
检查所有使用脚本注入字符串的测试用例,并识别任何包含脚本错误消息的测试用例,这些错误消息可能表明您的输入正在执行,但是导致了错误。为了执行成功的脚本注入,可能需要对它们进行微调。
7.6.3
如果该应用程序似乎容易受到攻击,请通过注入特定于所使用脚本平台的其他命令来验证这一点。例如,您可以使用类似于为OS命令注入进行模糊测试时使用的攻击有效载荷:
system('ping%20127.0.0.1')
7.7 文件包含测试(Test for File Inclusion)
7.7.1
如果在模糊处理期间从目标应用程序的基础设施接收到任何传入HTTP连接,应用程序几乎肯定会受到远程文件包含的攻击。以单线程和时间限制的方式重复相关测试,以确定究竟是哪些参数导致应用程序发出HTTP请求。
7.7.2
检查文件包含测试用例的结果,并确定导致应用程序响应异常延迟的原因。在这些情况下,可能是应用程序本身容易受到攻击,但是由于网络级过滤器,导致HTTP请求超时。
7.7.3
如果您发现远程文件包含漏洞,请部署一个web服务器,该服务器包含特定于您所针对的语言的恶意脚本,并使用一些用于测试脚本注入的命令来验证您的脚本是否正在执行。