In the Exploiting Deserialisation in ASP.NET via ViewState blog post, I explained how it is possible to run code on an ASP.NET web application using compromised Machine Key secrets. It covers cases in which the keys are hard coded and could be read using another vulnerability such as local file disclosure. However, most websites do not hard code these keys and use automatically generated values by ASP.NET. As a result, it is not simply possible to steal the keys by reading the configuration files.

Now I want to explain how hackers who have already exploited an ASP.NET application can read the auto generated parameters to maintain their access even after their original vulnerability has been patched.

This can also be abused very similar to a hidden key or a backdoor by malicious developers to execute code on a server when they do not have their access anymore.

What do you do with a comprised box?

Assume this generic scenario: An outdated ASP.NET CMS on IIS has been hacked using a vulnerability that has been patched in the latest version of the software.

This is what we know:

The exploit and its patch are public

A web shell was dropped

No other file changes have been recorded

Database values have not been modified by the attacker

No fixed machine key is in the web.config file

This is what we have done after pulling the server offline:

The web server has been restored to its pre-attack condition: Web shell has been deleted

Database has been restored to its pre-attack condition Any potential data changes have been reversed

The CMS application has been updated Vulnerability has been patched

All the hardcoded secrets and credentials within the application files or the database have been changed

Users’ passwords and other sensitive tokens in the accessible databases have been reset

Can we go online now without risk of attackers coming back?

Although some people may say “NO” for other reasons, I like to say “NO” as the auto generated Machine Key might have been stolen! This can be enough for hackers to run code on the server whenever they want.

Reading the Generated Keys

Attackers should be able to calculate the validation and decryption keys by reading the following registry keys (depends on the .NET version):

HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\4.0.30319.0\AutoGenKeyV4 HKEY_CURRENT_USER\Software\Microsoft\ASP.NET\ 2.0.50727.0\AutoGenKey

These registry keys belong to the IIS user (Application Pool) that runs the application.

However, when attackers can run ASP.NET code on the website, it easier to extract the keys directly. It should be noted that used keys where ASP.NET Framework 4.5 has been targeted are different than the previous versions.

Auto generated keys can have two modes:

IsolateApps In this case, it uses the value of HttpRuntime.AppDomainAppVirtualPath (e.g. /dir/appname/ ) when transforming the auto-generated key to make the validation and decryption keys

IsolateByAppId In this case, it uses the value of HttpRuntime.AppDomainAppId (e.g. /LM/W3SVC/1/ROOT/dir/appname/ where ‘1’ is the AppId) when transforming the auto-generated key to make the validation and decryption keys. This is useful when two different applications use the same virtual path so their keys will be different.



Different ASP.NET pages within the same application uses the same set of transformed keys.

I have created a simple proof of concept code in the following GitHub gist in order to extract auto generated validation and decryption keys:

https://gist.github.com/irsdl/36e78f62b98f879ba36f72ce4fda73ab

After extracting the keys, attackers can run code on the website using the method explained in the Exploiting Deserialisation in ASP.NET via ViewState blog post.

Recommendation:

Create a new Application Pool for your ASP.NET application when you need to reset all the credentials for any reasons. This will ensure that a new ASP.NET key will be generated for the application.

References:

https://gyorgybalassy.wordpress.com/2013/12/07/how-unique-is-your-machine-key/

https://devblogs.microsoft.com/aspnet/cryptographic-improvements-in-asp-net-4-5-pt-1/

https://devblogs.microsoft.com/aspnet/cryptographic-improvements-in-asp-net-4-5-pt-2/