Index: nselib/data/http-fingerprints.lua =================================================================== --- nselib/data/http-fingerprints.lua (revision 32563) +++ nselib/data/http-fingerprints.lua (working copy) @@ -12,6 +12,18 @@ -- 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 @@ -- 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 @@ } }, }); + +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 Index: scripts/http-enum.nse =================================================================== --- scripts/http-enum.nse (revision 32563) +++ scripts/http-enum.nse (working copy) @@ -13,6 +13,10 @@ 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.