Without altering a single line of code, attackers poisoned the NPM package “bignum” by hijacking the S3 bucket serving binaries necessary for its function and replacing them with malicious ones. While this specific risk was mitigated, a quick glance through the open-source ecosystem reveals that dozens of packages are vulnerable to this same attack.
Malicious binaries steal the user id’s, passwords, local machine environment variables, and local host name, and then exfiltrates the stolen data to the hijacked bucket.
The advisory depicted the interesting way in which the package was compromised.
The latest version of “bignum”, 0.13.1, was published more than 3 years ago and had never been compromised. However, several prior versions were.
Versions 0.12.2-0.13.0 relied upon binaries hosted on an S3 bucket. These binaries would get pulled from the bucket upon installation to support the functioning of the package. About 6 months ago, this bucket was deleted (the versions relying on it were mostly out of use).
This opened the bucket to a takeover, which resulted in the incident we are going to dive into.
What are "S3 Buckets"?
An S3 bucket is a storage resource provided by Amazon Web Services (AWS) that allows users to store, and retrieve, vast amounts of data over the Internet. It functions as a scalable, and secure, object storage service, storing files, documents, images, videos, and any other type of digital content. S3 buckets can be accessed using unique URLs, making them widely used for various purposes such as website hosting, data backup and archiving, content distribution, and application data storage.
The Beginning: Hijacking an Abandoned S3 Bucket
An NPM package, named “bignum” was found to leverage "node-gyp" for downloading a binary file during installation. The binary file was initially hosted on an Amazon AWS S3 bucket, which, if inaccessible, would prompt the package to look for the binary locally.
However, an unidentified attacker noticed the sudden abandonment of a once-active AWS bucket. Recognizing an opportunity, the attacker seized the abandoned bucket. Consequently, whenever bignum was downloaded or re-installed, the users unknowingly downloaded the malicious binary file, placed by the attacker.
It is important to note that each AWS S3 bucket must have a globally unique name. When the bucket is deleted, the name becomes available again. If a package pointed to a bucket as its source, the pointer would continue to exist even after the bucket's deletion. This abnormality allowed the attacker to reroute the pointer toward the taken-over bucket.
The Attack: Malicious Binary with Dual Functions
This counterfeit. node binary mimicked the functions of the original file. It carried out the usual and expected activities of the package. Still, undetected by the user, it also added a malicious payload that waws designed to steal user credentials and send them to the same hijacked bucket. The exfiltration was craftily performed within the user-agent of a GET request.
The Reversal: Unmasking the Hidden Functions
Reverse engineering the compiled file was no small task. Scanning the file using virus total did not yield any results, since it was not detected as malware. However, when looking at the strings contained within the file, it is easy to see that there is some weird behavior, so I had to dive deep into the assembly.
Starting with an endless list of byte additions to registries, comparisons, and data movements that initially seemed pointless, the reversing effort finally paid off - a URL was constructed by individually reversing the string parts.
Further investigation revealed that the binary file harvested data via functions like getpwd and getuid (as seen in the strings printout), extracting environmental data. It then created a TCP socket for IPv4 communication and covertly sent the collected data as a user-agent of a 'GET' request.
The Ripple Effect
Since it was the first time such an attack was observed, we conducted a quick search across the open-source ecosystem. The results were startling. We found numerous packages and repositories using abandoned S3 buckets that are susceptible to this exploitation.
The impact of this novel attack vector can vary significantly. However, the danger it poses can be huge if an attacker manages to exploit it as soon as this kind of change occurs. Another risk is posed to organizations or developers using frozen versions or artifactories as they will continue to access the same, now hijacked, bucket.
This new twist in the realm of subdomain takeovers serves as a wake-up call to developers and organizations. It underscores the need for stringent checks and monitoring of package sources, and associated hosting resources.
An abandoned hosting bucket or an obsolete subdomain is not just a forgotten artifact; in the wrong hands, it can become a potent weapon for data theft and intrusion.
Proactive Step to Prevent Future Hijacks
To prevent this attack from occurring elsewhere, we took over all the deserted buckets inside open-source packages we found in our search. Now when someone tries to reach the files hosted in these buckets, they will receive a disclaimer file we planted inside those buckets.
Attackers keep finding creative ways to poison our software supply chain, and this is a reminder of how fragile our supply chain processes are.
We need to understand that relying on software dependencies to deliver compiled parts in build time may inadvertently deliver malware if an attacker takes over its storage service.
We would like to thank the maintainer of the package Rod Vagg and Caleb Brown at Google for their cooperation and assistance with this investigation.
- Bignum v0.13.0:
- MD5: 1e7e2e4225a0543e7926f8f9244b1aab
- SHA-1: b2e1bffff25059eb38c58441e103e8589ab48ad3
- SHA-256: 3c6793de04bfc8407392704b3a6cef650425e42ebc95455f3c680264c70043a7
- Bignum v0.12.5:
- MD5: f671a326b56c8986de1ba2be12fae2f9
- SHA-1: ab97d5c64e8f74fcb49ef4cb3a57ad093bfa14a7
- SHA-256: 3ba3fd7e7a747598502c7afbe074aa0463a7def55d4d0dec6f061cd3165b5dd1