DVWA靶场通关笔记-XSS DOM(High级别)
目录
一、XSS
二、DOM型XSS
三、代码分析
1、index.php
2、High.php
3、渗透思路
四、渗透实战
1、渗透准备
2、采用Script标签绕过
3、采用IMG标签绕过
DVWA(Damn Vulnerable Web Application)中的 XSS DOM关卡是用于练习和演示 DOM XSS的不同场景,不同安全等级存在不同的脆弱点和绕过方法,本小节对高等级别(High)关卡进行渗透实战。
一、XSS
XSS(Cross-Site Scripting) 指的是攻击者通过在网页中注入恶意脚本,当用户访问该页面时,脚本会在用户浏览器中执行,从而窃取用户数据、会话信息或进行其他恶意操作。核心原理就是未对用户输入或输出进行适当过滤,导致恶意代码被浏览器解析执行。
XSS类型 | 位置 | 数据流向 |
反射型 XSS | 服务器端 | 用户输入 → 服务器 → 响应中包含恶意代码 |
存储型 XSS | 服务器端 | 用户输入 → 存储(数据库) → 所有用户访问时触发 |
DOM 型 XSS | 客户端 JavaScript 代码 | 用户输入 → 浏览器 DOM 操作 → 执行恶意代码 |
二、DOM型XSS
DOM 型 XSS(Document Object Model Cross-Site Scripting) 是一种特殊的 XSS 攻击,其注入点存在于客户端 JavaScript 代码中,而非服务器端。攻击者通过操控网页的 DOM 环境(如 URL 参数、表单输入等),诱导浏览器执行恶意脚本,无需服务器参与。
方面 | 普通XSS | DOM XSS |
---|---|---|
检测工具 | 传统扫描工具可分析HTTP响应内容 | 需动态分析JS代码和DOM操作 |
防御位置 | 服务器端过滤(如转义< , > ) | 客户端转义 + 避免危险的DOM操作 |
WAF防护 | 可通过拦截恶意HTTP请求防御 | 通常无效(攻击数据可能不发送到服务器) |
三、代码分析
1、index.php
进入DVWA靶场源目录,找到index.php源码。
这段代码是DVWA(Damn Vulnerable Web Application)中DOM型XSS的演示页面,主要功能是:
- 根据用户选择的语言生成一个下拉菜单。
- 当用户提交选择后,URL中会包含default=参数。
- 页面JavaScript会读取URL参数并动态生成选项。
详细注释后的代码如下所示。
<?php
// 设置根目录路径
define( 'DVWA_WEB_PAGE_TO_ROOT', '../../' );
// 引入DVWA页面初始化文件
require_once DVWA_WEB_PAGE_TO_ROOT . 'dvwa/includes/dvwaPage.inc.php';// 启动页面,要求认证和PHPIDS保护
dvwaPageStartup( array( 'authenticated', 'phpids' ) );// 创建新页面
$page = dvwaPageNewGrab();
// 设置页面标题
$page[ 'title' ] = 'Vulnerability: DOM Based Cross Site Scripting (XSS)' . $page[ 'title_separator' ].$page[ 'title' ];
$page[ 'page_id' ] = 'xss_d';
$page[ 'help_button' ] = 'xss_d';
$page[ 'source_button' ] = 'xss_d';// 连接数据库
dvwaDatabaseConnect();// 根据安全等级选择对应的级别文件
$vulnerabilityFile = '';
switch( $_COOKIE[ 'security' ] ) {case 'low':$vulnerabilityFile = 'low.php';break;case 'medium':$vulnerabilityFile = 'medium.php';break;case 'high':$vulnerabilityFile = 'high.php';break;default:$vulnerabilityFile = 'impossible.php';break;
}// c
require_once DVWA_WEB_PAGE_TO_ROOT . "vulnerabilities/xss_d/source/{$vulnerabilityFile}";// 对于impossible级别,不进行URI解码
$decodeURI = "decodeURI";
if ($vulnerabilityFile == 'impossible.php') {$decodeURI = "";
}// 构建页面主体
$page[ 'body' ] = <<<EOF
<div class="body_padded"><h1>Vulnerability: DOM Based Cross Site Scripting (XSS)</h1><div class="vulnerable_code_area"><p>Please choose a language:</p><form name="XSS" method="GET"><select name="default"><script>// 检查URL中是否包含default参数if (document.location.href.indexOf("default=") >= 0) {// 提取default参数值var lang = document.location.href.substring(document.location.href.indexOf("default=")+8);// 动态写入选项document.write("<option value='" + lang + "'>" + $decodeURI(lang) + "</option>");document.write("<option value='' disabled='disabled'>----</option>");}// 写入固定选项document.write("<option value='English'>English</option>");document.write("<option value='French'>French</option>");document.write("<option value='Spanish'>Spanish</option>");document.write("<option value='German'>German</option>");</script></select><input type="submit" value="Select" /></form></div>
EOF;// 添加更多信息链接
$page[ 'body' ] .= "<h2>More Information</h2><ul><li>" . dvwaExternalLinkUrlGet( 'https://www.owasp.org/index.php/Cross-site_Scripting_(XSS)' ) . "</li><li>" . dvwaExternalLinkUrlGet( 'https://www.owasp.org/index.php/Testing_for_DOM-based_Cross_site_scripting_(OTG-CLIENT-001)' ) . "</li><li>" . dvwaExternalLinkUrlGet( 'https://www.acunetix.com/blog/articles/dom-xss-explained/' ) . "</li></ul>
</div>\n";// 输出页面
dvwaHtmlEcho( $page );?>
2、High.php
打开源码High.php,分析可知这段代码使用switch方法的白名单过滤了XSS注入,如下所示。
分析代码,当前防护措施如下所示。
- 参数检查:检查URL中是否存在default参数(如?default=English),且值不为null。
- 白名单验证:只允许French、English、German、Spanish四个值,其他值会触发重定向到默认英语选项。
- 防御性设计:通过白名单强制无效输入回退到安全默认值,避免不可控输入。
详细注释后的源码如下所示。
<?php
// 检查是否存在名为"default"的GET参数且其值不为null
if (array_key_exists("default", $_GET) && !is_null($_GET['default'])) {# 白名单允许的语言选项switch ($_GET['default']) {case "French":case "English":case "German":case "Spanish":# 如果是白名单中的语言,不做任何操作,继续执行后续代码break;default:# 如果不在白名单中,重定向到?default=Englishheader("location: ?default=English");exit; // 终止脚本执行}
}
?>
3、渗透思路
由于源码器使用了switch白名单的方式,判断参数中的值是不是所规定的四种(French、English、German、Spanish),所以服务端是无法通过除此之外的其他内容绕过。
但还有一种绕过方式:
- 使用#符号来使URL传入内容被截断,URL栏的 # 号之后的内容并不会发送至服务器端
- 但是js语言中#号并不会被截断,会使得default传入的所有内容都会完整传入。
综上,当注入语句配置为“白名单的四个词+空格+#+原始注入语句”时,就可以实现URL白名单绕过,js可以传入完整的注入语句,从而实现$_GET['default']传递的值刚刚好为白名单内的值,使绕过验证,又实现了前端加载攻击语句。
四、渗透实战
1、渗透准备
配置security为High级别,如下所示。
进入DVWA靶场XSS DOM关卡High级别,选择English,此时完整URL地址如下所示。
http://127.0.0.1/dvwa/vulnerabilities/xss_d/?default=English
2、采用Script标签绕过
尝试注入XSS语句<script>alert('mooyuan')</script>,参考Low关卡,注入语句仍为<script>alert('mooyuan')</script>,针对本关卡,注入语句前增加French空格#号,注入语句如下所示。
French #<script>alert('mooyuan')</script>
3、采用IMG标签绕过
尝试注入XSS语句<img src=0 οnerrοr=alert('mooyuan')>,参考Medium关卡,构造单select闭合,语句变为</select><img src=0 οnerrοr=alert('mooyuan')>。针对本关卡,注入语句前增加English空格#号,注入语句如下所示。
English #</select><img src=0 onerror=alert('mooyuan')>