As the new year begins, we thought it would be fun to look back at some of the best bugs submitted during 2021. We had another record-breaking year, with over 1,600 advisories published. In the end, we came up with the following submissions from 2021 that stood out from the pack. Without further ado and presented in no particular order, here are the Top 5 bug submissions for 2021.
Microsoft Exchange Server Remote Code Execution Vulnerability, a.k.a. ProxyShell
“ProxyShell” is the name given to a devastating vulnerability in Microsoft Exchange Server, discovered by Orange Tsai of DEVCORE Research Team and used in his successful entry at the 2021 Pwn2Own contest. This critical vulnerability in Exchange Server garnered a great deal of attention in 2021, and for good reason. Actually a chain of three security flaws (CVE-2021-34473, CVE-2021-34523, and CVE-2021-31207), ProxyShell allows an unauthenticated attacker to execute arbitrary code in the context of SYSTEM on an Exchange server. As this is a pre-authentication vulnerability, there is no need for the attacker to start with any credentials to an Exchange account at the target organization. The chain does assume that the attacker knows or can guess a valid email address on the server, but this is a low bar indeed.
Compounding matters, it is frequently possible to conduct a ProxyShell attack from anywhere on the Internet, and not just from within the target organization’s network. The only requirement is that the attacker must be able to access the /autodiscover/autodiscover.json
endpoint on the Exchange web server. Typical deployments make this endpoint available to the Internet.
Orange Tsai has graciously provided a wonderful write-up detailing his finding in a guest blog on the Zero Day Initiative website. His research into these and other Exchange vulnerabilities was also the subject of his 2021 presentations at Black Hat USA and DEF CON.
2021 has seen a major uptick in researcher interest in Microsoft Exchange Server as a target. This is definitely an area to watch in the future.
Microsoft SharePoint InfoPath List Deserialization of Untrusted Data Remote Code Execution Vulnerability
Besides Exchange Server, Microsoft SharePoint Server has also been an attractive target for vulnerability research recently. The Zero Day Initiative disclosed 10 SharePoint vulnerabilities in 2021. We’d like to highlight CVE-2021-27076, which was reported to us by an anonymous researcher. I was intrigued by the innovative method that this attack employs to expose a deserialization attack surface that normally is inaccessible. In short, the researcher discovered that by altering identifier values that are handled client-side within the browser, it is possible to cause an arbitrary upload to be fed into an incorrect context where it will be treated as trusted data. This lets any authenticated user (typically, any domain user) execute arbitrary code on the SharePoint server in the context of the web application. If you’re curious to learn more about this technique, I encourage you to read my full write-up, which can be found on the Zero Day Initiative website.
Microsoft Windows Lock Screen Improper Access Control Authentication Bypass Vulnerability
I love a good lock screen bypass, and CVE-2021-26431 by Abdelhamid Naceri (halov) doesn’t disappoint. This research builds upon a prior discovery by Jonas Lyk, who noted that that the Narrator feature can sometimes be used to navigate and interact with UI elements that are improperly launched from the lock screen, though hidden from view. Exploiting CVE-2021-26431 involves attempting to log in to a PC using a Microsoft account. After providing an incorrect PIN, it’s possible to arrive at a dialog containing a hyperlink. Clicking the hyperlink launches an “Open With” dialog. Though this dialog is normally hidden from view, Jonas Lyk’s Narrator technique can then be used to interact with it. See Abdelhamid Naceri’s blog and his YouTube videos here and here to watch how he uses this to completely bypass the lock screen or to get a remote shell.
Don’t try this at home, though. From what we can tell, Microsoft has implemented a server-side fix, so that the HTML containing the vulnerable hyperlink is no longer delivered even on PCs that lack up-to-date patches.
Linux Kernel eBPF Improper Input Validation Privilege Escalation Vulnerability
eBPF (Extended Berkeley Packet Filter) is a technology used for the high-performance classification of streams of data packets. A common use case is user-mode software that needs to select a subset of incoming network data packets. To send all packets from kernel mode to user mode for evaluation is generally too expensive. eBPF provides an alternative: User-mode code sends a filter algorithm in the form of an eBPF bytecode program, which the kernel will compile and execute in the context of the kernel to evaluate each packet. The inherent security risks to this arrangement are unmistakable, though: the kernel’s eBPF compiler must be able to determine that the resulting compiled program is 100% free of memory safety issues, or else the security of the kernel will swiftly be compromised. There is little room for error. Furthermore, the competing needs for extreme optimization and perfect execution safety make the eBPF compiler a likely source of critical kernel vulnerabilities.
The bug we’d like to highlight is CVE-2021-31440, reported to the Zero Day Initiative by Manfred Paul in April of 2021 and fixed in this commit to the Linux kernel. The flaw is in the reasoning used by the eBPF compiler when tracking the upper and lower bounds of the value of the 32-bit subregister of a 64-bit wide register. In other words, when constructing a proof of the program’s memory safety, the compiler keeps track of the maximum and minimum values held in the program’s registers. Given knowledge of the bounds of a 64-bit register, the compiler sometimes needs to derive what the upper and lower bounds will be when the program uses just the register’s lower 32 bits.
The flaw is illustrated as follows: If the 64-bit register has a lower bound that is within the range of values that can be represented in 32 bits, then the compiler would reason that the lower bound of the 32-bit subregister has the same lower bound. For example, if it is known that the 64-bit register has a lower bound of 1, then the compiler would record that the lower bound of the 32-bit subregister is also 1. This is a mistake, though. For example, the 64-bit register’s lower bound could be 1, but its value at runtime might be 0x100000000 (= 2^32). This value is greater than 1, so the lower bound holds true. But in this case, the 32-bit subregister contains a value of 0. This shows that it is not correct to conclude that the lower bound of the 32-bit subregister is also 1.
The correct calculation is as follows: If there is a 64-bit register and both its lower and upper bounds are within the range that can be represented in 32 bits, then both the lower and upper bounds can be applied to the 32-bit subregister as well. Otherwise, neither bound can be inferred.
Failures in bounds checking within eBPF are typically catastrophic to kernel security, and this bug is no exception. An attacker can use this to escalate privileges from a low-privileged user account to code execution in the kernel.
Apple Safari Integer Overflow Remote Code Execution Vulnerability
Returning to Pwn2Own 2021, we have this Safari RCE by Jack Dates of RET2 Systems, Inc. (@ret2systems). Addressed by Apple as CVE-2021-30734, the bug is in WebKit’s implementation of WebAssembly. At the contest, it was paired with an out-of-bounds write in a driver (CVE-2021-30735) to get kernel-mode remote code execution.
WebKit handles WebAssembly via several tiers of execution. The first tier involves translating the WebAssembly to a bytecode format known as LLInt (Low-Level Interpreter). Following this translation, there are two additional tiers of JIT compilation. However, this vulnerability is in the LLIntGenerator
tier, which is the conversion to LLInt bytecode.
As LLIntGenerator
makes its pass through the code, it keeps track of the stack space required at each point by incrementing and decrementing a field named m_stackSize
. Through the use of a clever combination of WebAssembly features, our Pwn2Own contestant succeeded in incrementing m_stackSize
to its maximum value of UINT_MAX
. After rounding, this produces in a stack allocation zero bytes in size. Reads and writes based at this zero-length allocation give the WebAssembly script read/write access to copious amounts of adjacent memory.
For a thorough write-up of the vulnerability and the techniques used in exploitation, see the researcher’s blog here.
Thanks for joining us as we recapped some of the best bugs submitted to the ZDI program this year. We appreciate all those who submitted to the program over this past year. We can’t do what we do without the input and work of our global community of independent researchers. The program has certainly changed and grown over the years, but our desire to work with independent security researchers from around the globe has never wavered. If you haven’t submitted to the program, we hope you consider doing so in the future.
Until then, you can follow the ZDI team on Twitter for the latest in exploit techniques and security patches.