Java versions 15, 16, 17, and 18 (and maybe some older versions) have a big problem, ECDSA signature verification is totally broken. The story is a prime example of the dangers of unintended consequences, the pitfall of rolling your own crypto, and why to build a test suite for important code. In Java 15, the ECDSA verification code was re-written, moving the code from C++ to a Java-native implementation. The new code misses an important check, that the initialization and proof values are both non-zero.
A refresher on ECDSA will likely help. The Elliptic Curve Digital Signature Algorithm is a asymmetric cryptography scheme, where a public-private keypair is used to encrypt or sign messages. Rather than using the using factorization of large numbers as the one-way function, ECDSA uses a vector bouncing around the inside of a special elliptic curve. A signature consists of two values, the random starting point
r, and the proof
s. Part of the ECDSA spec is that those can’t be zero, because the verification function includes multiplication by those values. Multiplication and division by zero has a tendency to short-circuit algorithms, and this one is no exception. A signature of
s=0 is always valid, no private key needed.
The Java code left out the sanity-check for zeroes in the signature, so any Java program using ECDSA signatures can be defeated with trivial fake credentials — all zeroes. The worst part of this flaw is that it’s a known problem, and included in published test cases like Wycheproof. This wasn’t a project I was familiar with, but it’s definitely on my cryptographic radar now.
NIST famously publishes test vectors for various cryptography algorithms — published plaintext, key, and ciphertext sets, useful for validating that your code correctly implements the given scheme. The problem with these is that they aren’t adversarial; NIST vectors use the algorithm properly. Wycheproof’s tests are all invalid uses, designed to find edge case bugs like this one. If you’re involved with a crypto implementation, definitely use published test vectors in a test suite, but include Wycheproof or something like it.
This flaw was announced on Tuesday, but was originally discovered back in November, about five months ago. As keenly observed on Twitter, that’s a long time for Oracle to add an
if statement to their Java code. There is already a scanner to help you audit your Java programs for exposure to the problem. The official fix was released in the April collection of critical updates.
Log4Shell Second-Order Consequences
We don’t often think about second-order consequences of big bugs like Log4shell, but the fact is that every bugfix is also a possible new vulnerability, and when the bug being fixed is widespread and serious, there’s more likely to be follow-on bugs. The unlucky winners of this statistical lottery was Amazon, in this case. AWS added a hot-patch system to their Java infrastructure, and that system was vulnerable to container escape.
The hotpatch service scanned for any
java application running inside a container, and attempted to patch those processes if needed. Part of this process included running the container’s
java binary on the underlying host — without proper containerization, and running as root. It’s pretty trivial to replace the container’s
java binary with something malicious, trigger the hotpatch, and then take over the host when it runs the payload. Amazon has updated their code, but depending on what service you’re using, some manual steps may need to be taken.
Windows versions all the way back to Windows 7 have a glaring security problem in how Remote Procedure Calls are handled. What’s surprising is that this vulnerability isn’t accessed through the RPC port (135), but SMB (445), though an exploit at port 135 may still be found. CVE-2022-26809 is a pre-auth Remote Code Execution (RCE), scoring a CVSS of 9.8. Akamai has published an analysis of the patch, and it looks like an integer overflow could lead to a heap buffer overflow.
Stolen OAuth Tokens
In a developing story, GitHub has discovered that multiple private repositories have been checked-out using stolen OAuth tokens. It seems that the tokens were leaked from Heroku and Travis-CI. Both of those organizations are invalidating their tokens, and warning affected users. Travis CI has published a post, suggesting that tokens were accessed through a man-in-the-middle attack, but few concrete details have been released.
Watchguard Attacks in the Wild
CVE-2022-26318 was announced and fixed back in March with the very helpful “a vulnerability that could allow an unauthenticated user to execute arbitrary code on the Firebox.” As we know, an obscure vulnerability description isn’t enough to prevent a determined attacker from reverse-engineering a flaw; by the end of March, attacks were being observed in the wild. [Dylan Pindur] comes to our rescue in this post from Assetnote, which recaps the history of the bug, and does an analysis of the vulnerability. The whole dive is good stuff, but the short version is that a malformed XML document triggers too many calls to
strcat(), which overflows a buffer into the heap.
Bits and Bytes
Lenovo has released firmware updates for a wide swath of their laptop models, as researchers have discovered vulnerabilities in Lenovo’s UEFI firmware. The problems all seem to be due to manufacturing and debugging code that was unintentionally included in production firmware. The danger is that a sufficiently advanced piece of malware would no longer have to stop at just encrypting your data, it could install a module into the firmware, making for a very stubborn infection.
A VMware vulnerability, CVE-2022-22954, is being exploited in the wild. It’s described as “Server-side Template Injection Remote Code Execution”. The vulnerable component, the VMware Identity Manager is a component of other VMware products, so you may be running it unawares. It’s a CVSS 9.8, and appears to be exploitable pre-authentication.
And finally, Apache Struts 2.x has a recurring vulnerability: CVE-2020-17530 is back as CVE-2021-31805, as the initial fix proved to be insufficient. This flaw allowed OGNL code to be evaluated twice, which could lead to RCE. The bug was fixed again in version 2.5.30, released this month. Hopefully this fix catches all the corner cases.