Info

Tags: Challenge, Sensitive Data Exposure, JavaScript, Web Security

Description

Mission brief Cross-domain iframe communication? Sounds insecure...

Instructions Hello there! Your task is simple:

Have fun and please do not use external resources in your payload, otherwise your solution will be rejected.

Enumeration

I got access to 2 pages.

An attacker one(which needed to steal the token from the main page):

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/9fb9fa69-2b1b-446e-9663-de948d34827d/Untitled.png

Main page and attacker page editor:

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/af1f2619-35c6-4b8a-808d-2d3f499a228f/Untitled.png

I clicked on Open in new tab in order to be able to look into the source of the target page.

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/f89320b7-efe0-44f0-a84a-6a4f2bb87220/Untitled.png

Source code of the target page:

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Secret Tokens</title>
  <link rel="shortcut icon" href="static/favicon.ico">
  <link href="static/bootstrap.min.css" rel="stylesheet">
</head>

<body>

  <div class="container">
    <div class="d-flex flex-column flex-md-row align-items-center p-3 px-md-4 mb-3 bg-white border-bottom box-shadow">
      <h3 class="text-muted my-0 mr-md-auto">Secret Tokens</h5><a href="/webservice" target="_blank">Open in new tab</a>
    </div>

    <div class="container">

      <p class="alert alert-danger">
        Your secret token is: <b id="token"></b>
        <br>
    </div>

    <footer class="footer">
      <hr>
      <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Do not share it with anyone.</p>
    </footer>

  </div>
  <script>
    window.addEventListener('message', function(d){
        let message = d.data;
        document.getElementById('token').innerText = message;
    })
</script>
<iframe style="display: none" src="iframe?parent_origin=https://f19fdbffdf3834872b40b45669c4810c87bbf350.platform-next.avatao-challenge.com/webservice"></iframe>
</body>
</html>
<iframe style="display: none" src="iframe?parent_origin=https://f19fdbffdf3834872b40b45669c4810c87bbf350.platform-next.avatao-challenge.com/webservice"></iframe>

I clicked on it to take a look at the source.

<html>
  <script>
    let WHITELIST = ["avatao.com", "<https://f19fdbffdf3834872b40b45669c4810c87bbf350.platform-next.avatao-challenge.com/webservice>", "localhost", "avatao-challenge.com"];

    function validateOrigin(url) {
      let regex = /^(?:([^:/?#.]+):)?(?:\\/\\/(?:([^/?#]*)@)?([^/#?]*?)(?::([0-9]+))?(?=[/#?]|$))?([^?#]+)?(?:\\?([^#]*))?(?:#([\\s\\S]*))?$/;

      let origin = url.match(regex)[3];
      for (item of WHITELIST) {
        if (origin.endsWith(item)) {
          return true;
        }
      }
      return false;
    }

    let parentOrigin = new URL(location.href).searchParams.get('parent_origin');

    if (parentOrigin && validateOrigin(parentOrigin)){
      parent.postMessage("e3441ad7-e124-4349-b7cf-64b7493f4450", parentOrigin);
    }
  </script>
</html>