diff --git a/nselib/data/http-fingerprints.lua b/nselib/data/http-fingerprints.lua index 756f28628..2e5ad5ce6 100644 --- a/nselib/data/http-fingerprints.lua +++ b/nselib/data/http-fingerprints.lua @@ -12,6 +12,18 @@ local table = require "table" -- This file is released under the Nmap license; see: -- http://nmap.org/book/man-legal.html -- +-- @args http-fingerprints.nikto-db-path Looks at the given path for nikto database. +-- It then converts the records in nikto's database into our Lua table format +-- and adds them to our current fingerprints if they don't exist already. +-- Unfortunately, our current implementation has some limitations: +-- * It doesn't support records with more than one 'dontmatch' patterns for +-- a probe. +-- * It doesn't support logical AND for the 'match' patterns. +-- * It doesn't support sending additional headers for a probe. +-- That means, if a nikto fingerprint needs one of the above features, it +-- won't be loaded. At the time of writing this, 6546 out of the 6573 Nikto +-- fingerprints are being loaded successfully. +-- -- Although this format was originally modeled after the Nikto format, that ended -- up being too restrictive. The current format is a simple Lua table. There are many -- advantages to this technique; it's powerful, we don't need to write custom parsing @@ -63,11 +75,11 @@ local table = require "table" -- The text to output if this match happens. If the 'match' field contains captures, these -- captures can be used with \1, \2, etc. -- --- -- If you have any questions, feel free to email dev@nmap.org or contact Ron Bowes! -- -- CHANGELOG: -- Added 120 new signatures taken from exploit-db.com archives from July 2009 to July 2011 [Paulino Calderon] +-- Added the option to read nikto's database and make use of its fingerprints. [George Chatzisofroniou] -- fingerprints = {}; @@ -11830,3 +11842,99 @@ table.insert(fingerprints, { } }, }); + +local stdnse = require "stdnse" +local nmap = require "nmap" + +nikto_db_path = stdnse.get_script_args("http-fingerprints.nikto-db-path") or "db_tests" +local f = nmap.fetchfile(nikto_db_path) or io.open(nikto_db_path, "r") + +if f then + + stdnse.print_debug(1, "Found nikto db.") + + local nikto_db = {} + for l in io.lines(nikto_db_path) do + + -- Skip comments. + if not string.match(l, "^#.*") then + + record = {} + + for field in string.gmatch(l, "\"(.-)\",") do + + -- Grab every attribute and create a record. + if field then + string.gsub(field, '%%', '%%%%') + table.insert(record, field) + end + end + + -- Make sure this record doesn't exists already. + local exists = false + for _, f in pairs(fingerprints) do + if f.probes then + for __, p in pairs(f.probes) do + if p.path then + if p.path == record[4] then + exists = true + break + end + end + end + end + end + + -- What we have right now, is the following record: + -- record[1]: Nikto test ID + -- record[2]: OSVDB-ID + -- record[3]: Server Type + -- record[4]: URI + -- record[5]: HTTP Method + -- record[6]: Match 1 + -- record[7]: Match 1 (Or) + -- record[8]: Match1 (And) + -- record[9]: Fail 1 + -- record[10]: Fail 2 + -- record[11]: Summary + -- record[12]: HTTP Data + -- record[13]: Headers + + -- Is this a valid record? Atm, with our current format we need + -- to skip some nikto records. See NSEDoc for more info. + + if not exists + and record[4] + and record[8] == "" and record[10] == "" and record[12] == "" + and (tonumber(record[4]) == nil or (tonumber(record[4]) and record[4] == "200")) then + + -- Our current format does not support HTTP code matching. + if record[6] == "200" then record[6] = "" end + + nikto_fingerprint = { category = "nikto", + probes = { + { + path = record[4], + method = record[5] + } + }, + matches = { + { + dontmatch = record[9], + match = record[6], + output = record[11] + }, + }, + } + + -- If there is a second match, add it. + if record[7] and record[7] ~= "" then + table.insert(nikto_fingerprint.matches, { match = record[7], output = record[11] }) + end + + table.insert(fingerprints, nikto_fingerprint) + + end + end + end +end diff --git a/scripts/http-enum.nse b/scripts/http-enum.nse index 972473dd7..f99ae407e 100644 --- a/scripts/http-enum.nse +++ b/scripts/http-enum.nse @@ -13,6 +13,10 @@ This parses a fingerprint file that's formatted in a way that's compatible with scanner. This script, however, takes it one step further by building in advanced pattern matching as well as having the ability to identify specific versions of Web applications. +You can, however, parse the nikto database using http-fingerprints.nikto-db-path. This will try to parse +most of the fingerprints defined in nikto's database in real time. More documentation about this in the +nselib/data/http-fingerprints file. + Currently, the database can be found under Nmap's directory in the nselib/data folder. The file is called http-fingerprints and has a long description of its functionality in the file header.