入门小白进阶XSS的文章
xss攻击(Cross Site Scripting)全称跨站脚本攻击。通过嵌入恶意脚本代码到正常的用户能访问到的网页。当用户正常访问该页面时,执行恶意代码 。xss攻击可窃取cookie信息,监听用户行为,威胁web服务器安全,危害极大。
1.XSS注入介绍
1.1 XSS漏洞
比如说HTML超文本标记语言中<>标识开始,在动态页面中插入<Javascript脚本语言>,使得网页误以为插入了HTML语言,而成功执行Javascript脚本语言。xss攻击就利用了xss漏洞,执行脚本语言。
如:恶意链接
1 | http://xx.com/?search=<script>alert(”xss攻击”)</script> |
访问URL,最后跳出弹框“xss攻击”。
以下是可以利用XSS漏洞来达成的攻击:
- 网页挂马;
- 盗取Cookie;
- DoS攻击;
- 钓鱼攻击;
- 蠕虫攻击;
- 劫持用户web行为;
1.2 XSS分类
XSS的类型主要有以下三种:
反射型XSS
存储型XSS
DOM型XSS
第一种反射型XSS:
反射型payload一般存在于网页的Url中,只用户单击时触发,只执行一次,非持久化,故称反射型XSS。它是经过后端处理,不经过数据库。攻击者发送恶意Url链接让受害者点击(一般会对payload部分进行处理,如:编码转换和短域名跳转)。
第二种存储型XSS:
存储型xss攻击是持久型的。也是经过后端处理,但是经过数据库。会直接威胁web服务器安全,无需用户点击特定的url就可执行脚本攻击。
常见于页面数据交汇处,如:评论,修改用户信息,登录,留言板,搜索等地方。攻击者将脚本代码嵌入留言区等,提交到服务器,其他用户登录时也会执行该脚本代码。
第三种DOM型XSS:
DOM型XSS其实是一种特殊类型的反射型XSS,是不经过后端处理。它是基于DOM文档对象模型的一种漏洞。
2.XSS注入利用
2.1 COOKIE窃取
Cookie盗取是xss攻击中最实用也是最广泛的一种利用方式之一。我们知道Cookie是Web系统识别用户的身份和保存会话状态的主要机制,且是由服务器提供的、存储在客户端的一种数据。同时,对于cookie的操作十分的方便,我们可以通过Document对象访问Cookie。如:
1 | <script>alert(document.cookie)</script> |
会弹出当前页面的cookie信息。
Cookie有如下常见的属性:
1 | Domain————设置关联Cookie的域名; |
如何区分两者很简单,只要判断cookie中的expires即过期时间属性有没有设置,如果设置了即为本地cookie,反之为内存cookie。由于Cookie具有的不同属性,我们可以将不同属性的Cookie盗取方式分为以下几种情况。
默认
即不对Cookie的任何属性进行指定就设置Cookie的情况。这种情况下Cookie的获取最为简单。可以通过下列方式获取:
1 | <script> |
不同域
这是由于domain字段的机制导致的。一个Cookie如果不知道domain的值,则默认为本域。
例如有两个网站www.a.com和test.a.com且后者存在xss漏洞,按照同源策略,这两个网站是不同源的,默认情况下我们无法直接从test.a.com获取到www.a.com的Cookie,可是如果www.a.com的Cookie值中的domain属性设置为父级域即a.com,就可以通过test.a.com的xss漏洞获取到www.a.comwww.a.com的Cookie值。
不同路径
这是由于path字段的机制导致的。在设置Cookie时,如果不指定path的值,默认就是目标页面的路径。比如在www.a.com/admin/index.php设置cookie值且不知道path,那么path默认为/admin/。javascript可以指定任意路径的cookie,但是只有对于path值的目录下才能读取Cookie,即上述例子中只有/admin/目录下的javascipt才能读取前边设置的Cookie。
Http Only
HttpOnly是指仅在Http层面上传输的Cookie,当设置了HttpOnly标志后,客户端脚本就无法读取该Cookie,这样做能有效防御XSS攻击获取Cookie,也是目前防御XSS的主流手段之一。不过利用某些特定方式也可以同样读取到标志了HttpOnly的Cookie。
利用调试信息,如:PHP的phpinfo()和Django的调试信息,里边都记录了Cookie的值,且标志了HttpOnly的Cookie也同样可以获取到。
利用Apache Http Server 400错误暴露HttpOnly Cookie的特点。
Secure
Secure是指设置了Secure的Cookie尽在HTTPS层面上进行安全传输,如果请求是HTTP的,则不会带上改Cookie,这样做的好处是可以降低Cookie对中间人攻击获取的风险,不过对我们此处讨论的XSS攻击无拦截效果,可通过默认情况下获取。
P3P
HTTP响应头的P3P字段可以用于标识是否允许目标网站的Cookie被另一域通过加载目标网站而设置或发送。
我们来举个例子,在A域通过iframe等方式加载B域(此时也称B域为第三方域),如果我们想通过B域来设置A域的Cookie,或加载B域时带上B域的Cookie,这时就得涉及到P3P。
B域设置A域Cookie
在IE下默认是不允许第三方域设置的的,除非A域在响应头带上P3P字段。当响应头头带上P3P后,IE下第三方域即可进行对A域Cookie的设置,且设置的Cookie会带上P3P属性,一次生效,即使之后没有P3P头也有效。
加载B域时Cookie传入问题
我们知道Cookie分为内存Cookie和本地Cookie,当我们通过A域加载B域时,默认是带内存Cookie加载(如果无内存Cookie则不带),而如果想要带本地Cookie加载,则本地Cookie必须带P3P属性。
2.2 会话劫持
由于Cookie的不安全性,开发者们开始使用一些更为安全的认证方式——Session。
这里提到Session是因为我们在现实情况中可能会出现已经获取到了Cookie,但是由于用户已经退出了浏览器指示Session无效,导致我们无法通过Cookie欺骗来获取用户权限;又比如有的网站设置了HttpOnly,获取不到Cookie;再者有的网站将Cookie与客户端IP向绑定;此时我们便可以利用会话劫持来达到目的。
会话劫持的实质就是模拟GET/POST请求(带Cookie)通过受害者浏览器发送给服务器,我们可以通过下面的方式来完成。
1 | var img = document.creatElement("img"); |
通过javascript控制DOM对象来发起一个GET请求,如:
通过javascript自动构造隐藏表单并提交(POST)
通过XMLHttpRequest直接发送一个POST请求
我们可以通过构造的GET/POST请求来实现如添加管理员、删除文章、上传文件等操作。XSS蠕虫从某种意义上来说也属于会话劫持。
2.3钓鱼
现在一般我们都可以很容易的防范钓鱼网站,可是当钓鱼网站与XSS漏洞结合呢?设想一下,如mail.qq.com的页面存在XSS漏洞,攻击者通过iframe替换了原来的页面成钓鱼页面,并且网页的Url还是原来的页面,你是否能察觉出来?
2.3.1XSS重定向钓鱼
即从www.a.com通过xss漏洞跳转到www.b.com的钓鱼页面上,整个过程变化明显,受害者易察觉。
1 | http://www.a.com/index.php?search=%3Cscript%3Edocument.location.href="http://www.b.com/index.php"%3C/script> |
2.3.2HTML注入式钓鱼
通过javascript来修改页面的DOM对象属性,或在原页面中添加新的DOM元素。前者相对于后者更隐蔽。
2.4 Iframe
攻击者通过javascript来添加一个新的Iframe标签嵌入第三方域的内容(钓鱼网页),此时主页面仍处于正常页面下,具有极高的迷惑性。
3.XSS注入漏洞挖掘
3.1 XSS攻击过程
反射型XSS攻击的流程如下:
攻击者寻找具有漏洞的网站
攻击者给用户发了一个带有恶意字符串的链接
用户点击了该链接
服务器返回HTML文档此时该文档已经包含那个恶意字符串
客户端执行了植入的恶意脚本,XSS攻击就发生
存储型XSS攻击的流程如下:
用户提交了一条包含XSS代码的留言到数据库
当目标用户查询留言时,那些留言的内容会从服务器解析
后加载出来
浏览器发现有XSS代码,就当做正常的HTML和JS解析执行
DOM型XSS攻击的流程如下:
- 攻击者寻找具有漏洞的网站
- 攻击者给用户发了一个带有恶意字符串的链接
- 用户点击了该链接
- 服务器返回HTML文档,该文档此时不包含那个恶意字符串
- 客户端执行了该HTML文档里的脚本,然后把恶意脚本植入了页面
- 客服端执行了植入的恶意脚本,XSS攻击就发生了
3.2XSS挖掘点
数据交互的地方
- get、post、cookies、headers
- 反馈与浏览
- 文本编辑器
- 各类标签插入和自定义
数据输出的地方
- 用户资料
- 关键词、标签、说明
- 文件上传
- 反射型常见注入点:
- 网站的搜索栏、用户登录入口、输入表单等地方,常用来窃取客户端cookies或钓鱼欺骗。
- 存储型常见注入点:
- 论坛、博客、留言板、网站的留言、评论、日志等交互处。
DOM型注入点:
通过js脚本对对文档对象进行编辑,从而修改页面的元素。也就是说,客户端的脚本程序可以DOM动态修改页面的内容,从客户端获取DOM中的数据并在本地执行。由于DOM是在客户端修改节点的,所以基于DOM型的XSS漏洞不需要与服务器端交互,它只发生在客户端处理数据的阶段。可能触发DOM型XSS的属性:
- document.referer属性
- window.name属性
- location属性
- innerHTML属性
- documen.write属性
3.3白盒审计
通过查看源代码来判断网站的交互点是否存在安全过滤。由于此处涉及代码审计内容。
3.4黑盒审计
在现实环境中挖掘XSS漏洞时黑盒的情况偏多。我们进行XSS黑盒测试时主要分为手工检测和工具检测。
3.4.1手工检测
首先我们需要尽可能地找到目标的每个输入输出点并挨个尝试;在进行尝试的时候,我们应优先选择特殊字符进行测试,如”<>&;/‘:等,如果连<>都未过滤/转义,那么该输入点很可能存在XSS漏洞。
如果<>等标记符号都被过滤/转义了,我们也可以使用标签自身的属性/事件
1 | (href,lowsrc,bgsound,backgroud,value,action,dynsrc等) |
来触发XSS,如
1 | <input name="xx" value=<?=$query?>> |
这里的$query属于动态内容,我们把他替换成恶意代码,最终的代码为
1 | <input name="xx" value=xss onmouseover=evil_script> |
一般来说,针对输入框的黑盒测试可能存在反射型XSS,也可能存在存储型XSS,还有可能是DOM型,针对Url参数的黑盒测试绝大多数只存在反射型XSS或DOM型XSS。
常见标签
img标签
1 |
|
a标签
1 | 标准格式 |
input标签
1 | 标准格式 |
form标签
1 | XSS利用方式1 |
iframe标签
1 | XSS利用方式1 |
svg标签
1 | <svg onload=alert(1)> |
3.4.2工具检查
XSS的自动检测软件有,Burp的Scan模块,BruteXSS等
4.shellcode的绕过
4.1 绕过XSS-Filter
XSS-Filter是一段基于黑名单的过滤函数,大多数CMS都有这么个函数,作用于用户的每一个输入点,用于过滤可能的恶意代码。不过从某种意义上来说,基于黑名单的保护是一定不会是安全的,由于XSS的多变性,几乎不可能存在完全地过滤。
4.2 空格回车和Tab
对XSS-Filter而言,如果仅仅是将函数加入黑名单处理,那么可以在函数名称之中尝试加入空格、回车、Tab等键位符来进行绕过。这是由于在javascript中只会将;作为语句的终止符,当浏览器引擎解析javascript脚本时没有匹配到;便会继续处理,知道发现下个分号为止,而换行符并不是终止符。如下列代码可绕过对关键字javascript|alert的过滤:
1 | <img src=javascript:alert(/xss/)> |
4.3 对标签属性值进行转码
HTML中属性值支持ASCII码形式,如:
1 | <img src="javascript:alert('xss');"> |
替换成
1 | <img src="javascript:alert('xss');"> |
其中在ASCII表中116为t,58为:。也可以将,等插入javascript的头部,还可以将tab(	)|换行符(
)|回车键(
)插入到代码中的任意位置。
4.4 Fuzz标签未过滤事件名
如以下例子:
1 | <img src=x onerror=alert(/xss/)> |
其中的onerror即为IMG标签的一个事件,通常这样的事件都是以on开头,常见的有:
1 | onResume onReverse onSeek |
4.5 使用CSS绕过
利用Css样式表可以执行javascript的特性,如
Css直接执行javascript:
1 | <div style="background-image:url(javascript:alert('xss'))"> |
1 | <style> |
css中使用expression执行javascript:
1 | <div style="width: expression(alert('xss'))"> |
上述的两个例子中,都用到了样式表的url属性来执行XSS代码。
除了上述两种,还可以利用@import直接执行javascript代码
在现实环境下,HTML页面中的Css与Javascript的嵌入方式很相似,且Css也可以执行javascript代码,故我们的XSS代码也可以通过嵌入远程恶意css文件来进行XSS攻击。
4.6 扰乱规则
大小写变换;
利用expression执行跨站代码的时候,可以构造不同的全角字符来扰乱过滤规则;
结合样式表注释字符/**/,通过css执行javascript
样式标签会过滤\和\0,可以构造如:
1
@i\mp\0\0ort 'jav\0asc\0rip\t:al\0er\t("x\0ss")'绕过
Css关键字进行编码处理,如:
1
<p style="xss:\0065xpression(alert(/xss/))">
其中65为字母e进行unicode编码后的数字部分
利用浏览器解析注释的问题
4.7 利用字符编码
javascript支持许多的编码格式,如:
- unicode
- escapes
- 十六|十|八进制
5.XSS 防御
5.1 给cookie设置httpOnly
设置 Cookie 的 httpOnly 属性时,会致使客户端脚本(即JavaScript)无法访问cookie的信息(例如在控制台打印document.cookie无法获取到信息),只有与服务端交互的时候,http请求头才会带上该cookie的信息(控制台Network-包名-Headers-Request Headers-Cookie可查看详细信息),从而减少 Cookie 被盗取的可能性;但由于网站本身可能也需要获取 Cookie 的信息,因此通常来说,我们只会在部分重要的 Cookie 上(如密码)设置 httpOnly 属性。
5.2 输入检查
(一) 白名单
定义:判断输入格式,只允许通过特定格式的字符。
对于只允许用户提交纯文本的情况下。例如注册帐号时,使用白名单的形式检测邮箱的格式是否正确;
对于允许用户提交一些自定义 HTML 代码的情况下(富文本),如评论框、帖子的内容有图片、链接、表格等(需要通过 HTML 代码来实现)。使用白名单的形式(只可以使用指定的标签和属性)来实现输入检查。
(二) 黑名单
定义:收到数据时过滤危险字符
1 | (各种标签与属性,如<script>,<style>,<iframe>,onclick,onerror等),或者转义特殊字符(如:<--><,>-->>,&-->&,\-->","-->",'--'>等) |
对于允许用户提交一些自定义 HTML 代码的情况下(富文本),可以使用黑名单来过滤与转义危险字符。过滤与转义需前端与服务端配合使用,因为可以使用某些工具(如Node)绕过前端检测,直接发送数据给服务端。
5.3 输出检查
HTML 标签中(用户输入将在 HTML 解析环境进行)
HTML 属性中(用户输入将在 HTML 解析环境进行)
script 标签中 (用户输入将在 JavaScript 解析环境进行)
HTML 事件属性中(用户输入将在 JavaScript 解析环境进行)
地址栏中(用户输入将在 URL 解析环境进行)