Written by: Dan Shallom, Cyber-security expert at OP Innovate.
- There is a need for awareness of the potential risks of using open-source code
- Introducing the DLL preloading vulnerability we discovered on Kerberos.
- Mitigation & helpful tools and utilities.
- The CVE: https://nvd.nist.gov/vuln/detail/CVE-2020-13110
For those who are not familiar with NPM (Node Package Manager), it is a gigantic software registry that contains hundreds of thousands of open source Node.js projects in the form of packages. As a matter of fact, if a developer wanted to share their code with the world, NPM would be a good way to do it.
Open Source development brings much to the world by sharing ideas, perspectives, and yes, eventually, helpful code. Unfortunately this code, in many cases, is not implemented with security in mind. Think of it like this: a machine is built to supply its clients with X, Y, and Z which it does successfully, at least at the beginning. You see this machine was brought to market without ever undergoing a rigorous battery of testing under laboratory conditions. In time defects will begin to show and it may even become dangerous to its surroundings. So in addition to diminishing reliability, it turns into a workplace liability, an accident just waiting to happen.
In general, it is not recommended to use open-source packages without fully reviewing and testing them to confirm they are flawless and well secured.
Let’s dig in!
So let’s get our hands dirty with some hot-off-the-press findings. While conducting research for one of our clients we came across an NPM Kerberos package. In practice, Kerberos is a ticket-based authentication protocol that offers a stronger encryption capability than its predecessor, NTLM.
This NPM package is responsible for supporting Kerberos authentication using the Generic Security Services Application Program Interface, on cross-platform services. While reviewing the package files, we found something of particular interest: “kerberos_sspi”. SSPI (Security Support Provider Interface) is a Win32 API component that is essential for performing security operations such as the authentication itself.
Before we dive deeper into the technical details, consider this. So far there have been 28 versions of this package. 23 of them are vulnerable. Furthermore, the package has 3 dependencies. In order to understand the rate of spread (refreshingly, we’re not talking about Covid-19), here’s a graph that represents the number of downloads each week during the last year:
Our research focused on one component used inside the package file that poses a great risk to the overall security of the user: the dynamic loading of DLLs.
The method responsible for this is called “LoadLibrary()” and it has two possible implementations: the first is supplying a fully qualified path. The second is searching for a named DLL by running through a list of directories.
The LoadLibrary() searches for the named DLL in these directories in a set order and stops when it finds the DLL it is looking for. An attacker could therefore inject a legitimately named but malicious DLL into the first directory that is searched. The “LoadLibrary()” would find this DLL and stop its search. This malicious DLL would then be loaded into memory bringing with it potential for ACE (arbitrary code execution) and privilege escalation.
POC – Arbitrary code execution (ACE) and privilege escalation (PE)
Injecting a trojan DLL into an endpoint’s memory can lead to the execution of malicious code with unlimited possibilities on the endpoint, but arguably the most interesting is privilege escalation. Using highest privileged access, an attacker gains full control over the system and can view, edit and modify system files.
The reason ACE and PE attacks are mentioned in one breath is that when they are chained together, their effect causes a severe impact on the system. When combined, the attacker can execute code remotely. Thus ACE evolves into RCE (remote code execution).
Here’s how an attacker can exploit this attack:
When using functions such as “LoadLibrary()” it is essential to provide a full path for the assembly file in order to avoid preloading. With that being said, it is essential to update the Kerberos package to the latest version (that’s true of all packages, of course) before deploying this software in your product.
Vulnerable versions: 0.0.1–0.0.24
Secured versions: 1.0.0–1.1.3
In conclusion, it’s important to remember that open-source code is built and designed to do a job, often without security best practice in mind. We recommend adopting a habit of manually testing any open-source code that is integrated into your solutions, for vulnerabilities it may sneak into your solution. Eye-reviewing the code is always the best solution.
Contact us and learn more about how to secure your code!