Submitted by Ryan Barnett 06/03/2009
- 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.