On Aug 3, 2023 Phylum’s automated risk detection platform alerted us to a series of suspicious publications on
npm. The attacker eventually published final versions of two packages: a typosquat of a popular cryptocurrency library and a dependency that contained the malicious code buried deep in a large file that most developers would never bother looking at. The malicious code did not change the primary functionality of the cryptographic library. Instead, it makes an HTTP request to a Chinese server containing the user’s private key - game over for the unsuspecting user.
As of publication, these packages are still active on
npm with hundreds of downloads, and anyone using these packages should consider their cryptographic security compromised. Join us as we uncover the details of this ongoing attack.
The legitimate packages
First, we have the
A critical dependency for
npm with about 400K downloads.
First, we note that
@noble/curves contains a warehouse of cryptographic functions across about 100 files. Each of these files contain sophisticated code that most developers would never bother to scrutinize, making it an ideal hiding place. It is critical to point out that a compromise to or an error in any function in any of these libraries can have devastating effects, and
@noble/curves puts on the top line that its library is independently audited. This attacker exploited this trust to trick unsuspecting users into using his typosquatted fakes, instead of the legitimate packages.
@jackshanyeshuzi initially published
@jackshanyeshuzi/curvess a typosquat of
@noble/curves - note the extra
s in the typosquat - in his own namespace. (As an aside, changing the name from
curvess has no impact at all since the attacker chose to namespace his package.) Comparing the
README.md files between the two packages on
npm shows them to be nearly identical, but the careful observer would notice the important differences between the numbers of dependencies (1 vs. 2), dependents (132 vs. 1), and downloads (388K vs. 45).
With his spoofed cryptographic library in place, he published his first typosquat of the legitimate Ethereum package,
ethereum-cryptographyy - note the extra
y at the end on 3 August 2023. Shortly thereafter he published
This package appeared to be nearly identical to the legitimate package except for changing the dependencies as we can see by comparing line 4 this example.
package.json file also updates the dependency.
About 12 hours after
jackshanyeshuzi published the first typosquat
ethereum-cryptographyy, he unpublished it. Besides the false start typosquat package
ethereum-cryptograph which he published and unpublished within an hour, his main line of development was in
ethereum-cryptographyyy. Most of his versions are tests of minor changes, but his main goal can be seen in v.1.1.3 of
@jackshanyeshuzi/curvess in the file
abstract/weierstrass.js. Consider the first few lines of the legitimate package:
and compare with his version (line 10)
An import of the
http library has no legitimate use in this file. Farther down in the legitimate file, we find the function
Comparing with the attacker’s version, we see that his code is identical to the code in the legitimate
@noble/curves implementation of Weierstrass, except that his ships the user’s private key off to
wallet.cba123.cn before going about its business.
A quick lookup shows the key harvesting server in China, as confirmed by ICANN:
Later versions show him trying to cover his tracks with an amateur attempt at obfuscation:
It is easy to see that this code performs the same task.
The Phylum research team reported this package shortly after it was published, and as of this writing, the packages are still available on
npm with around 500 downloads so far. Any compromise of a private key in a cryptographic system should nullify any expectation of security. Moreover, this attacker did not directly change or weaken any of the cryptographic primitives in his spoofed library. He merely stole the keys by shipping them off to his server while the cryptographic code was going about its business.
This should serve as a reminder to remain vigilant about the open-source code that your organization imports, and especially all of their dependencies.
All of the versions of all of the package as of this publication are in the timeline below.
Development timeline for typosquatted packages
|2023-08-03T15:26:15.068Z||Published @jackshanyeshuzi/curvess v.1.1.0|
|2023-08-03T15:32:44.526Z||Published ethereum-cryptographyy v.2.1.2 (only version of this package)|
|2023-08-03T15:48:31.165Z||Published ethereum-cryptographyyy v.2.0.0|
|2023-08-04T02:20:45.551Z||Published ethereum-cryptograph v.1.0.3 (only version of this package)|
|2023-08-04T04:33:40.216Z||Published @jackshanyeshuzi/curvess v.1.1.1|
|2023-08-04T04:50:56.734Z||Published ethereum-cryptographyyy v.2.0.1|
|2023-08-04T05:58:13.285Z||Published @jackshanyeshuzi/curvess v.1.1.2|
|2023-08-04T06:00:33.479Z||Published ethereum-cryptographyyy v.2.0.2|
|2023-08-04T06:12:38.752Z||Published @jackshanyeshuzi/curvess v.1.1.3|
|2023-08-04T06:13:18.219Z||Published ethereum-cryptographyyy v.2.0.3|
|2023-08-04T06:23:43.895Z||Published @jackshanyeshuzi/curvess v.1.1.4|
|2023-08-04T06:24:21.969Z||Published ethereum-cryptographyyy v.2.0.4|
|2023-08-04T07:21:23.191Z||Published @jackshanyeshuzi/curvess v.1.1.5|
|2023-08-04T07:22:12.317Z||Published ethereum-cryptographyyy v.2.0.5|
|2023-08-04T07:34:44.749Z||Published @jackshanyeshuzi/curvess v.1.1.6|
|2023-08-04T07:35:17.807Z||Published ethereum-cryptographyyy v.2.0.6|
|2023-08-04T07:44:47.288Z||Published @jackshanyeshuzi/curvess v.1.1.7|
|2023-08-04T07:45:09.946Z||Published ethereum-cryptographyyy v.2.0.7|
|2023-08-04T07:55:44.509Z||Published @jackshanyeshuzi/curvess v.1.1.8|
|2023-08-04T07:56:23.687Z||Published @jackshanyeshuzi/curvess v.1.1.9|
|2023-08-04T07:56:47.192Z||Published ethereum-cryptographyyy v.2.0.9|