From d6015faec51ca30183484eb39ea5e7cc6b12833c Mon Sep 17 00:00:00 2001 From: kroosec Date: Wed, 20 Jun 2012 20:04:08 +0000 Subject: [PATCH] Added intensive mode and Naxsi fingerprints to http-waf-fingerprint. --- scripts/http-waf-fingerprint.nse | 87 ++++++++++++++++++++++++++++---- 1 file changed, 78 insertions(+), 9 deletions(-) diff --git a/scripts/http-waf-fingerprint.nse b/scripts/http-waf-fingerprint.nse index fb0a392fe..2c6bb7d0b 100644 --- a/scripts/http-waf-fingerprint.nse +++ b/scripts/http-waf-fingerprint.nse @@ -6,19 +6,25 @@ local table = require "table" local url = require "url" description = [[ -Tries to detect the presence of web application firewall and its type and version. +Tries to detect the presence of a web application firewall and its type and +version. -This works by sending a number of requests and looking in the responses for known behavior and fingerprints -such as Server header, cookies and headers values. +This works by sending a number of requests and looking in the responses for +known behavior and fingerprints such as Server header, cookies and headers +values. Intensive mode works by sending additional WAF specific requests to +detect certain behaviour. -Credit to wafw00f and w3af for some fingerprints. +Credit to wafw00f and w3af for some fingerprints. ]] --- -- @args http-waf-fingerprint.root The base path. Defaults to /. +-- @args http-waf-fingerprint.intensive If set, will add WAF specific scans, +-- which takes more time. Off by default. -- -- @usage -- nmap --script=http-waf-fingerprint +-- nmap --script=http-waf-fingerprint --script-args http-waf-fingerprint.intensive=1 -- --@output --PORT STATE SERVICE REASON @@ -35,12 +41,16 @@ categories = {"discovery", "intrusive"} -- Version 0.1: -- - Initial version based on work done with wafw00f and w3af. -- - Removed many false positives. --- - Added fingeprints for WAFs such as Incapsula WAF, Cloudflare, USP-SES ,Cisco ACE XML Gateway and ModSecurity. --- - Added fingerprints and version detection for Webknight and BinarySec, Citrix Netscaler and ModSecurity +-- - Added fingeprints for WAFs such as Incapsula WAF, Cloudflare, USP-SES, +-- Cisco ACE XML Gateway and ModSecurity. +-- - Added fingerprints and version detection for Webknight and BinarySec, +-- Citrix Netscaler and ModSecurity -- +-- Version 0.2: +-- - Added intensive mode. +-- - Added fingerprints for Naxsi waf in intensive mode. -- -- TODO: Fingerprints for other WAFs --- Add intensive mode (WAF specific requests) -- portrule = shortport.service("http") @@ -87,6 +97,8 @@ bigip = { end end end, + intensive = function(host, port, root, responses) + end, } local webknight @@ -109,6 +121,8 @@ webknight = { end end end, + intensive = function(host, port, root, responses) + end, } local isaserver @@ -133,6 +147,8 @@ isaserver = { end end end, + intensive = function(host, port, root, responses) + end, } local airlock @@ -160,6 +176,8 @@ airlock = { end end end, + intensive = function(host, port, root, responses) + end, } local barracuda @@ -179,6 +197,8 @@ barracuda = { end end end, + intensive = function(host, port, root, responses) + end, } local denyall @@ -199,6 +219,8 @@ denyall = { end end end, + intensive = function(host, port, root, responses) + end, } local f5trafficshield @@ -226,6 +248,8 @@ f5trafficshield = { end end end, + intensive = function(host, port, root, responses) + end, } local teros @@ -245,6 +269,8 @@ teros = { end end end, + intensive = function(host, port, root, responses) + end, } local binarysec @@ -267,6 +293,8 @@ binarysec = { end end end, + intensive = function(host, port, root, responses) + end, } local profense @@ -291,6 +319,8 @@ profense = { end end end, + intensive = function(host, port, root, responses) + end, } local netscaler @@ -331,6 +361,8 @@ netscaler = { end end end, + intensive = function(host, port, root, responses) + end, } local dotdefender @@ -348,6 +380,8 @@ dotdefender = { end end end, + intensive = function(host, port, root, responses) + end, } local ibmdatapower @@ -365,6 +399,8 @@ ibmdatapower = { end end end, + intensive = function(host, port, root, responses) + end, } local cloudflare @@ -389,6 +425,8 @@ cloudflare = { end end end, + intensive = function(host, port, root, responses) + end, } local incapsula @@ -408,6 +446,8 @@ incapsula = { end end end, + intensive = function(host, port, root, responses) + end, } local uspses @@ -425,6 +465,8 @@ uspses = { end end end, + intensive = function(host, port, root, responses) + end, } local ciscoacexml @@ -442,6 +484,8 @@ ciscoacexml = { end end end, + intensive = function(host, port, root, responses) + end, } @@ -477,6 +521,29 @@ modsecurity = { end end end, + intensive = function(host, port, root, responses) + end, +} + +local naxsi +naxsi = { + name = "Naxsi", + detected = false, + version = nil, + + match = function(responses) + end, + intensive = function(host, port, root, responses) + -- Credit to Henri Doreau + local response = http.get(host, port, root .. "?a=[") -- This shouldn't trigget the rules + local response2 = http.get(host, port, root .. "?a=[[[]]]][[[]") -- This should trigger the score based rules + + if response.status ~= response2.status then + stdnse.print_debug("%s Naxsi detected through intensive scan.", SCRIPT_NAME) + naxsi.detected = true + end + return + end, } @@ -502,6 +569,7 @@ local wafs = { uspses = uspses, ciscoacexml = ciscoacexml, modsecurity = modsecurity, + naxsi = naxsi, -- netcontinuum = netcontinuum, -- secureiis = secureiis, -- urlscan = urlscan, @@ -510,7 +578,6 @@ local wafs = { -- websecurity = websecurity, -- imperva = imperva, -- ibmwas = ibmwas, --- naxsi = naxsi, -- nevisProxy = nevisProxy, -- genericwaf = genericwaf, } @@ -582,7 +649,8 @@ end action = function(host, port) local root = stdnse.get_script_args(SCRIPT_NAME .. '.root') or "/" - local result = {"Detected firewalls", {}} + local intensive = stdnse.get_script_args(SCRIPT_NAME .. '.intensive') + local result = {"Detected WAF", {}} -- We send requests local responses = send_requests(host, port, root) @@ -594,6 +662,7 @@ action = function(host, port) -- the presence of any fingerprints. for _, waf in pairs(wafs) do waf.match(responses) + if intensive then waf.intensive(host, port, root, responses) end if waf.detected then if waf.version then table.insert(result[2], waf.name .. " version " .. waf.version)