Library vulns
Functions for vulnerability management.
The vulnerabilities library may be used by scripts to report and store vulnerabilities in a common format.
Reported vulnerabilities information must be stored in tables.
Each vulnerability must have its own state:
NOT_VULN
: The program was confirmed to be not vulnerable.
LIKELY_VULN
: The program is likely to be vulnerable,
this can be the case when we do a simple version comparison. This
state should cover possible false positive situations.
VULN
: The program was confirmed to be vulnerable.
EXPLOIT
: The program was confirmed to be vulnerable and
was exploited successfully. The VULN
state will be
set automatically.
DoS
: The program was confirmed to be vulnerable to Denial
of Service attack. The VULN
state will be set
automatically.
To match different vulnerability states, like the VULN
and EXPLOIT
states or the VULN
and
DoS
states, one can use the bitwise operations.
Vulnerability table: --------------------
local vuln_table = { title = "BSD ftpd Single Byte Buffer Overflow", -- mandatory field state = vulns.STATE.EXPLOIT, -- mandatory field -- Of course we must confirm the exploitation, otherwise just mark -- it vulns.STATE.VULN if the vulnerability was confirmed. -- states: 'NOT_VULN', 'LIKELY_VULN', 'VULN', 'DoS' and 'EXPLOIT' -- The following fields are all optional IDS = { -- Table of IDs -- ID Type ID (must be a string) CVE = 'CVE-2001-0053', BID = '2124', }, risk_factor = "High", -- 'High', 'Medium' or 'Low' scores = { -- A map of the different scores CVSS = "10.0", CVSSv2 = "...", }, description = [[ One-byte buffer overflow in BSD-based ftpd allows remote attackers to gain root privileges.]], dates = { disclosure = { year = 2000, month = 12, day = 18}, }, check_results = { -- A string or a list of strings -- This field can store the results of the vulnerability check. -- Did the server return anything ? some specialists can -- investigate this and decide if the program is vulnerable. }, exploit_results = { -- A string or a list of strings -- This field can store the results of the exploitation. }, extra_info = { -- A string or a list of strings -- This field can be used to store and shown any useful -- information about the vulnerability, server, etc. }, references = { -- List of references 'http://www.openbsd.org/advisories/ftpd_replydirname.txt', -- If some popular IDs like 'CVE' and 'OSVBD' are provided -- then their links will be automatically constructed. }, }
The following examples illustrates how to use the library.
Examples for portrule
and hostrule
scripts:
-- portrule and hostrule scripts must use the vulns.Report class -- to report vulnerabilities local vuln_table = { title = "BSD ftpd Single Byte Buffer Overflow", -- mandatory field references = { -- List of references 'http://www.openbsd.org/advisories/ftpd_replydirname.txt', }, ... } ... vuln_table.state = vulns.STATE.VULN local report = vulns.Report:new(SCRIPT_NAME, host, port) return report:make_output(vuln_table, ...)
local vuln_table = { title = "BSD ftpd Single Byte Buffer Overflow", -- mandatory field references = { -- List of references 'http://www.openbsd.org/advisories/ftpd_replydirname.txt', }, ... } ... vuln_table.state = vulns.STATE.VULN local report = vulns.Report:new(SCRIPT_NAME, host, port) report:add(vuln_table, ...) return report:make_output()
Examples for prerule
and postrule
scripts:
local FID -- my script FILTER ID prerule = function() FID = vulns.save_reports() if FID then return true end return false end postrule = function() if nmap.registry[SCRIPT_NAME] then FID = nmap.registry[SCRIPT_NAME].FID if vulns.get_ids(FID) then return true end end return false end prerule_action = function() nmap.registry[SCRIPT_NAME] = nmap.registry[SCRIPT_NAME] or {} nmap.registry[SCRIPT_NAME].FID = FID return nil end postrule_action = function() return vulns.make_output(FID) -- show all the vulnerabilities end local tactions = { prerule = prerule_action, postrule = postrule_action, } action = function(...) return tactions[SCRIPT_TYPE](...) end
Library debug messages:
- Level 2: show the
NOT VULNERABLE
entries. - Level 3: show all the vulnerabilities that are saved into the registry.
- Level 5: show all the other debug messages (useful for debugging).
Note: Vulnerability tables are always re-constructed before they are saved in the registry. We do this to avoid using vulnerability tables that are referenced by other objects to let the Lua garbage-collector collect these last objects.
Authors:
Copyright © Same as Nmap--See https://nmap.org/book/man-legal.html
Source: https://svn.nmap.org/nmap/nselib/vulns.lua
Script Arguments
- vulns.short
If set, vulnerabilities will be output in short format, a single line consisting of the host's target name or IP, the state, and either the CVE ID or the title of the vulnerability. Does not affect XML output.
- vulns.showall
If set, the library will show and report all the registered vulnerabilities which includes the
NOT VULNERABLE
ones. By default the library will only report theVULNERABLE
entries:VULNERABLE
,LIKELY VULNERABLE
,VULNERABLE (DoS)
andVULNERABLE (Exploitable)
. This argument affects the following functions: vulns.Report.make_output(): the default output function for portule/hostrule scripts. vulns.make_output(): the default output function for postrule scripts. vulns.format_vuln() and vulns.format_vuln_table() functions.
Functions
- add (script_name, ..., vulnerabilities)
Adds vulnerability tables into the vulnerability database (registry).
- add_ids (fid, ..., FILTER, IDs)
Add vulnerability IDs type to the vulnerability database associated with the
FILTER ID
.- add_popular_id (self, id_type, callback)
Registers and associates a callback function with the popular ID vulnerability type to construct and return popular links automatically.
- add_vulns (self, ..., vulnerabilities)
Adds vulnerability tables to the report.
- find (fid, selection_filter, FILTER, selection)
Search and return vulnerabilities in a list.
- find_by_id (fid, vuln_id_type, id, FILTER)
Search vulnerability entries by ID and return the results in a list.
- format_vuln (vuln_table, showall)
Format the vulnerability information and return it as a string.
- format_vuln_table (vuln_table, showall)
Format the vulnerability information and return it in a table.
- get_ids (fid, FILTER)
Gets the vulnerability database associated with the
FILTER ID
.- get_popular_link (id_type, id)
Calls the function associated with the popular ID vulnerability type to construct and to return the appropriate reference link.
- lookup_id (fid, vuln_id_type, id, FILTER)
Lookup for a vulnerability entry in the vulnerability database associated with the
FILTER ID
.- make_output (self, ..., vulnerabilities)
Report vulnerabilities.
- make_output (self, ..., vulnerabilities)
Report vulnerabilities.
- new (self, script_name, host, port)
Creates a new Report object
- register_popular_id (id_type, callback)
Registers and associates a callback function with the popular ID vulnerability type to construct and return popular links automatically.
- save_reports (filter_callback)
Initializes the vulnerability database and instructs the library to save all the vulnerability tables reported by scripts into this database (registry).
Functions
- add (script_name, ..., vulnerabilities)
-
Adds vulnerability tables into the vulnerability database (registry).
This function takes a variable number of vulnerability tables and stores them in the vulnerability database if they satisfy the callback filters that were registered by the
vulns.save_reports()
function.Scripts must call
vulns.save_reports()
function first to setup the vulnerability database.Parameters
- script_name
- The script name. The
SCRIPT_NAME
environment variable will do the job. - ...
- vulnerabilities
- A variable number of vulnerability tables.
Usage:
local vuln_table = { title = "Vulnerability X", state = vulns.STATE.VULN, ..., -- take a look at the vulnerability table example at the beginning. } local status, ret = vulns.add(SCRIPT_NAME, vuln_table)
Return values:
- True if the vulnerability tables were added, otherwise False.
- Number of added vulnerabilities on success.
- add_ids (fid, ..., FILTER, IDs)
-
Add vulnerability IDs type to the vulnerability database associated with the
FILTER ID
.This function will create a table for each specified vulnerability ID into the vulnerability database to store the associated vulnerability entries.
This function takes a
FILTER ID
as it is returned by thevulns.save_reports()
function and a variable number of vulnerability IDs type as parameters.Scripts must call
vulns.save_reports()
function first to setup the vulnerability database.Parameters
- fid
- ...
- FILTER
- ID as it is returned by
vulns.save_reports()
- IDs
- A variable number of strings that represent the vulnerability IDs type.
Usage:
vulns.add_ids(fid, 'CVE', 'OSVDB')
- add_popular_id (self, id_type, callback)
-
Registers and associates a callback function with the popular ID vulnerability type to construct and return popular links automatically.
The callback function takes a vulnerability ID as a parameter and must return a link. The library automatically supports three different popular IDs:
CVE
: cve.mitre.orgOSVDB
: osvdb.orgBID
: www.securityfocus.com/bidParameters
- self
- id_type
- String representing the vulnerability ID type.
'CVE'
,'OSVDB'
... - callback
- A function to construct and return links.
Usage:
function get_example_link(id) return string.format("%s%s", "http://example.com/example?name=", id) end report:add_popular_id('EXM-ID', get_example_link)
Return value:
True on success or false if it can not register the callback. - add_vulns (self, ..., vulnerabilities)
-
Adds vulnerability tables to the report.
Takes a variable number of vulnerability tables and stores them in the internal db of the report so they can be reported later.
Parameters
- self
- ...
- vulnerabilities
- A variable number of vulnerability tables.
Usage:
local vuln_table = { title = "Vulnerability X", state = vulns.STATE.VULN, ..., -- take a look at the vulnerability table example at the beginning. } local status, ret = report:add_vulns(vuln_table)
Return values:
- True if the vulnerability tables were added, otherwise False.
- Number of added vulnerabilities on success.
- find (fid, selection_filter, FILTER, selection)
-
Search and return vulnerabilities in a list.
This function will return a list of the vulnerabilities that were stored in the vulnerability database associated with the
FILTER ID
that satisfy theselection filter
. It will take aFILTER ID
as it is returned by thevulns.save_reports
function and aselection_filter
table as parameters.Scripts must call
vulns.save_reports()
function first to setup the vulnerability database.This function is not affected by the
vulns.showall
script argument. Theselection_filter
is an optional table parameter of optional fields which can be used to select which vulnerabilities to return, if it is not set then all vulnerability entries will be returned.Parameters
- fid
- selection_filter
- FILTER
- ID as it is returned by
vulns.save_reports()
- selection
- An optional table to select which vulnerabilities to
list. The fields of the selection filter table are:
state: The vulnerability state.
risk_factor: The vulnerability
risk_factor
field, can be one of these values:"High"
,"Medium"
or"Low"
. hosts_filter: A function to filter thehost
table of the vulnerability table. This function must return a boolean, true if it passes the filter otherwise false. Thehost
table: host = {ip, targetname, bin_ip} ports_filter: A function to filter theport
table of the vulnerability table. This function must return a boolean, true if it passes the filter, otherwise false. Theport
table: port = {number, protocol, service, version} id_type: The vulnerability ID type, (e.g: 'CVE', 'OSVDB' ...) id: The vulnerability ID. All these fields are optional.
Usage:
-- All the following fields are optional. local selection_filter = { state = vulns.STATE.VULN, -- number risk_factor = "High", -- string hosts_filter = function(vuln_table.host) -- Function that returns a boolean -- True if it passes the filter, otherwise false. end, -- vuln_table.host = {ip, targetname, bin_ip} ports_filter = function(vuln_table.port) -- Function that returns a boolean -- True if it passes the filter, otherwise false. end, -- vuln_table.port = {number, protocol, service -- version} id_type = 'CVE', -- Vulnerability type ID (string) id = 'CVE-XXXX-XXXX', -- CVE id (string) } local list = vulns.find(fid, selection_filter)
Return value:
List of vulnerability tables on success, or nil on failures. - find_by_id (fid, vuln_id_type, id, FILTER)
-
Search vulnerability entries by ID and return the results in a list.
This function will return a list of the same vulnerability that affects different hosts, each host will have its own vulnerability table.
Scripts must call
vulns.save_reports()
function first to setup the vulnerability database.Parameters
- fid
- vuln_id_type
- A string representing the vulnerability ID type.
- id
- The vulnerability ID.
- FILTER
- ID as it is returned by
vulns.save_reports()
Usage:
local list = vulns.find_by_id(fid, 'CVE', 'CVE-XXXX-XXXX')
Return value:
List of vulnerability tables on success, or nil on failures. - format_vuln (vuln_table, showall)
-
Format the vulnerability information and return it as a string.
This function can return nil if the vulnerability mandatory fields are missing or if the script argument
vulns.showall
and the'showall'
string parameter were not set and the state of the vulnerability isNOT VULNERABLE
.Script writers must check the returned result.
If the vulnerability table contains the
host
andport
tables, then the following fields will be shown:vuln_table.host.targetname
,vuln_table.host.ip
,vuln_table.port.number
andvuln_table.port.service
Parameters
- vuln_table
- The vulnerability information table.
- showall
- A string if set then show all the vulnerabilities
including the
NOT VULNERABLE
ones. This optional parameter can be used to overwrite thevulns.showall
script argument value.
Usage:
local vuln_str = vulns.format_vuln(vuln_table, 'showall') if vuln_str then return vuln_str end
Return value:
Multiline string on success. If one of the mandatory vulnerability fields is missing or if the script argumentvulns.showall
and the'showall'
string parameter were not specified and the vulnerability state isNOT VULNERABLE
then it will print a debug message about the vulnerability and return nil. - format_vuln_table (vuln_table, showall)
-
Format the vulnerability information and return it in a table.
This function can return nil if the vulnerability mandatory fields are missing or if the script argument
vulns.showall
and the'showall'
string parameter were not set and the state of the vulnerability isNOT VULNERABLE
.Script writers must check the returned result.
If the vulnerability table contains the
host
andport
tables, then the following fields will be shown:vuln_table.host.targetname
,vuln_table.host.ip
,vuln_table.port.number
andvuln_table.port.service
Parameters
- vuln_table
- The vulnerability information table.
- showall
- A string if set then show all the vulnerabilities
including the
NOT VULNERABLE
ones. This optional parameter can be used to overwrite thevulns.showall
script argument value.
Usage:
local vuln_output = vulns.format_vuln_table(vuln_table) if vuln_output then -- process the vuln_output table end
Return value:
Multiline string on success. If one of the mandatory vulnerability fields is missing or if the script argumentvulns.showall
and the'showall'
string parameter were not specified and the vulnerability state isNOT VULNERABLE
then it will print a debug message about the vulnerability and return nil. - get_ids (fid, FILTER)
-
Gets the vulnerability database associated with the
FILTER ID
.This function can be used to check if there are vulnerability entries that were saved in the vulnerability database. The format of the vulnerability database associated with the
FILTER ID
is specified as Lua comments in this library.Scripts must call
vulns.save_reports()
function first to setup the vulnerability database.Parameters
- fid
- FILTER
- ID as it is returned by
vulns.save_reports()
Usage:
local vulndb = vulns.get_ids(fid) if vulndb then -- process vulnerability entries end
Return value:
vulndb The internal vulnerability database associated with theFILTER ID
if there are vulnerability entries that were saved, otherwise nil. - get_popular_link (id_type, id)
-
Calls the function associated with the popular ID vulnerability type to construct and to return the appropriate reference link.
The library automatically supports three different popular IDs:
CVE
: cve.mitre.orgOSVDB
: osvdb.orgBID
: www.securityfocus.com/bidParameters
- id_type
- String representing the vulnerability ID type.
'CVE'
,'OSVDB'
... - id
- String representing the vulnerability ID.
Usage:
local link = vulns.get_popular_link('CVE', 'CVE-2001-0053')
Return value:
URI The URI on success or nil if the library does not support the specifiedid_type
, and in this case you can register new ID types by callingvulns.register_popular_id()
. - lookup_id (fid, vuln_id_type, id, FILTER)
-
Lookup for a vulnerability entry in the vulnerability database associated with the
FILTER ID
.This function can be used to see if there are any references to the specified vulnerability in the database, it will return
True
if so which means that one of the scripts has attempted to check this vulnerability.Scripts must call
vulns.save_reports()
function first to setup the vulnerability database.Parameters
- fid
- vuln_id_type
- A string representing the vulnerability ID type.
- id
- The vulnerability ID.
- FILTER
- ID as it is returned by
vulns.save_reports()
Usage:
local status = vulns.lookup(fid, 'CVE', 'CVE-XXXX-XXXX')
Return value:
True if there are references to this entry in the vulnerability database, otherwise False. - make_output (self, ..., vulnerabilities)
-
Report vulnerabilities.
Takes a variable number of vulnerability tables and stores them in the internal db of the report, then format all the vulnerabilities that are in this db for user display. Scripts should use this function as a tail call.
To show the
NOT VULNERABLE
entries users must specify thevulns.showall
script argument.Parameters
- self
- ...
- vulnerabilities
- A variable number of vulnerability tables.
Usage:
local vuln_table = { title = "Vulnerability X", state = vulns.STATE.VULN, ..., -- take a look at the vulnerability table example at the beginning. } return report:make_output(vuln_table)
Return value:
multiline string on success, or nil on failures. - make_output (self, ..., vulnerabilities)
-
Report vulnerabilities.
Takes a variable number of vulnerability tables and stores them in the internal db of the report, then format all the vulnerabilities that are in this db for user display. Scripts should use this function as a tail call.
To show the
NOT VULNERABLE
entries users must specify thevulns.showall
script argument.Parameters
- self
- ...
- vulnerabilities
- A variable number of vulnerability tables.
Usage:
local vuln_table = { title = "Vulnerability X", state = vulns.STATE.VULN, ..., -- take a look at the vulnerability table example at the beginning. } return report:make_output(vuln_table)
Return value:
multiline string on success, or nil on failures. - new (self, script_name, host, port)
-
Creates a new Report object
Parameters
- self
- script_name
- host
- port
Return value:
report object - register_popular_id (id_type, callback)
-
Registers and associates a callback function with the popular ID vulnerability type to construct and return popular links automatically.
The callback function takes a vulnerability ID as a parameter and must return a link. The library automatically supports three different popular IDs:
CVE
: cve.mitre.orgOSVDB
: osvdb.orgBID
: www.securityfocus.com/bidParameters
- id_type
- String representing the vulnerability ID type.
'CVE'
,'OSVDB'
... - callback
- A function to construct and return links.
Usage:
function get_example_link(id) return string.format("%s%s", "http://example.com/example?name=", id) end vulns.register_popular_id('EXM-ID', get_example_link)
Return value:
True on success or false if it can not register the callback. - save_reports (filter_callback)
-
Initializes the vulnerability database and instructs the library to save all the vulnerability tables reported by scripts into this database (registry).
Usually this function should be called during a
prerule
function so it can instructs the library to save vulnerability entries that will be reported by thevulns.Report
class or by thevulns.add()
function.This function can take an optional callback filter parameter that can help the library to decide if it should store the vulnerability table in the registry or not. The callback function must return a boolean value. If this parameter is not set then all vulnerability tables will be saved. This function will return a uniq
FILTER ID
for the scripts to be used by the other library functions to reference the appropriate vulnerability entries that were saved previously.Parameters
- filter_callback
- The callback function to filter vulnerabilities. The function will receive a vulnerability table as a parameter in order to inspect it, and must return a boolean value. True if the the vulnerability table should be saved in the registry, otherwise false. This parameter is optional.
Usage:
FID = vulns.save_reports() -- save all vulnerability reports. -- Save only vulnerabilities with the <code>VULNERABLE</code> state. local function save_only_vuln(vuln_table) if (vuln_table.state & vulns.STATE.VULN) ~= 0 then return true end return false end FID = vulns.save_reports(save_only_vuln)
Return value:
Filter ID A uniq ID to be used by the other library functions to reference and identify the appropriate vulnerabilities.