[白帽子讲WEB安全]XSS

第三章:XSS <Cross Site Script>

3.1 XSS简介

通过“HTML注入”篡改了网页,插入了恶意的脚本,从而在用户浏览网页时,控制用户浏览器的一种攻击<一开始跨域,如今是否跨域已经不重要>

XSS破坏力强大,且产生的情景复杂,难以一次性解决。现在业内达成的共识是:针对各种不同场景产生的XSS,需要区分情景对待。

XSS分类:反射型XSS、存储型XSSDOM Based XSS

反射型XSS又称“非持久性XSS”(Non-persistent XSS),只是简单地把用户输入的数据“反射”给浏览器。

存储型XSS又称“持久型XSS”,用户输入的数据存储在服务器端,具有很强的稳定性

DOM Based XSS这种类型并非按照“数据是否保存在服务器端”来划分,从效果上来说也是反射型XSS,但其形成原因较特别。出于历史原因,就把他单独作为一个分类了。修改页面的DOM结点形成XSS,故称之为DOM Based XSS。

3.2 XSS攻击进阶

3.2.1 初探XSS Payload

XSS Payload其实就是一段Javascript脚本(还可以是Flash或其他富客户端的脚本),所以任何JavaScript脚本能实现的功能,XSS Payload都能做到。一个最常见的XSS Payload,就是通过读取浏览器的Cookie对象,从而发起“Cookie 劫持”攻击

Example

可以通过XSS将这段代码注入到目标页面中,并在最后将document.cookie对象作为参数发送到远程服务器

获取某个打开的页面的cookie:在浏览器地址栏中输入:

在当前的WEB中,Cookie一般是用户登陆的凭证,浏览器发起的多有请求都会自动带上Cookie。如果Cookie没有绑定客户端信息,当攻击者窃取了Cookie后,就可以不用密码登陆用户的账户

Cookie的“HttpOnly”标识可以防止“Cookie劫持”

3.2.2 强大的XSS Payload

Cookie劫持对抗:Set-Cookie时给关键字Cookie植入HttpOnly标识、Cookie与IP绑定

3.2.2.1 构造GET与POST请求

GET:

Example Code :删除文章编号为156713012的文章,攻击者只需让博主执行下面这段JS代码(XSS Payload)

POST

方法一:构造form表单并自动提交<构造DOM节点、innerHTML>

方法二:通过XMLHttpRequest发送一个POST请求

攻击者除了可以实施Cookie劫持外,还能够通过模拟GET、POST请求操作用户浏览器

3.2.2.2 XSS钓鱼

Example 1:验证码绕过

对于验证码,XSS Payload可以通过读取页面内容,将验证码的图片URL发送到远程服务器上来实施—攻击者可以在远程XSS后台接受当前验证码,并将验证码的值返回给当前XSS Payload,从而绕过验证码

Example 2:密码修改<XSS与钓鱼结合>

利用JavaScript在当前页面上“画出”一个伪造的登陆框,当用户在登陆框中输入用户名和密码后,其密码将被发送至黑客的服务器

充分发挥想象力,可以使得XSS攻击的威力更加巨大

3.2.2.3 识别用户浏览器

最简单的办法:通过XSS读取浏览器的UserAgent对象

但是UserAgent可以被伪造,比如Firefox有很多扩展可以屏蔽或自定义浏览器发送的UserAgent,所以JS读取的浏览器对象不一定准确

更高级的方法:浏览器之间的实现存在差异—不同的浏览器会各自实现一些独特的功能,而同一个浏览器的不同版本之间也可能会有细微的差别,几乎不会误报

参考代码:P54

3.2.2.4 识别用户安装的软件

Example code 1:检测是否有迅雷控件(XunLeiBHO.ThunderIEHelper)

Flash的system.capabilities对象,能够查询客户端电脑中的硬件信息

Firefox的插件:可通过查询“navigator.plugins”对象就可得到所有插件

3.2.2.5 CSS History Hack<通过CSS 发现一个用户曾经访问过的网站>

原理:利用style的visited属性—如果用户曾经访问过某个链接,那么这个链接的颜色会变的与众不同。但是Firefox在2010年3月底修补了这个问题

POC:Proof Of Concept,验证性测试

3.2.2.6 获取用户的真实IP地址

JS本身并没有提供获取本地IP的能力,需借助第三方软件,比如JRE,XSS可通过调用JavaApplet的借口获取客户端的本地IP地址

Example code

另外两个利用java的代码见书中P61

3.2.3 XSS攻击平台

Attack API<XSS Payload封装>、BeEF<完整的XSS攻击过程>、XSS-Proxy<轻量级>

3.2.4 终极武器:XSS Worm

3.2.4.1 Samy Worm

3.2.4.2 百度空间蠕虫

一般来说,用户之间发生交互行为的页面,如果存在存储型XSS,则比较容易发起XSS   Worm攻击. (比如,发送站内信、用户留言等页面,都是XSS的高发区,需要重点关注,如果一个页面只能由用户个人查看,比如“个人资料设置”页面,因为缺乏用户之间的互动功能,所以即使存在XSS,也不能被用于XSS Worm传播)

3.2.5 调试JavaScript

Firebug , IE 8 Developer Tools , Fiddler , Http Watch

3.2.6 XSS构造技巧

3.2.6.1 利用字符编码

Example: 百度在一个<script>标签中输出了一个变量,其中转义了双引号:

但是,百度返回页面采用GBK/GB2312编码,故“%c1\”这两个字符组合会成为一个Unicode字符,在firefox中会认为这个一个字符,所以构造:

3.2.6.2 绕过长度限制

XSS构造:

希望的效果:

假设长度限制为20个字节,则这段XSS会被切割为:

攻击者利用事件(Event)来缩短所需要的字节数:

实际输出为:

但利用“事件”能够缩短的字节数是有限的,最好的办法是把XSS Payload写到别处,再通过简短的代码加载这段XSS Payload

最常用的一个藏代码的地方就是“location.hash”,不会被记录到WEB日志中

location.hash本身没有长度限制

在某些特殊环境下,利用注释符绕过长度限制

3.2.6.3 使用<base>标签

定义页面上所有使用“相对路径”标签的hosting地址

<base>并非只能用于<head>内,而是可以出现在页面任何地方,并且作用于位于该标签之后的所有标签

在设计xss安全方案时一定要过滤掉该标签

3.2.6.4 window.name的妙用

对window.name赋值无长度限制,window对象是浏览器的窗体,非document对象,故不受同源策略限制。攻击者利用这个对象可以实现跨域、跨页面传递数据

缩短XSS Payload长度

其他技巧请百度:《突破XSS字符数量限制执行任意JS代码》

3.2.7-变废为宝:Mission Impossible

3.2.7.1 Apache Expect Header XSS

服务器出错时,会把Expect头的内容未经任何处理便写入到页面中,因此Expect头中的HTML代码就被浏览器解析执行了。-> 使用Flash构造请求。

3.2.7.2 Anehta 的回旋镖

反射型XSS也能想存储型XSS一样利用:将要利用的XSS嵌入一个存储型XSS中

思路:如果在B域上存在一个反射型XSS B,在A域上存在一个存储型XSS_A,当用户访问A域上的XSS_A时,同时嵌入B域上的XSS_B则可以达到在A域的XSS攻击B域用户的目的。

3.2.8-容易被忽视的角落:Flash XSS

Flash中嵌入ActionScript脚本,由于Flash文件如此危险,所以在实现XSS Filter时一般都会禁用<embed>,<object>等标签

对策:若仅仅是视频文件,则要求转码为flv文件<静态>,若是带动态脚本的flash,则要通过flash的配置进行限制<allowScriptAccess, allowNetworking, XSS过滤>

3.2.9-真的高枕无忧吗:JavaScript开发框架

Dojo, YUI, JQuery

3.3 XSS的防御

流行的浏览器内置了一些对抗XSS的措施,如FirefoxCSPNoscript扩展,IE8内置的XSS Filter

3.3.1 四两拨千金:HttpOnly<set-Cookie时设置,需给关键Cookie都加上HttpOnly>

严格讲:HttpOnly并非为了对抗XSS,它解决的是XSS后的Cookie劫持攻击;设置之后JavaScript读取不到Cookie的值

绕过:Apache支持的一个HeaderTRACE. TRACE一般用于调试,它会将请求头作为Response Body返回。

使用HttpOnly有助于缓解XSS攻击,但仍然需要其他能够解决XSS漏洞的方案

3.3.2 输入检查

输入检测的逻辑,必须放在服务器端代码中实现。

目前Web开发的普遍做法,是同时在客户端JS中和服务端代码中实现相同的输入检查。客户端JS输入检查可以阻碍大部分误操作的正常用户,从而节约服务器资源

在XSS的防御上,输入检查一般是检查用户输入的数据中是否包含一些特殊字符,如<、>、’、”等,如果发现存在特殊字符,则将其过滤或者编码

比较智能的“输入检查”,可能还会匹配XSS特征,比如查找用户数据中是否包含<script>,javascript等敏感字符。

这种输入检查的方式被称为XSS Filter

XSS Filter在用户提交数据时获取变量,并进行XSS检查;但此时用户数据并没有结合渲染页面的HTML代码,因此XSS Filter对语境的理解并不完整。(恶意JS URL可绕过)

在大多数情况下,URL是一种合法的用户数据

XSS Filter还有一个问题—-对<,>等字符的处理,可能会改变用户数据的语义

3.3.3 输出检查

一般来说,除了富文本的输出外,在变量输出到HTML页面时,可以使用编码或者转义的方式来防御XSS

3.3.3.1安全的编码函数

html:   HtmlEncode:字符转换成HTMLEntities,对应的标准是ISO-8859-1

至少转换:

Php:   htmlentities() , htmlspecialchars()

JavaScript:   JavaScriptEncode

JaVaScriptEncodeHtmlEncode的编码方式不同,他需要使用“\”对特殊字符进行转义。在对抗XSS时,还要求输出的变量必须在引号内,以避免造成安全问题

XML:   XMLEncode  <HtmlEncode类似>

Json:   JSONEncode  <JavascriptEncode类似>

注意:在适当的时候选用适当的函数,编码后的数据长度可能会发生改变,从而影响某些功能,在写代码时需要注意这个细节,以避免产生不必要的bug

3.3.3.2只需要一种编码吗

XSS攻击主要发生在MVC架构中的view层,大部分的XSS漏洞可以在模板系统中解决

对于浏览器来说,htmlparser会优先于JavaScript Parser执行,所以解析过程是,被HtmlEncode的字符先被解码,然后执行JavaScript事件

导致XSS攻击发生的原因,是由于没有分清楚输出变量的语境

3.3.4 正确防御XSS

XSS的本质还是一种“HTML注入”,用户的数据被当成了HTML代码一部分来执行,从而混淆了原本的语义,产生了新的l语义

XSS可能发生的所有场景

3.3.5 处理富文本<用户提交的一些自定义的HTML代码>

<script>,<iframe>,<base><form>等,应该被严格禁止

标签选择上,应该使用白名单,避免使用黑名单。比如,之允许<a>,<img>,<div>等比较安全的标签存在

尽可能禁止用户自定义CSS与style,如果一定要用,则像过滤富文本一样过滤CSS

开源项目:Anti-Samy,   HTMLPurify

3.3.6 防御DOM Based XSS

DOM Based XSS是一种比较特别的XSS漏洞,前文提到的几种防御方法都不太适用,需要特别对待

    首先,在”$var”输出到<script>时,应该执行一次JacascriptEncode;其次,在document.write输出到HTML页面时,要分具体情况看待,如果是输出到事件或者脚本,则需再做一次javascriptEncode;如果是要输出到HTML内容或者属性,则要做一次htmlEncode。

也就是说,从javascript输出到HTML页面,也相当于一次XSS输出过程,需要分语境使用不同的编码函数。

会触发DOM Based XSS的地方很多,一下几个地方是JavaScript输出到HTML页面的必经之路:

除了上述,一下几个地方也可能成为DOM Based XSS的输入点,需要重点关注

  • 页面中的inputs框
  • window.location(href,hash等)
  • window.name
  • document.referrer
  • document.cookie
  • localstorage
  • XMLHttpRequest返回的数据

3.3.7 换个角度开xss风险

一般来说,存储型XSS的风险高于反射型XSS。因为存储型XSS会保存在服务器上,有可能会跨页面存在。它不改变页面URL的原有结构,因此有时候还能逃过一些IDS的检测。比喻IE8的XSS Filter和firefox的Noscript Extension,都会检查地址栏中的地址是否包含XSS脚本。而跨页面的存储型XSS可能会绕过这些检测工具。

攻击过程来说,反射型XSS,一般要求攻击者诱使用户点击一个包含XSS代码的URL链接;而存储型XSS,则只需要让用户查看一个正常的URL链接。比如一个Web邮箱的邮件正文页面存在一个存储型XSSL漏洞,当用户打开一封邮件时,XSS Payload会被执行。这样的漏洞极其隐蔽,且埋伏在用户的正常业务中,风险颇高。

风险角度看,用户之间有互动的页面,是可能发起XSS Worm攻击的地方。而根据不同页面的page view高低,也可以分析出哪些页面受XSS攻击后的影响会更大。比如在网站首页发生的XSS攻击,肯定比网站合作伙伴页面的XSS攻击要严重的多

在修补XSS漏洞时遇到的醉倒挑战之一就是漏洞数量太多,因此开发者可能来不及,也不愿意修补这些漏洞。从风险角度重新定位每个XSS漏洞,就具有了重要的意义

3.4 小结

理论上,XSS漏洞虽然复杂,但却时可以彻底解决的,在设计XSS解决方案时,应该深入理解XSS攻击原理,针对不同的场景使用不同的方法,同时很多开源项目为我们提供了参考

原文链接:https://www.cnblogs.com/sevensd/p/5502960.html

原创文章,作者:优速盾-小U,如若转载,请注明出处:https://www.cdnb.net/bbs/archives/17364

(0)
上一篇 2022年11月18日
下一篇 2022年11月18日

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注

优速盾注册领取大礼包www.cdnb.net
/sitemap.xml