Dependency confusion, sometimes referred to as substitution attack, dependency repository hijacking, or simply repo jacking, is a software supply chain assault in which a valid internal software dependency is replaced with malicious third-party code.
This type of attack vector can be created in several ways, such as
Namespacing: By uploading a malicious software library to a public registry (such as the Python Package Index [PyPI] or JavaScript's npm registry) with a name that is similar to a trusted, internally used library, systems that do not perform a namespace/URL check may unintentionally load the malicious code.
DNS Spoofing: Systems can be tricked into downloading dependencies from malicious sources while presenting what appear to be authentic internal URLs or routes by employing a method known as DNS spoofing.
Scripting: Systems can be configured to change CI/CD pipeline configurations or build/install scripts.
Initially, this type of attack vector was found by Alex Birsan:
After understanding this vulnerability, I quickly made me busy searching for this bug pattern on web2 companies such as Microsoft and Apple.
Months later, surprisingly I found this bug on one of the Cod4rena Timeswap(web3) contests. Although it’s Out of scope, the project validated and fixed this bug and rewarded around $5000 bucks.
So, let’s dive into this
I discovered an npm package and the scope of the package is unclaimed on the NPM website. This will give any User to claim that package and be able to Upload a Malicious Code under that unclaimed package. This results in achieving the Remote code execution on developers/users' machine who depends on the timeswap repository to build it on local env.
Vulnerable Package Name: @timeswap-labs/timeswap-v1-core
Proof of concept:
Create an Organization called "timeswap-labs".
Create a package called "@timeswap-labs/timeswap-v1-core" under "timeswap-labs" Organization.
An attacker can able to upload malicious code on an unclaimed npm package with a higher version like 99.99.99
Now If any user/timeswap developer installs it by npm install package.json. The malicious pkg will be executed.
An attacker can inject a backdoor when the project team imports their private package.
Claim the Scope name called "timeswap-labs" By Following the above POC Step 1.
I think the issue here raises an interesting exploit where an attacker could inject malicious code into a smart contract dependency. As such, I think this is relevant and a valid attack path. Rewarded around $5000
I have Found a Python package named "OSXFrameworks" which is Private and Apple has the Copyright and Manages the Package under the Apple Github page. I Register the "OSXFrameworks" on Public as Pypi Package. Before Uploading it to Pypi I have Setup the RCE Script on the setup.py File to Execute RCE when any External User installs the package by "pip install OSXFrameworks".
The root cause of the problem is "package names are unclaimed on pypi"
Osxframeworks Github Page: https://github.com/apple/ccs-pyosxframeworks/blob/master/setup.py
Malicious "OSXFrameworks" pypi package: https://pypi.org/project/OSXFrameworks/
Steps to Reproduce:
Merge package setup file with RCE script on setup.py
The version in the setup.py must be a higher version than the original GitHub repo.
In this case, the Orginal "OSXFrameworks" has 0.1 and I changed it to 0.1.7 in setup.py
Upload the Package with Relevant Files to pypi.
Then wait for the connection in your Server by using netcat or any reverse shell.
I set up the RCE script to retrieve the IP address and Current working directory when any User Executes the "pip install OSXFrameworks".
I Got Successfully a Code Execution when the user installed my Package. I Attached Proof as a Screenshot.
Impact: It's a Reputational Loss to Apple Because Apple has the Copyright for this Private Package and does not have the Version control i.e. A lock File to Control Version.
When we address a problem in our web applications, we like to give credit to the person who reported the issue to us. Hall of Fame link:
I Found a Python package name called "qlib_server" that is unclaimed on the PyPI website. So I claimed this package name on the PyPI to upload a malicious rce script on it. It's a Dependency confusion.
Attack Scenario: The Attacker claims the package and uploads it to the public on pypi with a higher version than the original package version on GitHub. Also, the attacker attaches the script to the setup.py file. when any External or Internal user run "pip installs “qlib_server", my malicious rce script will execute! I set up the rce script to retrieve the current working directory of a user
Steps to Reproduce:
Claim the Package "qlib_server"
Upload it with the rce script in setup.py file.
Mention a higher version than the original Github repo.
when any External or Internal user run "pip install qlib_server", my malicious rce script will execute!
I got multiple rce from random servers that are trying to install my malicious package. These are also a dependency confusion vulnerability from a different angle.
I have attached a screenshot that literally shows the rce results, which I got from potential internal or external users.
Impact: It's a reputational loss to Microsoft because Microsoft manages the vulnerable package under their github repository and they have Copyright. The root cause for this problem was the package name was unclaimed on pypi.
The Malicious Package that I have uploaded on Pypi: https://pypi.org/project/qlib-server/
Microsoft adds my name into their MSRC Hall of Fame.