Exploiting __VIEWSTATE Knowing the Secret

If you don't know the keys yet, start with the sister page about recovering / guessing them. This page is for the case where you already have the validationKey (and sometimes the decryptionKey) and want to forge a valid malicious __VIEWSTATE.

When is the secret enough?

In practice, “knowing the secret” usually means you obtained the values from a leaked web.config, machine.config, registry/host access, another node in the same web farm, or from a publicly disclosed / hardcoded machineKey.

The minimum material you need depends on the framework mode:

  • .NET < 4.5:
  • If encryption is not enforced, the validationKey and validation algorithm are enough.
  • Even if ViewStateEncryptionMode="Always" is configured, older versions still accept an unencrypted ViewState if __VIEWSTATEENCRYPTED is removed from the request.
  • .NET >= 4.5 / compatibilityMode="Framework45":
  • You usually need both the validationKey and the decryptionKey, plus their algorithms.
  • The payload also depends on the target page path and application path.

Quick triage checklist

Before generating the payload, collect:

  • __VIEWSTATE
  • __VIEWSTATEGENERATOR if present
  • Target page path (for example /dir/app/page.aspx)
  • IIS application path / virtual root (for example /app/)
  • Validation algorithm + validationKey
  • Decryption algorithm + decryptionKey if the target uses modern ViewState protection
  • ViewStateUserKey if the application salts ViewState per user / session

If you only know the keys but not the exact gadget to use, check the nearby .NET gadget page.

Forging the payload with ysoserial.net

Legacy targets (.NET 4.0 and below)

When the target uses the legacy signing logic, ysoserial.net can use either:

  • --generator=<__VIEWSTATEGENERATOR> if the page exposes that value, or
  • --path + --apppath if you know the IIS application root.

Example using the exposed generator value:

ysoserial.exe -p ViewState -g TypeConfuseDelegate \
  -c "cmd /c whoami" \
  --generator=CA0B0334 \
  --islegacy \
  --validationalg="SHA1" \
  --validationkey="<VALIDATION_KEY>"

If the page is configured with ViewStateEncryptionMode="Always" but runs on .NET < 4.5, remove __VIEWSTATEENCRYPTED from the request and send an unencrypted but correctly signed payload.

Modern targets (.NET 4.5 and above)

Modern ViewState derivation uses the target page path and application path when deriving the protection material, so you normally need both:

ysoserial.exe -p ViewState -g TextFormattingRunProperties \
  -c "cmd /c whoami" \
  --path="/content/default.aspx" \
  --apppath="/" \
  --validationalg="HMACSHA256" \
  --validationkey="<VALIDATION_KEY>" \
  --decryptionalg="AES" \
  --decryptionkey="<DECRYPTION_KEY>"

If the payload fails and you suspect the path or app path is wrong, retry with --isdebug. The plugin prints the derived values and helps validate whether your guess matches the target's __VIEWSTATEGENERATOR / path logic.

Recent ysoserial.net builds also expose --minify, which is handy when you need to keep the forged payload short enough for WAF, proxy, or URL-length constraints.

Common gotchas

__VIEWSTATEGENERATOR is helpful, but mostly for legacy targets

ysoserial.net's ViewState plugin explicitly treats --generator as a legacy shortcut. For .NET 4.5+ you should expect to need the real --path and --apppath values.

ViewStateUserKey will break otherwise valid payloads

If the application binds ViewState to a user, session, or anti-CSRF token, you must include the same value when generating the payload:

ysoserial.exe -p ViewState -g TextFormattingRunProperties \
  -c "cmd /c whoami" \
  --path="/content/default.aspx" \
  --apppath="/" \
  --validationalg="HMACSHA256" \
  --validationkey="<VALIDATION_KEY>" \
  --decryptionalg="AES" \
  --decryptionkey="<DECRYPTION_KEY>" \
  --viewstateuserkey="<KNOWN_OR_GUESSED_VSUK>"

GET requests can also work

Although POST is the common delivery path, some applications also parse __VIEWSTATE from a GET request. This is useful when trying to stay close to the application's normal traffic or when replaying a payload through a URL-based gadget delivery point.

__EVENTVALIDATION can be abused with the same secrets

The same signing material can also become useful against __EVENTVALIDATION, but exploitation is more constrained than normal ViewState abuse: you need a POST request, a page that actually processes input, and a valid control/input name.

Why this still matters in 2025

This workflow is still very relevant because attackers increasingly do not need an additional bug once the keys are known:

  • Microsoft reported in February 2025 that threat actors were abusing publicly disclosed ASP.NET machine keys to generate valid malicious ViewState blobs.
  • 2025 real-world cases such as hardcoded machineKey values in vendor products turned “knowing the secret” into a practical internet-scale exploitation path.
  • In shared IIS / SharePoint farms, one recovered key pair can often be replayed laterally against sibling applications that trust the same configuration.

So, once you recover a single valid key pair, immediately test:

  • Other virtual directories on the same host
  • Sibling nodes behind the load balancer
  • Admin-only pages that expose richer gadget surfaces
  • Alternate state parameters such as __EVENTVALIDATION

References