For our last Nexus Intelligence Insight of 2019, we'll cover a component vulnerability discovered in a not-so-happy accident that appears far more dangerous than the researcher had previously hypothesized.The back story starts with Carnegie Mellon University SEI researcher Will Dormann who was researching brute force password discovery and how the Bouncy Castle BKS version 1 file is vulnerable to a brute force breach using associated metadata with a file format kept largely unprotected by default. The empirical results of his experiment are both expected and unexpected and will hopefully help developers and security professionals alike, stay ahead of the threat this component potentially poses. We'll dig into the attack mechanics, the unintended find and what developers can do to remediate.
Name of Vulnerability/Sonatype ID: CVE-2018-5382
Type of Vulnerability: Information Exposure
CVSS 3.0 Metrics: CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
org.bouncycastle : bcprov-jdk14 : ( , 1.47)
org.bouncycastle : bcprov-jdk15on : ( , 1.47)
org.bouncycastle : bcprov-jdk16 : ( , )
The `bouncycastle` package is vulnerable to Information Exposure due to inadequate encryption strength. The `engineLoad()` function in the `JDKKeyStore.class` file uses BKS version 1 (which utilizes a 16-bit HMAC hash) which is not safe. This flaw allows an attacker to brute-force and derive sensitive values which can be used to compromise security or perform timing attacks.
Timing and side-channel attacks work by an attacker being able to deduce a secret by brute-forcing multiple values observing the time it takes for the processor to validate an incorrect answer from a correct one and return a response. This can, over time, deduce the secret or enough data for the attacker to be able to deduce the secret value.
In this particular case, the inadequate encryption length uses a 16-bit HMAC (hash) which, given the processing technology and hardware resources today, would be relatively trivial to brute-force for an attacker.
Let’s dig into the real life mechanics of this attack from CMU SEI researcher's experiment:
As stated above, Carnegie Mellon University SEI researcher Will Dormann demonstrates how the Bouncy Castle BKS version 1 file is special in that the associated metadata with a file of this format is kept largely unprotected by default and any use of keystore-level password and key is intended merely for verifying integrity and NOT to encrypt any metadata information itself.
A trivial Python script written by Dormann revealed a password but took a very long time to run as it utilized brute-forcing. The script keeps reading arbitrary passwords from a pre-fed password list (text file) and trying them one-by-one to guess the password.
The findings were surprising however when the same script ran concurrently on multiple resources using the “ProcessPoolExecutor” class as a means to optimize brute-forcing. This happened by accident as the researcher forgot to terminate the script once it had found a successful password guess. The result? Multiple, different passwords were revealed for the same file as the script kept on running!
How could this be possible? Multiple passwords for the same file?
This led the researcher to suspect if there was a strong possibility of hash collisions going on.
In most mainstream hashing algorithms being used today, such as SHA-256, or even those considered cryptographically weak like MD5, the chance of a hash collision i.e. that two different strings (of passwords) yielding the exact same or similar hash values is infinitesimally small for most cases. Although HMAC algorithms like SHA-1 have been proven to be susceptible to collisions, such a collision requires a very high processing power in practice, that is, "the equivalent processing power as 6,500 years of single-CPU computations and 110 years of single-GPU computations.”
Given the computation resources available today and in the last decade, 16-bit is by no means an adequate length when it comes to assuring password security. In 1996 alone, MD5 with its 128-bit key length was shown to be insecure and prone to collisions. This is why an HMAC securing passwords with a key length even 8 times smaller than that of MD5 would be catastrophic!
In the case of hashlib.sha1, the digest_size is 20 bytes (160 bits). But where it gets interesting is the derivation of hmac_key. The size of hmac_key is determined by hmac_key_size//8 (integer division, dropping any remainder). In this case, it's 20//8, which is 2 bytes (16 bits). Why is there integer division by 8 at all? It's not clear, but perhaps the developer confused where bits are used and bytes are used in the code.
For users of `org.bouncycastle:bcprov-jdk14` and `org.bouncycastle:bcprov-jdk15on` components, upgrading to version 1.47 is the recommended solution. However, a fixed version for `org.bouncycastle:bcprov-jdk16` component does not exist in Maven Central as of writing this piece.
In the fixed versions of Bouncycastle - i.e. 1.47 or newer, the BKS keystore format was updated to version 2, which uses a more rigorous HMAC of length 160-bit. This effectively resolves CVE-2018-5382.
DevOps-native organizations with the ability to continuously deploy software releases have an automation advantage that allows them to stay one step ahead of the hackers. Customers of Sonatype Nexus were notified of CVE-2018-5382 within hours of the discovery. Their development teams automatically received instructions on how to remediate the risk.
If you're not a Sonatype customer and want to find out if your code is vulnerable, you can use Sonatype's free Nexus Vulnerability Scanner to quickly find out.
Visit the Nexus Intelligence Insights page for a deep dive into other vulnerabilities like this one or subscribe to automatically receive Nexus Intelligence Insights hot off the press.