2023/08/25 9:57PM
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.
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.
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.
When we enter in our login information, we receive back a login token from the child `iframe`.
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.
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.
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.
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