CVE-2020-0688 or how key reuse led to remote code execution on Exchange servers
Recently, Microsoft published an advisory for a vulnerability in Exchange Server that was fixed as part of the February 2020 Patch Tuesday. Looking at the description we can guess what it is about:
A remote code execution vulnerability exists in Microsoft Exchange Server when the server fails to properly create unique keys at install time. Knowledge of the validation key allows an authenticated user with a mailbox to pass arbitrary objects to be deserialized by the web application, which runs as SYSTEM.
Since it involves deserialization and “unique” keys, my initial guess was that Exchange might be using a hardcoded validation (HMAC) key on default installations, and if that is indeed the case, it should be easy to escalate this issue into a full remote code execution attack.
A little bit of background
ViewState
is a parameter used by ASP.NET web applications to keep track of visited pages’ states. It is implemented client-side, meaning that the server will dump the page state into the ViewState
variable, and will send it back and forth to the client (normally as a hidden Form field). This way, when the user submits the page back, the server will be able to retrieve the ViewState
parameter and reconstruct the previous page state. In order to dump the page state (object tree) in a format that can be sent as an HTTP request parameter, ASP.NET will serialize the object tree and then base64 encode it.
An attacker that can tamper with this parameter would be able to inject arbitrary serialized payloads, that would be executed when the server deserializes the ViewState
parameter to reconstruct the page state. For this reason ASP.NET signs the ViewState
parameter using an HMAC with a secret key. With this mechanism, no attacker can tamper with the ViewState
without the server realizing it! Or well, at least if the HMAC secret is kept … secret. What would happen if all Exchange servers out there shared the same key? Exactly, any authenticated attacker will be able to manipulate the ViewState
parameter, re-sign it using the hardcoded secret key and craft a malicious ViewState
resulting in remote code execution when said ViewState
is deserialized.
Zero Day Initiative (ZDI) published an advisory about CVE-2020-0688 this week which confirmed my guess and gave us more details on it. I suggest you read this article if you want to know more about the details of this CVE and under which conditions it can be exploited.
Where have I put the keys?
ViewState
misuses and attacks go back a long way in time. I tried to summarize a part of this vulnerability class history at LocoMocoSec back in April 2018 (you can find the slides here). As explained in this presentation ViewState
has gone through many changes. From not being signed to using a Key Derivation Function (KDF) to generate per-request unique keys (read more here and here). As I explained at LocoMocoSec, that offered little additional protection since all the values used to derive the per-request unique keys could be guessed by an attacker. Being able to leak the MachineKeys
will eventually turn into remote code execution. Let’s review some of the ways these keys can be leaked:
- Leaking
web.config
through Local File Inclusion or XXE vulnerabilities.- e.g.: AfterLogic WebMail Pro ASP.NET 6.2.6 - Administrator Account Disclosure via XXE
- Leaking
web.config
through Padding Oracles.- e.g.: MS10-070 (CVE-2010-3332)
- Vulnerability in .NET Framework enabling information disclosure
- e.g.: MS15-041 (CVE-2010-1648)
- Yellow Screen of Death
- Leaking
web.config
in public repos. For example:
The last one that I mentioned in my LocoMocoSec presentation becomes very relevant in the context of the Exchange vulnerability:
- Hardcoded keys used by one-click installers
Protecting the keys to your kingdom
Developers can mitigate exfiltration of their application configuration by encrypting sections of the configuration files. Make sure to encrypt encryption and signing keys and to never reuse them across multiple installations.
Conclusions
Simple mistakes can lead to full infrastructure compromise. In this case, reusing an HMAC secret totally defeated its intended purpose and allowed message tampering which when mixed with serialized data turned into full blown remote code execution.