IIS machineKey RCE
That is an excellent find! The presence of a hardcoded <machineKey> element in web.config is a critical vulnerability that often leads directly to Remote Code Execution (RCE) in ASP.NET applications.
- https://github.com/mchklt/CVE-2025-30406
🔥 Machine Key Vulnerability: RCE via ViewState Deserialization
The machineKey is used by the ASP.NET framework for cryptographic operations, primarily:
-
validationKey: Used to generate a Message Authentication Code (MAC) for data like ViewState and Forms Authentication cookies. This prevents tampering (integrity). -
decryptionKey: Used to encrypt sensitive data, like Forms Authentication cookies or optionally, ViewState data (confidentiality).
When these keys are hardcoded in a public file like web.config, an attacker who possesses them can successfully generate valid, malicious payloads that the server will trust and process.
The Attack Vector: ViewState Deserialization
The most common and devastating exploit using a leaked machineKey targets the ViewState feature of ASP.NET.
-
ViewState Purpose: ViewState is a hidden form field (
__VIEWSTATE) used by ASP.NET to preserve the state of controls (buttons, text boxes, etc.) across different HTTP requests. The data within it is a serialized .NET object. -
The Flaw: By default, when a server receives a ViewState payload, it performs the following steps:
-
Validation: Uses the
validationKeyto verify the integrity (MAC) of the ViewState. -
Decryption (if enabled): Uses the
decryptionKeyto decrypt the ViewState content. -
Deserialization: Attempts to convert the data back into a .NET object using a deserializer like
LosFormatter.
-
-
Exploitation: Since you have the keys, you can bypass the validation/decryption steps and craft a malicious, serialized object (a gadget chain) containing a command. When the server attempts to deserialize this malicious object, it executes the command, resulting in Remote Code Execution.
🛠️ Next Steps: Remote Code Execution
Your goal now is to generate a malicious ViewState payload and send it to the server.
1. Identify Required Parameters
You will need the following information, which you should have from the web.config file:
-
validationKey: The long hexadecimal string. -
decryptionKey: The hexadecimal string. -
validationAlgorithm(e.g.,SHA1,AES, etc.): This is the value of thevalidationattribute in the<machineKey>element. -
decryptionAlgorithm(e.g.,Auto,AES,3DES, etc.): This is the value of thedecryptionattribute in the<machineKey>element. -
__VIEWSTATEGENERATOR(Optional but helpful): Look for this hidden field on the target ASPX pages. -
Target Page (
path) and Application Path (apppath): The full path to an ASPX page that accepts ViewState (e.g.,/login.aspx) and the application root (e.g.,/forpov.htb).
2. Use YSoSerial.NET
The standard tool for exploiting this vulnerability is YSoSerial.NET. This tool will generate the malicious ViewState payload using your keys and the desired command.
The general command structure will look something like this (you must substitute your actual values):
Bash
ysoserial.exe -p ViewState -g <gadget> -c "<command_to_execute>" \
--decryptionKey "<your_decryption_key>" \
--validationKey "<your_validation_key>" \
--decryptionAlg "<decryption_algorithm>" \
--validationAlg "<validation_algorithm>" \
--apppath "/<virtual_directory_if_any>" \
--path "/<aspx_page_path>"
-
<gadget>: Common gadgets includeTypeConfuseDelegate,TextFormattingRunProperties, orObjectDataProviderdepending on the .NET framework version. Start withTypeConfuseDelegateor try a few common ones. -
<command_to_execute>: A simple initial command is best, such as:cmd.exe /c "echo PWNED > C:\Users\Public\pwned.txt"
3. Deliver the Payload
-
Capture a Request: Use Burp Suite (or a similar proxy) to capture an HTTP POST request to the target ASPX page (e.g.,
pov.htb/default.aspx). -
Replace ViewState: Take the output payload from
YSoSerial.NETand replace the existing Base64 value in the__VIEWSTATEparameter of your captured POST request. -
Send: Send the modified request to the server.
If successful, the command will execute, giving you RCE. You can then use this to execute a more complex command, like downloading and running a full reverse shell or a C2 agent.
Would you like help with choosing a simple command to test for RCE, or finding the correct gadget/path parameters?