nbs-system / naxsi

NAXSI is an open-source, high performance, low rules maintenance WAF for NGINX
GNU General Public License v3.0
4.8k stars 606 forks source link

Rule for payload encoding using different charset #417

Closed notdodo closed 11 months ago

notdodo commented 6 years ago

Hi!

I was reading this slideshare and I wanted to try this kind of WAF bypass on NAXSI.

I state that I've used the default rules with this scores:

CheckRule "$SQL >= 3" BLOCK;
CheckRule "$RFI >= 2" BLOCK;
CheckRule "$TRAVERSAL >= 1" BLOCK;
CheckRule "$EVADE >= 1" BLOCK;
CheckRule "$XSS >= 2" BLOCK;

Using this payload http -v -f POST http://172.17.02/index.php Hello="input1='union all select * from users--" the request is correctly blocked but using a different charset (charset=ibm037) the request is not blocked:

http -v -f POST http://172.17.02/index.php Hello="%89%95%97%A4%A3%F1=%7D%A4%95%89%96%95%40%81%93%93%40%A2%85%93%85%83%A3%40%5C%40%86%99%96%94%40%A4%A2%85%99%A2%60%60" Content-Type:"application/x-www-form-urlencoded; charset=ibm037"

POST /index.php HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 199
Content-Type: application/x-www-form-urlencoded; charset=ibm037
Host: 172.17.02

Hello=%2589%2595%2597%25A4%25A3%25F1%3D%257D%25A4%2595%2589%2596%2595%2540%2581%2593%2593%2540%25A2%2585%2593%2585%2583%25A3%2540%255C%2540%2586%2599%2596%2594%2540%25A4%25A2%2585%2599%25A2%2560%2560

HTTP/1.1 200 OK
Connection: keep-alive
Content-Type: application/x-www-form-urlencoded; charset=ibm037
Date: Thu, 12 Apr 2018 10:10:24 GMT
Server: nginx
Transfer-Encoding: chunked
X-Powered-By: PHP/5.6.35

input1'union all select * from users--

Backend example:

header("Content-Type: " . $_SERVER["CONTENT_TYPE"]);
echo urldecode($_POST["Hello"]);

I know that this code sucks and it's totally not safe to use (is just an example).

My question: is there a way to instruct NAXSI to decode the payload using the charset given in the Content-Type header before performing the score evaluation and thus block the request?

buixor commented 6 years ago

Hello,

@edoz90 this one is a rather interesting one ! I guess the simplest way would be to create a rule to match on the Content-Type header to restrict to the ones that nginx can internally properly decode (naxsi relies on nginx's internal url-decoding functions).

In your usecase, php is hosted by the nginx server itself ?

Cheers,

notdodo commented 6 years ago

Hi!

Yes, NGINX is used to proxy the traffic to PHP. I esplicitly used fastcgi_param CONTENT_TYPE $content_type; to forward the header to PHP but it wasn't necessary.

This was just a ""PoC"" of the article that I read so I don't use that PHP code in production (and no one should).

I thought too to whitelist only encodings accepted by the backend but what if a user use a legit request for a non-whitelisted encoding beacuse che used that in his browser? I know that the request and payload should be always double checked on server-side but the article states that the application should be accessible from anyone and I didn't know NGINX url-decoded some encodings.

Sorry if I was not clear and thank you for your response.

jvoisin commented 6 years ago

I think that despite the fact that naxsi might block some legitimate requests with fancy encoding, this is the way to go™, because there is no other ones.

buixor commented 6 years ago

Hello, We are mering a branch with a test-case for your report. The automagic rule to drop this should be (drop every charset that is not utf-8) :

MainRule "rx:charset\s*=\s*(?!utf\-8)" "mz:$HEADERS_VAR:content-type" "s:DROP";

However, as charset/encoding is a never-ending joke that depends on the webserver you actually use, we don't think that including it in core-rules is a good idea. Thoughts ?

buixor commented 6 years ago

Shall we have an internal rule to explicitly drop all non-standard encodings ?

jvoisin commented 6 years ago

Since naxsi is used in countries that are likely using fancy encodings, I don't think that we should :D

qingweiqm commented 6 years ago

we know that attacker will try to encode the attack payload with URL encoding or base64 encoding and so on, how does the naxsi to deal with this kind of encode attack, I just try url encoding attack, and found it's working......

buixor commented 6 years ago

@qingweiqm : can you be a bit more explicit ? naxsi is url-decoding payloads where it makes sense (ie. url, form/url-encoded posts etc.), so it shouldn't

ghost commented 6 years ago

Isn't the application culprit for decoding blindly the user input using the user-supplied charset?!

I don't know of any application that does this but i could be wrong.

osevan commented 2 years ago

Any news about urldecoding attacks on naxsi?

wargio commented 2 years ago

definitely not implemented. Decoding charsets is difficult, and nowdays everybody should use utf-8, any other charset should be banned. This https://github.com/nbs-system/naxsi/issues/417#issuecomment-381628385 should fix the issue if you ever have one.

osevan commented 2 years ago

Thx