5 years ago, I published a blog post covering one of the most widespread and potentially damaging Cryptojacking attacks seen on the Web. Despite the extensive coverage in global media at the time, and the realisation of just how bad things could have been, it seems we really didn't learn our lesson.
The Government Cryptojacking Attack
You can read the full blog post I published back in 2018 that goes into all of the details much more than I will here. In this blog post, I want to focus on what we took away from that attack and what changes we've seen in the industry since.
We Got Lucky
Not only did we get lucky, we got lucky in more ways than one.
Ian, who got the Antivirus warning, found the attack ~3 hours after it had started! Talk about a rapid detection, but, it could have been there for months prior. Not only that, but had he not got the warning, or had the attackers taken any basic precautions to avoid detection, the attack could have lurked for days, weeks or even months longer too. Here's the script file archived at Sun, 11 Feb 2018 05:22:27 and it's clean, then the next archive was Sun, 11 Feb 2018 11:26:33 and the file has been infected.
The first person that Ian tipped off about this was me. He knew to raise it with someone that works in the area of web security and I was able to quickly identify the source of the attack. Given the nature of the attack and that it needed to be stopped quickly, I went public and started reaching out to all of the appropriate organisations to try and get a rapid response, which started less than 48 hours later after the NCSC here in the UK reached out to me.
The luckiest thing about this, though, was that the attackers seemed to lack any imagination at all. Just pause for a second and think about your answer to the following question:
Honestly, I can't believe that all the attackers decided to do was mine some Monero, but I also think that's part of the problem with regards to the lack of response. Had this been some cataclysmic event, and the attackers had done any one of a thousand things that would be highly visual and damaging, there would have been much more impact. I discussed the possibilities widely in the press at the time, and the striking thing was that you could do almost anything you can think of, as long as you can copy/paste the code from Stack Overflow!!
This Is A Solved Problem
As I discussed back in my original blog post covering this incident, we already have a pair of technologies that were designed to help with exactly these kinds of attacks. Both Subresource Integrity, which I first covered in 2015, and Content Security Policy, which I first covered in 2014, could have stopped this attack, but neither were in use.
You can read my blog posts on both of those security mechanisms for great detail, but I can summarise them quite easily here for you.
<script src="//www.browsealoud.com/plus/scripts/ba.js" integrity="sha256-Abhisa/nS9WMne/YX+dqiFINl+JiE15MCWvASJvVtIk=" crossorigin="anonymous"></script>
By adding that
CSP: script-src 'self' browsealoud.com; connect-src 'self' browsealoud.com
browselaoud.com and apply the same restriction for outbound connections from the page, only to yourself and
browsealoud.com. This CSP would do either or both of 1) stopping the
coinhive.com JS from loading and 2) stopping the stolen Cryptocurrency from being sent to the attackers.
Where Are We Today?
There have of course been various studies into this, many companies (including my own) now offer features and products to help you with this problem, but it was a particular whitepaper that was brought to my attention by another friend of mine and really spurred the creation of this blog post.
Some years ago, @Scott_Helme talked about a cryptominer on the ICO website, and how SRI could have potentially helped.https://t.co/KrK1GNC3r3— Devdatta Akhawe (@frgx) April 3, 2023
I am glad to say they .. no wait what 😂
(ht @nicknikiforakis excellent paper https://t.co/jHCGl7hV19) pic.twitter.com/sHQ9xGmYhV
We found that both domains include a ba.js script in the HTML of some pages that (1) first asks the URL browsealoud.com/.../sri.json for the SRI digest of a particular version of the browsealoud.js script, before (2) programmatically injecting the element with the digest. This is an incorrect usage of SRI that does not provide any security guarantee, even if the initial ba.js script were to be requested using SRI (it did not use SRI), because a compromised provider would be able to change the script content and the digest accordingly.
So the original
ba.js file that was infected a few years back is now simply acting as a bootstrap to pull in the required dependencies from the 3rd-party and it's getting the integrity attributes from... the 3rd-party... All the attacker has to do is infect the
ba.js file just like they did before and, while they're there, update the
sri.json file to change the hash, assuming of course that the hash isn't generated dynamically...
You can see this approach in the file (https://www.browsealoud.com/plus/scripts/ba.js) and looking through the archives, it seems that the vendor changed to this method in mid-2020. One original point of resistance from the vendor during the initial response to the attack was against offering versioned paths, which are required for SRI to work because the file has to be static to be integrity checked, it can't be dynamic. Having a versioned path meant the vendor would have to do feature deprecations and support older version, rather than the existing approach which was effectively "
latest.js" and the library just 'updates' any time when the vendor changes the file and they have no legacy support considerations. My guess would be that this approach gets them to a point where they can dynamically update the library on all of their customer sites without the customer having to update the version in the path for the JS file. The problem is, that was exactly the problem in the first place! Think about it: If the vendor can patch the JS you're loading into your site, then so can an attacker! At least now I suppose they can say "we're using SRI"... 🤷♂️
Getting Started Is Easy
src attribute of your script tag and we'll generate the new script tag for you to replace the old one.
For CSP, it's a little harder than copy/paste to get started, but it's really not much harder. We have a dedicated Content Security Policy page that gives you details, but the CSP Wizard is really the place to start. By using a CSP Report-Only header that sends reports for everything, but doesn't block anything, we can quickly audit all of the dependencies you have across your entire site.
Content-Security-Policy-Report-Only: default-src 'none'; form-action 'none'; frame-ancestors 'none'; report-uri https://demo.report-uri.com/r/d/csp/wizard
Once we've generated the list of dependencies that you have, we need you to tell us which ones are supposed to be there and which ones aren't. From that, we can generally build your entire policy for you! Even if you never decide to go to enforce mode, we can still monitor for new dependencies being added to your site, or any other changes, and alert you if they look suspicious. A CSP in Report-Only mode is still a very powerful monitoring solution and it shouldn't be overlooked.
If you want any more information specific to Cryptojacking or Magecart, check out those dedicated product pages or, you can look at our Case Studies for other real-world examples of where these kinds of attacks have happened and caused serious problems for the organisations involved. If you have any questions, feel free to drop them down below or you can email/DM me via the usual channels!