Wednesday, June 3, 2009

WAF Detection with wafw00f

Submitted by Ryan Barnett 06/03/2009

Another interesting presentation that was given by Wendel Guglielmetti Henrique, Trustwave & Sandro Gauci, EnableSecurity at the recent OWASP AppSec EU conference was entitled The Truth about Web Application Firewalls: What the vendors don't want you to know.  The two main topics to the talk were WAF detection and evasion.

WAF Detection
The basic premise for this topic is that inline WAFs can be detected through stimulus/response testing scenarios.  Here is a short listing of possible detection methods:

  • Cookies - Some WAF products add their own cookie in the HTTP communication.
  • Server Cloaking - Altering URLs and Response Headers
  • Response Codes - Different error codes for hostile pages/parameters values
  • Drop Action - Sending a FIN/RST packet (technically could also be an IDS/IPS)
  • Pre Built-In Rules - Each WAF has different negative security signatures

The authors even created a tool called wafw00f to help automate these fingerprinting tasks.  The tool states that it is able to identify over 20 different WAFs (including ModSecurity) so I thought I would try it out against my own ModSecurity install to see how it works.  After reviewing the python source code and running a few tests, it is evident that in order for wafw00f to identify a ModSecurity installation, it is relying upon the Pre Built-In Rules category as mentioned above.  Specifically, if a ModSecurity installation is using the Core Rule Set and has the SecRuleEngine On directive set, then the OS command/file access attack payloads sent by wafw00f will trigger the corresponding rules and a 501 response status code will be returned.

Reliance upon the returned HTTP status code is not a strong indicator of the existence of a WAF as this can be easily changed.  Looking on the other end of the spectrum, and taking a defensive posture, this scenario reminds me somewhat of best practice steps for virtual patch creation.  One of the key tenants for creating these patches is that you don't want to key off of attributes in an attack payload that are superfluous.  The point being is that there are only a small set of key elements that are key to the success of the exploit.  These are the items that you want to focus on for a virtual patch.  If, however, you key off of non-essential data from some proof of concept code, your virtual patch can be easily evaded if the attack alters this data.  In this particular case with wafw00f, the HTTP response code generated by ModSecurity is customizable by the polices so the identification effectiveness is reduced to only "Default Configurations."  With ModSecurity, for instance, it is trivial to update the status action of the Core Rule Set to use some other status code.  This can be accomplished in a number of ways such as by using the block action in the rules or SecRuleUpdateActionById directive to change what status code is returned.

This is an interesting tool in that it aids with the pentesting/assessment steps of footprinting the target network.  The more details that you can identify about the target, the more finely tuned your attack strategy can be.  With this in mind, if you want to easily trick wafw00f, you could always update the SecServerSignature ModSecurity directive to spoof the server response header and impersonate another WAF product :)  Take a look at the wafw00f code for hints on what data to use.


Ajay Singh Negi said...

Original Posting can be found here:

Thanks a lot for posting.

A nice papper written on how to by pass Modsecurity in milw0rm by on of the Indian author Lavakumar Kuppan

Ryan Barnett said...

Thanks for the note Ajay. Yes, I have seen that paper. With regards to impedance mismatch, as described in the paper, it is difficult for a WAF to properly mimic every possible way that a back-end web application may interpret data. In this particular case, how ASP/ASP.NET handle multiple parameters with the same name. The best approach for ModSecurity is not to try and mimic the concatenation of the parameter data but to instead implement a rule to identify if multiple parameters are being passed that have the same name as this would usually be abnormal. We did discuss this issue on the ModSecurity users mail-list and I even posted a rule - This HTTP Parameter Pollution rule will be included in the upcoming Core Rule Set (CRS) v2.0.