There are no doubts that the web is moving forward to HTTPS (secure) content. Most important names have today their certificates ready and their websites are in effect, secure. But have you ever wandered: secure to what extent? It’s clear that content served through HTTPS is protected from man in the middle (MITM) attacks, network sniffing/tampering and more. But, have you ever thought if the HTTPS protocol is protecting end users from something else? The answer is a clear YES.
As we know, attackers today deliver their malicious payloads using a wide range of channels and one of them is malvertising. They buy cheap ad-space to apparently advertise something, but deep inside those banners we can find obfuscated malware code. In fact, we’ve seen in the past how the bad guys were going as far as detecting if the user was a potential victim or if she’s was an analyst. If the human behind the keyboard was an unsavvy user attackers delivered the full malicious payload, otherwise they simply passed, masquerading themselves as innocent advertisers of a product.
Mixed Content Warning
Attackers have a problem these days because some of their tricks work only in insecure pages, and browsers by default do not render insecure content from secure sites. To be concrete, if attackers are forced to load their code via HTTPS, many of their tricks (like detecting files in your file-system) will fail. Consider this: modern browsers refuse to load insecure content (HTTP) from secure locations (HTTPS). This is called sometimes “Mixed Content”.
If we are navigating an HTTPS page, browsers will not load insecure content (for example, an HTTP iframe with a banner inside). Internet Explorer will warn the user with the option to “Show all content” (which reloads the main page and shows the mixed content).
Edge also blocks the content but shows no warnings unless the user has devtools-console in view. On the other hand, if the source of an iframe is insecure, a confusing error message is rendered instead of the HTTP content.
Images are allowed
An interesting exception is the fact that all browsers let insecure images load and render without restrictions. In other words, if attackers are already sniffing inside a network they will be able to view and replace images on the fly, but this does not seem to represent a real threat to final users. There’s a very clear blog-post written years ago by Eric Lawrence (aka: Internet Hero) explaining why the IE team allowed to load insecure images without warnings. It makes sense: tons of sites were loading their images from external places using the HTTP protocol or even worse, they had hard-coded in their sources the HTTP protocol pointing to local images, but the main content itself (html/scripts) was secure. So, they decided to allow image tags to render with no warnings except the little padlock at the right of the address bar, which disappears when insecure content is loaded.
This is how the address bar looks before and after loading insecure images on IE. Note that the secure protocol of the main address bar does not change at all. I’ve circled the padlock in red so it’s easier to see.
The same thing happens on Microsoft Edge but the padlock is on the left. If you want to experiment, try it live right here.
An interesting fact to keep in mind is that both browsers consider pseudo-protocols (res: mhtml: file:) insecure, and so we won’t be able to load them (like regular http inside https).
These iframes won't render anything if the main page is secure/https <iframe src="http://"> <iframe src="res://"> <iframe src="file://"> <iframe src="mhtml://"> <iframe src="mhtml:res://">
Behavior with Pseudo-Protocols
You might be thinking, what do HTTPS has to do with these strange mhml: and res: protocols? Well, those strange protocols are used by attackers to load content from your hard-disk and detect the presence of local files, but if the main page is secure, they will have a big problem: IE will refuse to render those protocols and thus, avoid running their tricks! Think about it for a moment: secure pages are not only helping us to be protected from MITM attacks, but as a side effect are preventing attackers to execute many of their tricks.
Remember: when attackers want to check if the user has a particular file in her file-system, they tend to use well known techniques that abuse of the mhtml/res/file protocols. If you’ve never seen this before, check out this post, but the main point here is simple: modern browsers do not allow “mixed content” by default, and many of those tricks will fail in HTTPS.
Forcing the Content to be Loaded
Now that we are clear on attacker’s intentions, it’s time to step in their feet and (try to) bypass these warnings. Knowing in advance that there’s an exception to the rule (image tags) that renders content without user interaction, I tried to load an image as the source of an IFRAME (instead of using an IMG) but had no success. Then a bit of playing with the EMBED and OBJECT elements (both can render html) without real success. Finally, I tried with a regular IFRAME but setting its location using a server redirect instead of the insecure URL directly. That seemed to work, the content was finally loaded.
Main page should be secure/https The iframe below renders an insecure (http) bing.com <iframe src="https://www.cracking.com.ar/redir/redir.php?URL=http://www.bing.com">
As a researcher this finding seems interesting, but not useful from an attacker point of view. We’ve been able to load mixed content without user interaction, but we still have a warning which obviously calls the attention. The warning shows a wrong message because insecure content is displayed (bing.com has really been loaded as http), however, attackers will never use something that warns the user like that.
The problem happens when the insecure bing.com tries to render yet another insecure iframe inside. In other words, nested iframes need to be secure even inside insecure parent iframes. Of course we can again load the content using a redirection but that’s not helpful in real life because attackers need to load the IE pseudo-protocols (mhtml: res: and file:) and IE does not accept server redirects to those ones. We need a better alternative.
Bypassing the Warning Messages
To bypass the warning message, the solution stumbled upon me. I was really surprised that something so basic made the trick: a document.write in the insecure iframe was enough. Can it be that simple?
Main page should be secure/https The iframe below renders an insecure (http) page which does a document.write <iframe src="https://www.cracking.com.ar/redir/redir.php?URL=http://unsafe.cracking.com.ar"> The HTML code in the iframe is quite simple: <script>document.write()</script>
Once we’ve loaded the insecure content and document.written inside, the iframe is free to load insecure content without the need of redirects. In other words, at this point attackers can load mhtml/res protocols and do their tricks without restrictions: IE has no idea that this content is being rendered and every nested iframe will be loaded without glitches.
Check out the PoC LIVE
Edge is vulnerable to the redirection trick, but the document.write one does not work. Maybe there’s an alternative, but I will stop here, knowing that attackers have simple ways to achieve their malicious goals.
Have a nice day!