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.
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.
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:
web.configthrough Local File Inclusion or XXE vulnerabilities.
web.configthrough Padding Oracles.
web.configin public repos. For example:
The last one that I mentioned in my LocoMocoSec presentation becomes very relevant in the context of the Exchange vulnerability:
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.
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.