Blog |

The NPM package that walked away with all your passwords

Detecting malware in package manager repositories

Tomislav Pericin Author: Tomislav Pericin, Chief Software Architect & Co-Founder at ReversingLabs

The NPM package that walked away with all your passwords

Software developers are increasingly being targeted by supply chain attacks. Popularization of package managers and their integration into the development pipelines has made this ecosystem an interesting target for various threat actors. A testament to how successful they’ve become at this is the frequency at which such stories appear in the media. Recently it feels like new supply chain attacks are being discovered and talked about on a daily basis.

Developer account or build environment compromise are the two main ways attackers subvert the development infrastructure. Once in, they have an almost infinite number of ways to plant malware and introduce backdoors into the software package.

Backdoors are particularly tricky to detect because of this. A single line of code that changes the logic of the program can be a backdoor that allows unauthorized access to the system. Similarly, a single line of code is all it takes for a script to reach out to a remote server and download instructions to execute on the infected machine. Because of this, such supply chain attacks are usually detected post-infection, by developers themselves, upon realization that something odd is going on in the system.

Malware is what usually follows a successful backdoor installation. And its second stage payload can be anything, from credential stealing malware to ransomware or crypto mining software. In today’s world, most attackers are financially motivated and will use their position for any sort of gain.

The complexity of finding these supply chain attacks cannot be overstated. A backdoor that leads to an infection can be a single line of code, one that’s hidden away, surrounded by hundreds of others written by the original software authors. And that backdoored package is just one of the million others hosted in the package repository. That makes checking all this code a daunting task, to say the least.

NPM, node package manager, aimed primarily at JavaScript developers, is one such behemoth. It hosts almost 9M packages, which in turn consist of 1.7 billion files, or just under 37.5TB worth of data - numbers that are only getting bigger with each passing day.

We processed the entire NPM repository with our Titanium Platform static analysis solution running on a single server with one AMD EPYC 32 core processor, 256 GB of RAM, and two 3.5 TB NVMe SSD disks. This analysis took slightly under 6 days and 16 hours to complete, during which we’ve collected, and indexed, around 1.6TB worth of metadata. This metadata, generated by our static analysis engine, is what allows us to hunt for malicious files and answer complex questions - like which packages contain portable executable files that are similar to previously known malicious pieces of code. And, as it is implied by the title of this blog, we did find a few of those.

Looking at the breakdown of interesting file types and subtypes we’ve found during our analysis, there’s certainly more in these packages than just JavaScript.

Fig: Breakdown of filetypes and subtypes across the NPM repository


Fig: Breakdown of filetypes and subtypes across the NPM repository

Intrigued by the presence of executable code for Windows, PE files on the graph, we decided to dig in and take a closer look at the packages containing this file type. Among the plethora of Mono .NET applications and common third-party libraries, stood a pretty well-known potentially unwanted application - a password recovery tool. We call these kinds of applications potentially unwanted as their use, or misuse, has to be put in context. A password recovery tool used to refresh your memory when you forget a website credential is OK, but it being found in NPM repository, probably not OK.

The password recovery tool in question is WebBrowserPassView. It is used to recover website login information stored by Internet Explorer, Mozilla Firefox, Google Chrome, Safari, and Opera browsers.

Fig: WebBrowserPassView


Fig: WebBrowserPassView

Its interface and usage are pretty straightforward, but that’s not the reason why threat actors use it. The appeal of this tool is in the fact that it can be used programmatically from the command line, without even showing the graphical interface, to store the credentials list shown above to a file. That makes it perfect for threat actors. With all the complexity of password recovery taken away, they can focus on what really matters: easy credentials.

We found this password recovery tool in a package called bb-builder, and its story is certainly an interesting one. It was uploaded to the NPM repository by a pretty active open source developer, someone with hundreds of projects on their personal GitHub page. But this bb-builder project isn’t one of them. Furthermore, that is the most recently published and updated project on their NPM page, telling us that the account probably isn’t actively used anymore.

Inspection of the code within the different versions of bb-builder paints a picture of how this code was developed. And with the help of the metadata NPM registry tracks about these packages, the timeline of this supply chain attack can be perfectly reconstructed.

2018-03-04 14:22:58
bb-builder project is created and its initial version 1.0.0 is uploaded to the NPM repository. The package is empty and contains a very basic placeholder manifest. This is likely done to test if the compromised developer credentials are still valid.

2018-03-04 14:26:18
bb-builder project is updated to version 1.0.1. This is the first version to include the password recovery tool. Its use, however, is rudimentary. The JavaScript code just calls the tool to log the passwords to an HTML file. This is likely done to test the level of security the NPM repository has, if it would detect the password recovery tool and block the package as malicious.

2018-03-04 14:55:47
bb-builder project is updated to version 1.0.2. Dependency on Axios package is added, an HTTP client that can post web requests. This dependency is used to submit the password recovery output to a web server hosted here http://1[.]host[.]jwte[.]ch:1337/pwn

2018-03-04 15:01:36
bb-builder project is updated to version 1.0.3. The attacker realizes that storing the password recovery output in the current working directory probably isn’t the greatest idea and decides to change that to a more discreet location.

2018-03-04 15:03:17
bb-builder project is updated to version 1.0.4. The attacker realizes that the server that’s set up to receive the passwords isn’t getting any traffic from his test machine. There’s a bug in the code that incorrectly tries to locate the password recovery output. It is fixed.

2018-03-04 15:15:54
bb-builder project is updated to version 1.0.5. The attacker refactors the code a little bit to make it easier to maintain down the road.

2018-03-04 15:27:18
bb-builder project is updated to version 1.0.6. The attacker decides that leaving the evidence in the form of the password recovery output also isn’t a great idea and decides to add code that deletes it after submission to the previously mentioned web server. This is the final version of bb-builder project.

The following image shows the entirety of the JavaScript code that performs the credential theft.

Fig: bb-builder JavaScript


Fig: bb-builder JavaScript

Download statistics for this NPM package give a glimpse into its possible prevalence in the field.

Fig: Download statistics for NPM project bb-builder


Fig: Download statistics for NPM project bb-builder

This package isn’t included in any other as a dependency, therefore its installation prevalence can only be attributed to wrongful installation by developers that were looking for a different package with a similar name. The NPM repository hosts a few dozen packages that start with the term bb. It is very likely that the ones that have installed bb-builder by mistake were looking for the package bb-build instead.

The domain that collected the stolen credentials is gone at this point, and the damage bb-builder package can cause without it is practically zero. But its existence is a cautionary tale of how easy it is for these kinds of attacks to hide in plain sight, and how easy it is to remain undetected for a very long time.

Titanium platform is the ultimate static analysis solution capable of taking on the challenge that is large dataset analysis. But its power isn’t only in the malware detection rules we’ve put into it ourselves, it is also in the flexibility that it gives its users to extend it by adding their own. This allows for rapid threat hunting iterations. Regardless of the dataset being processed, be it a public one like NPM or a private one that you own, hunting for threats has never been this fast.

Preventing software supply chain attacks that target your developers is only possible with a platform that can inspect every single package they use.

Affected packages and SHA256:
bb-builder-1.0.0: fb160a0b7b139e38a4922a4337230da7a20e38995f9513971428945babfe688c
bb-builder-1.0.1: 06a80e6e86c70f56ca253efd0cf3fb7d5491756a30d10648a25b615b04d87d95
bb-builder-1.0.2: 5467f6c7b92e31681fb23a63242304d3c3c90b4e8a101fe32fd5cd78015bb4dd
bb-builder-1.0.3: 835edf362c92a6603df943167dcd52b18f5cf422d13ca92089b4919c331dcffe
bb-builder-1.0.4: f0f0cab3e665063ec607d3a389cc11e76676510b494aa45e3321de8a1eef94dc
bb-builder-1.0.5: d374e697c52b701a80e6460bba905afbcc32961f2384c380cae0d471abd6ea39
bb-builder-1.0.6: f0af6bfb31acd4b73ba75efa4c135a498e8545ac0bf74abd8b654d38a27a4e55

Disclosure timeline:
08/20/2019 - Contacted NPM security team
08/21/2019 - NPM security team removes the packages (advisory)

To learn more about how static analysis can find malicious code within a package manager repository, listen to our podcast hosted by Cyberwire: Detecting Malware in Package Manager Repositories