EnableSecurity / wafw00f

WAFW00F allows one to identify and fingerprint Web Application Firewall (WAF) products protecting a website.
https://www.enablesecurity.com/
BSD 3-Clause "New" or "Revised" License
5.18k stars 926 forks source link

wafw00f does not detect Azion's WAF anymore #141

Closed pedro823 closed 2 years ago

pedro823 commented 3 years ago

Describe the bug wafw00f's AzionCDN detection code cannot detect any Azion WAFs. This is because they've changed their header settings, not sending Server: Azion anymore.

To Reproduce I've set up an Azion WAF on this test domain: robert.garrucho.com.br. To reproduce, just run wafw00f https://robert.garrucho.com.br and see that it doesn't detect the WAF.

image

Expected behavior Here's a code that does detect the WAF:

curl <HOST> -H 'pragma: azion-debug-cache' -o /dev/null -v 2>&1 | grep 'x-cache-location'

By sending pragma: azion-debug-cache as a header, Azion returns debug headers, one of which is the WAF ruleset.

image

Note that www.garrucho.com.br, a website that does not have a WAF set up, returns /.

image

P.S.

I can create a PR and fix this myself! But to do that, I need a little bit of context.

0xInfection commented 3 years ago

This Azion WAF looks weird. In your case a specific header needs to be sent in the request. However for a sample I found in the wild, it returned the same header in response that you're sending in the request.

$ curl https://www.████████████.com.br/ -sD - -o /dev/null
HTTP/2 200 
date: Mon, 13 Sep 2021 15:40:27 GMT
content-type: text/html
content-length: 184201
x-amz-id-2: 2VIN9/GF0NC3Z6ley37Gf85VPog5q7GPljMyKPKqP0tiI4VS0djLSwdrCxgUtahZuZ5EvZtvdF4=
x-amz-request-id: MVQFXD1XP8KEHY1R
last-modified: Mon, 13 Sep 2021 15:21:55 GMT
x-amz-version-id: null
etag: "66ffa3ecb9f5844391be4c32b2a46320"
server: AmazonS3
cache-control: public, max-age=120, s-maxage=604801
x-varnish: 78778159 66602919
age: 123
via: 1.1 varnish-v4
x-ua-device: desktop
x-host: ██████████.amazonaws.com
x-url: /home/correio/public_html/_conteudo/home/index.html
x-url-without-qs: /
access-control-allow-origin: *
access-control-allow-methods: GET, OPTIONS
access-control-allow-headers: Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token
x-cache2: HIT
pragma: azion-debug-cache
content-security-policy: upgrade-insecure-requests
x-xss-protection: 1; mode=block
x-content-type-options: nosniff
strict-transport-security: max-age=63072000;includeSubDomains;preload
accept-ranges: bytes

Notice that the Pragma: azion-debug-cache is returned in the response by default. Not sure whats up.

pedro823 commented 3 years ago

Wow, this is by far the weirdest response headers I've ever seen.

for once, server: AmazonS3 implies it's an S3 origin. However, it also has an x-varnish header, and AWS doesn't use (or at least, they don't say that they use) varnish proxies on S3. Azion uses nginx proxies.

also, Pragma: azion-debug-cache is a request header, not a response header. Azion does not return that pragma in any response.

My best guess of that setup is the routing Azion -> varnish -> S3, and that varnish is adding that Pragma response header, as someone didn't know how to configure it.

Just to be sure, does dig CNAME www.<hidden-domain>.com.br +short return something like *.ha.azioncdn.net. or *.map.azionedge.net?

0xInfection commented 3 years ago

It points to *.ha.azioncdn.net.

dig www.████████████.com.br CNAME +short
225659z.ha.azioncdn.net.

Does that make a difference anyhow? :)

0xInfection commented 3 years ago

Other variants of responses that I've seen include these headers:

Server: Azion Ipath Server
Server: Azion IMS
Server: azion webserver

I think the best we can do is include all these headers as checks in the response. We can craft an additional request for sure if needed, please take a look at customRequest() function in main.py#L47.

Let me know what do you think about this.

pedro823 commented 3 years ago

It points to *.ha.azioncdn.net.

dig www.████████████.com.br CNAME +short
225659z.ha.azioncdn.net.

Does that make a difference anyhow? :)

Well, if the domain wasn't even pointed to Azion, there would be no way for them to be using the Azion WAF, so just a sanity check 😅

These headers you've shown, by the way, do not necessarily mean that they're using a WAF, but it strongly points to whether they're using Azion as a CDN or not.

This customRequest() function seems sufficient for this case. I know we should avoid adding new custom requests because it significantly slows down the recognition and raises more red flags, so I'll see if there is any other way out.

0xInfection commented 2 years ago

Closing this issue as a edge-case for now, please feel free to reopen this issue if there are any new findings. Thanks! :)