DigiNinja postMessage - Login Lab

2023/08/25 9:57PM

Description

In this scenario, the login for the system is performed by a script hosted on a different domain. The login page is held in an `iframe` and on a successful login it sends the token up to the parent, this page, so it can also use it.

Summary

This lab involves a child `iframe` that has an insecure configuration where the child `iframe` will send sensitive data to any parent. This is an issue if the `X-Frame-Options` header is not set because that means you can `iframe` the child website to receive the sensitive information.

Note: This attack doesn't always work on chrome browsers. If you want to test the exploit, I recommend using Firefox.

Step 1

We have a main website and then we also have an `iframe` with the login form.

If you go to the "Sources" tab in chrome dev tools, you can see that there is another `iframe` on the page.

Step 2

When we enter in our login information, we receive back a login token from the child `iframe`.

Step 3

Having a look at the parent website code we can see that the parent is including the child in an `iframe`.

Having a look at the child `iframe` code we can see that the `iframe` includes a JS file.

Having a look at the JS code, we can see that the child `iframe` is sending the sensitive login token to the parent using the wildcard origin. The means that the origin of the parent can be anything.

Step 4

Before we can exploit this `postMessage` vulnerability, we first need to check if we can put the child `iframe` on to our own website. The X-Frame-Options HTTP response header can be used to indicate whether or not a browser should be allowed to render a page in a `<frame>, <iframe>, <embed> or <object>.`

To check if the `X-Frame-Options` HTTP header is being set on a child `iframe` we can use chrome dev tools network tab and filter for Doc.

When we click on the `l_child.php` document, we can see that there is no `X-Frame-Options` header meaning we can put this document in an `iframe` on our own website.

Step 5

To setup the exploit I will host the following code on an EC2 instance.

exploit.html


    <html>
        <head>
            <title>PostMessage Lab</title>
            <script src="/exploit.js"></script>
        </head>
        <h1>Shelled's Website</h1>
        <body>
            <iframe src="https://html5server.digi.ninja/l_child.php" width="1000" height="1000"/>
        </body>
    </html>

exploit.js


    function receiveMessage(message) {
        console.log(message.data)
    }
    
    window.addEventListener("message", receiveMessage, false);

As you can see, I have a website an I'm putting the child `iframe` into the website.

This now means that the when the code in the child `iframe` `window.parent.postMessage(token, "*")` is executed, I will be the parent. In order to receive the message from the child `iframe`, I will need to have a listener for the message event. This can be seen in the `exploit.js` file.


    function receiveMessage(message) {
        console.log(message.data)
    }
    
    window.addEventListener("message", receiveMessage, false);

When the message is received, it will be logged in the console.

Step 6

Lets login to the application. As you can see, the sensitive token is being logged on our website.

To see a video view here: https://www.youtube.com/watch?v=9OAJVX--zJg&ab_channel=Shelled

Shoutout to [DigiNinja](https://twitter.com/digininja) for the awesome lab. You can try it out here: https://html5.digi.ninja/l_parent.php