Web应用程序渗透测试方法论 - 测试基于输入的漏洞

应用程序很多重要的漏洞都是由无法预测的用户输入触发

May 13, 2017 - 2 minute read -
web security test

注:原文来自《黑客攻防技术宝典》

test-input-based-vulners

1. 模糊测试所有请求参数

(1) 检查应用程序解析过程中获得的结果,确定所有提交由服务器端应用程序处理的参数的特殊客户端请求。相关参数分别位于URL查询字符串、请求主体及HTTP cookie中。他们还包括所有给应用程序行为造成影响的用户提交数据,如Referer或User-Agent消息头。

(2) 要对这些参数进行模糊测试,可以使用自己的脚本,或者现成的模糊测试工具。

(3) 配置一组适当的攻击有效载荷,在应用程序中探查漏洞。模糊测试应用程序中的第一个请求参数往往需要发布数目庞大的请求,并在结果中查找反常现象。如果设定的攻击字段字符串过多,这样反而达不到预期的目标,甚至生成无数的输入,以致很难对其进行分析。因此,较为明智的做法是,测试一系列可在专门设计的输入的反常响应中轻易确定的常见漏洞,以及出现在应用程序的所有位置而非某些特殊功能中的漏洞。可以使用以下一组有效载荷测试一些常见的漏洞。

SQL Injection
    ‘
    ‘--
    ‘; waitfor delay ‘0:30:0’--
    1; waitfor delay ‘0:30:0’--
XSS and Header Injection
    xsstest
    “><script>alert(‘xss’)</script>
OS Command Injection
    || ping -i 30 127.0.0.1 ; x || ping -n 30 127.0.0.1 &
    | ping –i 30 127.0.0.1 |
    | ping –n 30 127.0.0.1 |
    & ping –i 30 127.0.0.1 &
    & ping –n 30 127.0.0.1 &
    ; ping 127.0.0.1 ;
    %0a ping –i 30 127.0.0.1 %0a
    ` ping 127.0.0.1 `
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>/

(4) 前面所有的有效载荷均以字面量形式显示,?、;、&、+空格与=字符因为在HTTP请求中有特殊含义,需要进行URL编码。

(5) 标记响应中的一些常见的错误消息。

error
exception
illegal
invalid
fail
stack
access
directory
file
not found
varchar
ODBC
SQL
SELECT
111111

(6) 确定包含有效载荷自身的响应,该响应表示可能存在XSS或消息头注入漏洞。

(7) 在通过一个文件包含有效载荷制定的主机上建立一个Web服务器或netcat监听器,监控服务器由于远程文件包含攻击而发出的链接尝试。

(8) 实施并完成攻击后,在结果中查找表示存在漏洞的反常响应。

(9) 参考渗透测试中的每一个问题的详细描述,对模糊测试结果表明可能存在的每一个潜在的漏洞进行确认,同时考虑如何成功地利用这些漏洞。

(10) 用自动化工具,如Burp Intruder、Burp Proxy发动大量测试,在测试完成后手动检查测试结果。

(11) 如果在解析应用程序的过程中确定了带外输入通道,可通过它们向应用程序提交用户可控制的输入。渗透测试员应当通过提交各种旨在触发常见的Web应用程序漏洞的专门设计的数据,对这些输入通道进行类似的模糊测试。根据输入通道的特点,可能需要建立一个定制脚本或其他工具。

(12) 除了手动对应用程序请求进行模糊测试外,如果拥有一个自动化Web应用程序漏洞扫描器,还应当运行该扫描器,对目标应用程序进行自动测试,并比较两方面的测试结果。

2. 测试SQL注入

(1) 如果发现在上面的步骤3中列出的SQL攻击字符串导致任何反常响应,那么应该手动探查,观察应用程序如何处理相关参数,确定其中是否存在SQL注入漏洞。

(2) 如果提交上述字符串返回错误消息,分析这些消息的意义。了解错误消息在常用数据库平台中的含义。

(3) 如果在请求中提交一个单引号导致错误或出现其他反常行为,可尝试提交两个单引号;如果这种输入是错误或异常行为消失,应用程序可能易于受到SQL注入。

(4) 设法使用常用的SQL字符串连接符函数构建一个等同于良性输入的字符串。如果提交这个字符串得到与提交原始的良性输入相同的响应,那么应用程序可能易于受到攻击。例如,如果原始输入为表达式FOO,可以使用下面的输入测试:

‘||’FOO
‘+’FOO
‘ ‘FOO

同样,应对在HTTP请求中具有特殊意义的字符进行URL编码。

(5) 如果原始输入为数字字符,尝试使用一个其结果等于原始值的数学表达式。例如,如果原始值为2,尝试提交1+1或3-1。如果应用程序做出相同的响应,表示它易于受到攻击;如果数字表达式对应用程序的行为造成系统性的影响,那么应用程序久特别容易受到攻击。

(6) 如果前面的测试取得成功,可以通过使用针对SQL的数学表达式构造一个特殊的值,进一步确定SQL注入漏洞是否存在。如果可以通过这种方法系统性地控制应用程序的逻辑,那么几乎可以肯定应用程序易于受到SQL注入攻击。例如,下面两个表达式的结果都等于2:67-ASCII(‘A’),51-ASCII(1)

(7) 如果使用waitfor命令进行的模糊漏洞测试导致应用程序在进行响应时出现反常的时间延迟,那么所使用的数据库为MS-SQL,且应用程序易于受到SQL注入攻击。手动重复测试,在waitfor参数中制定不同的值,确定响应时间是否随着这个值而发生系统性地变化。请注意,可以在几个SQL查询中插入攻击有效载荷;这时观察到的时间延迟为指定值的固定数倍。

(8) 如果应用程序易于受到SQL注入攻击,渗透测试员要考虑可以实施哪些攻击,以及如何利用它们实现自己的目的。

3. 测试XSS与响应注入

3.1 确定反射型请求参数

(1) 分类模糊漏洞测试的结果,确定任何与模糊测试第3步中列出的XSS有效载荷相匹配的字符串。这些是在应用程序中按原样返回的XSS测试字符串。

(2) 对于上述每一个字符串,检查应用程序的响应,查找用户提交的输入的位置。如果该字符串出现在响应主力中,应测试应用程序中是否存在XSS漏洞。如果它出现在HTTP消息头中,应测试应用程序是否存在消息头注入漏洞。如果它被用在302响应的Location消息头中,或者用于以某种方式指定重定向,应测试应用程序中是否存在重定向漏洞。请注意,同一个输入可能会被复制到响应中的几个位置,因此应用程序中可能存在几种类型的反射型漏洞。

3.2 测试反射型XSS

(1) 对于在响应主体中出现的所有请求参数,检查它周围的HTML代码,确定是否可以提交专门设计的输入,从而执行任意JavaScript脚本。例如,通过注入标签,注入一段现有代码,或在一个标签属性中插入精心设计的值,执行任意JavaScript脚本。

(2) 利用攻破签名过滤器的各种方法作为参考(参照书第12章),了解如何利用专门设计的输入执行任意JavaScript脚本。

(3) 尝试向应用程序提交各种可能的输入,监控它的响应,确定应用程序是否对输入进行任何过滤或净化。如果攻击字符串被原样返回,使用浏览器确定成功执行了任意JavaScript脚本(例如,通过生成一个警告对话框)。

(4) 如果发现应用程序阻止需要使用的某些字符串或表达式,或者对某些字符进行URL编码,尝试使用各种技巧避开过滤(参照书第12章)。

(5) 如果在一个POST请求中发现了XSS漏洞,仍然可以通过一个包含表单的恶意Web站点,由必要的请求参数和一段脚本自动提交该表单,对这个漏洞加以利用。但是,如果可以通过Get请求利用漏洞,就可以使用大量的攻击传送几种。尝试在GET请求中提交相同的参数,看攻击是否仍然取得成功。(可以使用Burp Proxy的“改变请求命令”操作转换请求类型)

3.3 测试HTTP消息头注入

(1) 对于在响应消息头中出现的每一个请求参数,确认应用程序是否接受URL编码的回车(%0d)与换行(%0a)符,以及它们是否按原样在响应中返回。请注意,在服务器的响应中寻找的是换行符本身,而不是它们的URL编码形式。

(2) 如果在提交专门设计的输入后,服务器的响应消息头新增了一行,那么应用程序易于受HTTP消息头注入攻击。攻击者可以利用这种漏洞实施各种攻击。

(3) 如果服务器的响应中仅返回两个换行符中的一个,根据实际情况,仍可以设计出有效地攻击方法。

(4) 如果发现应用程序阻止包含换行符的输入,或者净化出现在响应中的这些字符,尝试使用下面的输入测试过滤的效率:

foo%00%0d%0abar
foo%250d%250abar
foo%%0d0d%%0a0abar

3.4 测试任意重定向

(1) 如果反射型输入用来指定某类重定向的目标,测试是否可以提交专门设计的输入,生成指向一个外部Web站点的任意重定向。如果可以,渗透测试员就可以利用这种行为提高🎣攻击的可信度。

(2) 如果应用程序以参数值的形式传送绝对URL,那么修改URL中的域名,测试应用程序是否重定向到不同的域。

(3) 如果参数中包含一个相对URL,将这个URL修改成制定另一个域的绝对URL,并测试应用程序是否重定向到这个域。

(4) 如果应用程序为防止外部重定向,在进行重定向前对参数进行某种形式的确认,通常仍然可以轻易避开这种确认。尝试使用参考书13章藐视的各种攻击测试过滤的效率。

3.5 测试保存型攻击

(1) 如果应用程序保存用户提交的输入,并随后在屏幕上显示这些输入,那么,在模糊测试整个应用程序后,可能会发现攻击字符串在本身并未包含这些字符串的请求的响应中返回。留意这种情况,确定被保存数据的原始进入点。

(2) 有时,只有完成一个多阶段过程,用户提交的数据才被保存成功。如果在应用程序解析过程中确定这种功能,那么手动完成相关过程,并在被保存的数据中查找XSS漏洞。

(3) 如果拥有足够的访问权限,应仔细审查可在更高权限的用户会话中显示低权限用户的数据管理功能。管理功能中存在的任何保存型XSS漏洞往往会直接导致权限提升。

(4) 测试用户提交的数据被保存且向该用户显示的每一种情况。测试这些情况,从中查找上述XSS和其他响应注入漏洞。

(5) 如果发现一个漏洞将一名用户提交的输入显示给其他用户,渗透测试员要确定可用于实现目标的最佳攻击有效载荷,如会话劫持或请求伪造。如果被保存的数据仅向提交该数据的用户显示,那么设法找到办法,链接已经发现的所有漏洞(如不完善的访问控制),从而在其他用户的会话中注入一个攻击。

(6) 如果应用程序允许文件上传与下载,应始终探查这种功能是否易于受到保存型XSS攻击。如果应用程序允许HTML.JAR或文本文件,且并不确定或净化它们的内容,那么几乎可以肯定它们易于受到攻击。如果它允许JPEG文件且并不确定其中是否包含有效地图像,那么它可能易于受到针对Internet Explorer用户攻击。测试应用程序如果处理它支持的每种问价类型,并弄清浏览器如果处理包含HTML而非正常内容的响应。

(7) 在一名用户提交的数据被显示给其他用户的每一个位置,如果应用程序实施的过滤阻止发动保存型XSS攻击,确定应用程序的行为是否使它易于受到本站点请求伪造攻击。

4. 测试OS命令注入

(1) 如果在第1节第3步中列出的任何命令注入攻击字符串导致应用程序在做出响应时出现反常的时间延时,那么应用程序易于受到OS命令注入攻击,手动重复进行测试,在-i或-n参数中指定不同的值,确定响应时间是否随着这个值而发生系统性地变化。

(2) 使用所发现的任何一个可成功实施攻击的注入字符串,尝试注入另一个更加有用的命令(如ls或dir),确定是否能够将命令结果返回到浏览器上。

(3) 如果不能直接获得命令执行结果,还可以采用其他方法。

  • 可以尝试打开一条通向自己计算机的带外通道。尝试使用TFTP上传工具至服务器,使用Telnet或netcat建立一个通向自己计算机的反向shell,并使用mail命令通过SMTP发送命令结果。
  • 可以将命令结果重定向到Web根目录下的一个文件,然后使用自己的浏览器直接获取结果。例如: dir > c:\inetpub\wwwroot\foo.txt

(4) 一旦找到注入命令的方法并能够获得命令执行结果,就应当确定自己的权限(通过使用whoami或类似命令,或者尝试向一个受保护的目录写入一个无害文件)。然后就可以

5. 测试路径遍历

(1) 对于执行的每次模糊测试,检查在第1节第3步中列出的路径遍历攻击字符串生成的结果。可以在Burp Intruder中单击有效载荷列的顶部,按有效载荷对结果进行分类,从而将这些字符串生成的结果分类,从而将这些字符串生成的结果分组。如果收到一个不常见的错误消息,或者长度不正常的响应,手动检查响应,确定其中是否包含特定文件的内容或其他表示执行了反常文件操作的证据。

(2) 在解析应用程序的受攻击面的过程中,应该已经注意到了一些专用的功能,使用它们可根据用户提交的输入读取和写入文件。除了对所有参数进行模糊测试外,还应极其仔细地手动测试这项功能,确定所有路径遍历漏洞。

(3) 如果某个参数中包含一个文件名、文件名的一部分或一个目录,修改这个参数的值,并在其中插入任意一个子目录和一个遍历序列。例如,如果应用程序提交参数:file=foo/file1.txt,那么可以尝试提交以下值:file=foo/bar/../file1.txt

如果两种情况下应用程序的行为完全相同,那么它易于受到攻击,渗透测试员应该继续以下步骤。如果上述两种情况下应用程序行为有所不同,那么应用程序可能阻止、删除或净化遍历序列,致使文件路径失效。可以尝试使用参考书第10章的编码与其他攻击避开过滤。

(4) 如果前面在基础目录中使用遍历序列的测试取得成功,尝试使用其他序列上溯到基础目录,并访问服务器操作系统中的已知文件。如果这些尝试失败,应用程序可能在许可文件访问前实施了各种过滤或检查,应当进行深入分析,了解应用程序实施的控制以及是否可以避开这些控制。

(5) 应用程序可能会检查被请求的文件扩展名,只允许用户访问特殊类型的文件。尝试使用空字节或换行符攻击,并在后面连接已知的、应用程序接受的文件扩展名,设法避开过滤。例如:

../../../../../boot.ini%00.jpg
../../../../../etc/passwd%0a.jpg

(6) 应用程序可能会检查用户提交的文件路径是否以一个特定的文件名或词根开头。尝试将遍历序列附加在一个已知应用程序接受的词根后面,避开过滤。例如:

/images/../../../../../../../etc/passwd

(7) 如果这些攻击无法取得成功,尝试阻止使用几种测试技巧,首先对基础目录进行全面地测试,了解应用程序实施的过滤以及它如何处理无法预料的输入。

(8) 如果能够读取服务器上的任意文件,尝试获取以下任何一个文件,进而扩大攻击范围。

  • 操作系统与应用程序的密码文件。
  • 服务器与应用程序配置文件,发现其他漏洞或优化另一次攻击。
  • 可能含有数据库证书的包含文件。
  • 应用程序使用的数据源,如MySQL数据库文件或XML文件。
  • 服务器可执行页面的源代码,以执行搜索漏洞的代码审查。
  • 可能包含用户名和会话令牌的应用程序日志文件等。

(9) 如果能够写入服务器上的任意文件,分析是否可以实施以下攻击,进而扩大攻击范围。

  • 在用户的启动文件夹中创建脚本。
  • 当用户下一次连接时,修改in.ftpd等文件执行任意命令。
  • 在一个拥有执行许可的Web目录中写入脚本,从浏览器调用它们。

6. 测试脚本注入

(1) 对于执行的每一次模糊测试,在测试结果中搜索字符串111111本身(即它前面没有其他测试字符串)。确定可能易于受到脚本命令注入攻击的切入点。

(2) 检查使用脚本注入字符串的所有测试,确定所有包含脚本错误消息的测试;这些错误消息表示输入被执行,但造成一个错误,因而可能需要对测试进行优化,以成功实施脚本注入。

(3) 如果应用程序似乎易于受到攻击,通过注入其他专门针对应用程序所使用的脚本平台的命令,确认漏洞是否存在。例如,可以使用类似于模糊测试OS命令注入时使用的攻击有效载荷:

system(‘ping%20127.0.0.1’)

7. 测试文件包含

(1) 如果在模糊测试时受到任何由目标应用程序的基础架构提出的HTTP连接,那么几乎可以肯定应用程序易于受到远程文件包含攻击。以单线程的方式在有限的时间内重复相关测试,确定到底是哪些参数致使应用程序提出HTTP请求。

(2) 查找文件包含测试结果,确定在应用程序的响应中造成反常延迟的所有测试。在这些情况下,可能应用程序本身易于受到攻击,但HTTP请求可能因为网络级过滤而超时。

(3) 如果发现一个远程文件包含漏洞,部署一台包含恶意脚本(专门针对所攻击的语言而编写)的Web服务器,使用和测试脚本注入类似的命令确定脚本是否被执行。