This blog post will cover two techniques that persistent, high volume malvertisers have been leveraging in recent months to maximize the impact of their campaigns. We will also disclose the details of a security bug that we recently found in Opera for Android (CVE-2019–19788) as a result of our ongoing research into iframe sandboxing and popup blocker bypasses.

Background

The term malvertising is usually used to encompass any number of attacks where digital advertising is the delivery vector for a malicious payload. Over the last several years, the majority of malvertisements have been ads that appear legitimate on the surface, but spawn forced redirections or pop-ups to phishing pages, tech support scams, or malware downloads.

Much like the rest of the cyber threat landscape on the internet, anti-malvertising mitigation is an arms race between security vendors and the perpetrators with the bulk of the battle taking place inside the browser.

It’s easy to take for granted just how large of an attack surface web browsers can provide to folks with bad intentions. Browsers are comprised of millions of lines of code and browser vendors are under tremendous pressure to implement new features and APIs to keep up with rapidly evolving web specifications put forth by the W3C.

As new APIs and standards are proposed and built, it’s inevitable that browser vendors will vary in their implementations and these subtle differences can have some really niche security implications. This is important for us to keep front of mind during our research, because if something strangely unique is targeting specific browser types or versions, it might be indicative of such abuse.

Intent Based Iframe Sandbox Bypass On Firefox Android

A good example that we came across towards the tail end of 2019 comes from a malvertising group that we’ve written about before called Zirconium:

Consider the following redirect payload:

finalDestination5 = "hxxp://tags.bluekai.com/site/35702?redir=" + encodeURIComponent("ftp:hxxps://[redacted].com/index/2013381515?id=12933&referer=pcgames.de&hash=DAdZWUBcb3h1b3EBHVZCTEZzfGpzdgUOV15PXHdwdHRmdXo%3D".split("ftp:")[+!!"avada kedavra!"]); try {

top.location.href = finalDestination5

} catch (e) {

try {

var url = "hxxps://[redacted].com/index/2013381515?id=12933&referer=pcgames.de&hash=DAdZWUBcb3h1b3EBHVZCTEZzfGpzdgUOV15PXHdwdHRmdXo%3D".split("/")

, scheme = (url[0] || location.protocol).replace(":", "");

location.href = "intent://" + url.splice(2).join("/") + "#Intent;scheme=" + scheme + ";package=com.android.chrome;end";

} catch (e) {

new Image().src = "//bit.ly/[redacted]";

}

}

;

There are a few interesting things going on here:

The first attempt at redirection is via unvalidated redirect through ad tech vendor BlueKai.

The second attempt at a redirect is via an Android Intent URI Scheme, and its failure is tracked separately via a bit.ly event tracker.

Any time we see a redirect that deviates from the basic mechanism of top.location.href = “http://…” we need to ask ourselves, “Why is it being done like this?”

These abnormalities typically exist either for the sake of obfuscation, or because the attacker is taking advantage of a bug or quirk that optimizes the impact of their campaign.

The most common types of bugs we find from analyzing these types of payloads are cross-origin iframe sandbox bypasses. For testing purposes, we can distill this payload into one line of JavaScript:

location.href = "intent://malicious_landing_page/#Intent;scheme=https;package=com.android.chrome;end"

Before we can explain what this means and why it’s interesting, we need to understand exactly what an Intent is within the context of Android. For those who might not be familiar with it, the basic concept is actually quite simple. Android apps are actually software packages comprised mainly of Activity components or Service components.

An Activity, according to the Android documentation is a “single, focused thing that the user can do. Almost all activities interact with the user...” so activities are most often represented by windows, overlays or UI components in an app (but not always).

An Intent, on the other hand, “is an abstract description of an operation to be performed…An Intent is a messaging object you can use to request an action from another app component.”

Which brings us to the Intent URI scheme. In addition to providing the ability for Activities to interact with each other across different applications via Intents, the Android ecosystem is also big on deep linking — that is Android apps can implement custom URI schemes for external apps or websites to link to. For example, when a mobile web browser asks you if you want to complete a certain action in a native app and then spawns that app, this is usually done via such a deep link.

Lots of additional documentation on the inner workings of Android can be found in the official developer documentation:

With that little primer out of the way, we begin to understand what’s happening with the Zirconium Intent URI redirection. Looks like the link is passing along the redirect url via Intent to the Chrome app. How cool! But also… why would they chose to do it this way? Does it circumvent any security measures?

We begin our investigation by staging the payload in a cross-origin iframe with the following standard ad serving sandbox attributes:

"allow-forms allow-pointer-lock allow-popups-to-escape-sandbox allow-popups allow-same-origin allow-scripts allow-top-navigation-by-user-activation"

With these attributes, IFrames will prevent forced redirections that are not user initiated, but does it hold true for Intent URIs? Turns out that it does not on FireFox Android!

The Intent URI scheme is a great example of browser functionality that’s not defined by any concrete standard. For example, Chrome made some decisions around Intent URI support a while back to apply some user activation restrictions to Intent URI’s in general in many situations, but FireFox went a different route:

We reported this abuse to the FireFox team just about 4 months ago and a decision is yet to have been made on how to handle Intent URIs from IFrames.

*At the time of this discovery, Zirconium were heavily targeting FireFox browsers in their campaigns.

Zirconium By The Numbers

Zirconium is a malvertising group whose ongoing activity has years of history. They stand out from among the malvertising crowd with their unique Javascript obfuscation techniques and long lived campaigns that fall in and out of dormancy between long periods of steady activity.

Zirconium hits blocked by Confiant over the last 30 days.

Zirconium hits by geo over the last 30 days.

Zirconium hits by OS over the last 30 days.