xss.haozi.me靶场通关wp
一、模块介绍
网站页面

1.input
输入的内容

2.html
通过处理程序(server code)渲染完的代码

3.server code
服务端代码,告诉我们如何处理输入的代码

4.浏览器框
显示代码执行结果

二、具有该属性的标签
1.onmouseover
/*常用*/
a
p
img
div
span
/*不常用*/
button
input
textarea
select
option
label
li
ul / ol
table / tr / td / th
form
fieldset
iframe2.onerror
/*加载失败时必触发*/
img
<img src=x onerror=alert(1)>
/*脚本加载失败时触发*/
script
<script src=404 onerror=alert(1)>
/*脚本加载失败时触发*/
link
<link rel=stylesheet href=x onerror=alert(1)>
三、通关详解
此靶场所有题目都是Dom型xss!
1.0x00
没有过滤,直接输入<script>alert(1);</script>即可成功弹窗

payload:
<script>alert(1)</script>
2.0x01
此题将<div>换成了<textarea>,而<textarea>是一个多行文本框,在此标签里输入的内容都会变成多行文本框里的数据,所以需要先将<textarea>闭合
在payload前添加一个</textarea>把标签闭合,即可成功执行后面的xss语句

payload:
</textarea><img src=1 onerror=alert(1)>--+
3.0x02
此题输入点在一个input标签的输入框的value属性中,即在一个当行文本框中输入内容
这里用了两种方法,闭合input标签和在input标签的属性里注入
1.闭合input标签

2.onmouseover属性

payload:
"> <img src=1 onerror=alert(1)>#
" onmouseover="alert(1)">
4.0x03
此题服务器的过滤使用了正则表达式,将括号替换为空
正则匹配:
/ 正则表达式要匹配的内容在这两个斜杠中间,g为全局匹配(一般用于在某一字符串中搜索/替换)[]为匹配其中字符的任意一个字符(如,[abcd],匹配a或b或c或d)

由此可知,题目将括号替换为空
使用反引号绕过`

payload:
<img src=1 onerror=alert`1`>
5.0x04
此题依旧是正则表达式,在上一题的基础上多过滤了反引号
于是我们可以使用编码的方式进行绕过,但是只可以在标签属性(如,scr、onmouseover、value等)中使用编码绕过
使用Unicode编码,将()转化成(),并在两个括号中间加上1即可成功弹窗

payload:
<input onmouseover=alert(1)>
6.0x05
依旧是正则表达式,由代码可知输入点在一个注释里,且服务器将-->替换成表情防止闭合注释符
但是注释符还有另一个写法:--!>,使用此写法闭合即可成功弹窗

payload:
--!><img src=1 onerror=alert(1)><!--
7.0x06
正则表达式:
i:不区分大小写
|:匹配前面或后面的内容,如匹配ab/cd则要写成(ab|cd),其中括号用来消除歧义
*:匹配所有符号
因为. 匹配的任意字符不包括换行符,所以使用换行符绕过

payload:
onmouseover
=alert(1)
8.0x07
正则表达式:
\:转义符,匹配后面字符本身
?:表示前面的字符可以出现也可以不出现(出现0次或1次)(如,匹配某url,但不知道是http还是https,即可写成https?😕/xxx.com)
+:表示前面的内容可以出现1次或多次
所以,由代码可知,此题不能输入完整html标签,否则会被过滤
因为html语言兼容性强,不完整的标签也可以解析(不输入后面的闭合标签)

payload:
最后标签应该要加个空格和后面的闭合标签隔开
<img src=1 onerror=alert(1)
9.0x08
由代码可知正则表达式匹配闭合</style>的标签
<style>标签表示css样式,不能执行JavaScript语句,即不能直接输入xss语句,像<img scr="xxx">,其中img和src中间有空格,也就是说标签和属性之间是有空格的,</style>标签也是一样的,在style后面加入空格,加入空格后可以往后面加上属性,但是不加属性只加空格也是可以解析的,所以使用空格来绕过匹配

payload:
</style > <img src=1 onerror=alert(1)>
10.0x09
此题正则表达式匹配的是https://www.segmentfault.com或http://www.segmentfault.com开头的网址
所以,必须以上两个url开头才会有显示,先输入其他内容则会显示Invalid URL
这个标签是在script标签里,可以使用onerror属性来注入

payload:
https://www.segmentfault.com" onerror="alert(1)
11.0x0A
先看代码,下方过滤和上一题一样,但是又增加了新的过滤,将特殊符号替换为实体
所以我们无法使用闭合,只能从url后面想办法
此题可以使用http协议的基础概念,url前面可以添加身份验证信息,如:https://user:pass@www.segmentfault.com(现在用得很少,不安全)
又因为必须以固定的url开头,所以我们把www.segmentfault.com当作身份认证信息,后面再去请求其他域名,如外部js或自己写一个服务器
①使用题目默认的外部js:

②使用自己写的js文件:

因为是js文件所以不需要写<script>,只有在html页面插入xss语句才需要写<script>
启动一个http服务器(这里我们直接使用phpstudy的服务器)
将https改为http(因为127.0.0.1是http的服务器)

此时载入不成功,因为现在是在一个https页面上引入一个http的内容(在一个安全的页面上引入一个不安全的内容),这是浏览器禁止的行为

我们需要修改设置


成功弹窗

payload:
http://www.segmentfault.com@xss.haozi.me/j.js
12.0x0B
此题过滤只有一个转为大写
html标签不区分大小写,但是JavaScript语句区分大小写
我们可以引用外部js来弹窗

注:协议和域名都不区分大小写,但是文件区分大小写(haozi内部自带两个文件j.js和J.JS)
本题还可以使用Unicode编码将alert(1);编码来进行绕过
payload:
<script src="https://xss.haozi.me/j.js"></script>
13.0x0C
先看代码,和上一题差不多,但是多了一个把script替换成空
遇到替换成空要想到双写绕过
所以在上一题payload的基础上把script双写即可

也可同上一题使用其他标签+Unicode编码绕过
<scriscriptpt src="https://xss.haozi.me/j.js"></scscriptript>
14.0x0D
正则匹配:
// :javascript单行注释
/**/ :javascript多行注释
所以可以通过换行来规避单行注释,然后使用html的注释符--> 注释掉后面的引号

payload:
alert(1)
-->15.0x0E
查看代码和要匹配的内容
<([a-zA-Z])
():表示分组,如ip为192.168.1.1,使用正则表达式匹配数字,正则表达式为[0-9]+\.[0-9]+\.+[0-9]+,此时想要取出次ip的第二位(168)做后续处理,那么可以在第二位匹配到的位置加上括号[0-9]+\.([0-9]+)\.[0-9]+\.+[0-9]+,然后使用$1取第一个分组匹配到的内容($0为整个正则表达式匹配到的内容本身),也可以这样分组[0-9]+\.([0-9]+\.[0-9]+)\.+[0-9]+,此时$1为168.1
a-zA-Z:表示匹配abc到z所有字母且不区分大小写,等同于[a-z]/i
此正则表达式匹配的内容为”<后一串字符放到分组1中“,替换为"<_$1",如输入<a会将其替换并大写为<_A


所以输入任意html标签都会被替换
我们可以使用特殊字符” ſ “(古英文的小写s),将其转化为大写后就变成了大写的S

payload:
<ſcript src=1 onerror="alert(1)"></ſcript>
16.0x0F
由代码可知此题将特殊符号替换为html实体,输入点在onerror中
因为输入点是在标签属性内,即使进行了编码也可以识别(前面有题是用中这个方法绕过的),所以可以直接用单引号进行闭合

payload:
'); alert(1)('
17.0x10
此题输入点在window.data中且没有过滤
我们可以先输入空(赋值为空),用分号结束window.data语句,再使用alert弹窗

payload:
alert(1)18.0x11
此题对特殊字符加了两个转义符(\\)
var:在JavaScript中定义变量
console.log(”${s}“):s为我们输入的经过转义的内容
document.createElement('a'):创建一个a元素
a.href = url:a标签(超链接)的属性等于前面定义的url
document.body.appendChild(a):body体添加一个子元素a,即把a标签放进body体中
a.click():点击a标签
所以,我们输入的内容是一个a标签的超链接的内容,并且JavaScript会自动点击这个超链接
首先我们先不去看转义,直接闭合javascript:console.log(" ")
通过");alert("1这样一个语句即可成功闭合
直接复制上去,发现成功弹窗

即进行了一次解转义,在s这里已经少了一个转义符,只剩一个(在html中也可以看到)

而在创建url时又进行了一次赋值,又少了一个转义符

所以,写到标签中的url里已经没有转义符了

因此,这道题不需要管转义符就可以成功弹窗
payload:
");alert("1
19.0x12
查看代码,依旧是正则表达式替换,把双引号替换成“\"”
而代码中已经赋值过一次,所以要去掉一个转义符,此时只有一个转义符

我们依旧先不管过滤,直接构造闭合(尽可能不使用双引号,因为过滤的就是双引号,防止出现奇怪的错误)
通过构造");alert(1);//这样的语句进行闭合console.log("");
输入语句后发现,双引号被转义,变成了数据,没能成功闭合

所以我们再在前面加上一个转义符,将代码中用来转义双引号的转义符转义掉,而我们输入的双引号就能成功闭合从而输出后面的alert(1),然后加上分号结束语句(若分号被过滤,可使用加号,做字符串拼接),再用//注释后面的语句

查看元素,打开控制台可以看到,因为我们增加的转义符将代码自带的转义符进行了转义,所以代码自带的转义符变成了数据从而被输出

payload:
/");alert("1")//