The Nmap Scripting Engine is perfect for detecting vulnerabilities, and for this reason there are already several exploitation scripts included with Nmap. Not too long ago, each developer used his own criteria of what output to include when reporting these vulnerabilities. To address this issue and unify the output format and the amount of information provided, the library vulns
was introduced.
This recipe will teach you how to report vulnerabilities correctly in your NSE scripts by using the library vulns
.
The correct way to report vulnerabilities in NSE is through the library vulns
. Let's review the process of reporting a vulnerability:
vulns
(Nmap 6.x format):local vulns = require "vulns"
vuln
object table. Pay special attention to the state
field:local vuln = { title = "<TITLE GOES HERE>", state = vulns.STATE.NOT_VULN, references = {"<URL1>", "URL2"}, description = [[<DESCRIPTION GOES HERE> ]], IDS = {CVE = "<CVE ID>", BID = "BID ID"}, risk_factor = "High/Medium/Low" }
local vuln_report = new vulns.Report:new(SCRIPT_NAME, host, port) return vuln_report:make_output(vuln)
PORT STATE SERVICE REASON 80/tcp open http syn-ack http-vuln-cve2012-1823: VULNERABLE: PHP-CGI Remote code execution and source code disclosure State: VULNERABLE (Exploitable) IDs: CVE:2012-1823 Description: According to PHP's website, "PHP is a widely-used general-purpose scripting language that is especially suited for Web development and can be embedded into HTML." When PHP is used in a CGI-based setup (such as Apache's mod_cgid), the php-cgi receives a processed query string parameter as command line arguments which allows command-line switches, such as -s, -d or -c to be passed to the php-cgi binary, which can be exploited to disclose source code and obtain arbitrary code execution. Disclosure date: 2012-05-3 Extra information: Proof of Concept:/index.php?-s References: http://eindbazen.net/2012/05/php-cgi-advisory-cve-2012-1823/ http://cve.mitre.org/cgi-bin/cvename.cgi?name=2012-1823 http://ompldr.org/vZGxxaQ
The library vulns
was introduced by Djalal Harouni and Henri Doreau to unify the output returned by NSE scripts that performed vulnerability checks. This library also manages and keeps track of the security checks done, a useful feature for users who would like to list the security checks even if the target was not vulnerable.
The vulnerability table can contain the following fields:
title
: String indicating the title of the vulnerability. This field is mandatory.state
: This field indicates different possible states of the vulnerability check. This field is mandatory. See the table vulns.STATE
for all possible values.IDS
: Field that stores CVE and BID IDs. It is used to automatically generate advisory URLs.risk_factor
: String that indicates the risk factor: High
/Medium
/Low
.scores
: Field that stores CVSS and CVSSv2 scores.description
: Description of the vulnerability.dates
: Field of dates relevant to this vulnerability.check_results
: String or list of strings used to store returned results.exploit_results
: String or list of strings used to store the exploitation results.extra_info
: String or list of strings used to store additional information.references
: List of URIs to be included as references. The library will automatically generate URIs for CVE and BID links if the table IDS was set.As you saw previously, the procedure to report vulnerabilities within NSE is pretty straightforward. First, we create a table containing all of the vulnerability information:
local vuln = { title = "<TITLE GOES HERE>", state = vulns.STATE.NOT_VULN, ... }
To report back to the users, we need a report object:
local vuln_report = new vulns.Report:new(SCRIPT_NAME, host, port)
The last function that you should use in NSE scripts that include this library is make_output()
. This will generate and display the report if the target was found to be vulnerable, or will return nil
if it wasn't.
return vuln_report:make_output(vuln)
If you would like to study more NSE scripts that use this library, visit http://nmap.org/nsedoc/categories/vuln.html. Note that not all the scripts use it yet as this library was introduced fairly recently.
You can tell Nmap to report on all vulnerability checks performed by NSE by using the library argument vulns.showall
:
# nmap -sV --script vuln --script-args vulns.showall <target>
A list of all vulnerability checks will be shown:
| http-vuln-cve2011-3192: | VULNERABLE: | Apache byterange filter DoS | State: VULNERABLE | IDs: CVE:CVE-2011-3192 OSVDB:74721 | Description: | The Apache web server is vulnerable to a denial of service attack when numerous | overlapping byte ranges are requested. | Disclosure date: 2011-08-19 | References: | http://nessus.org/plugins/index.php?view=single&id=55976 | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3192 | http://osvdb.org/74721 |_ http://seclists.org/fulldisclosure/2011/Aug/175 | http-vuln-cve2011-3368: | NOT VULNERABLE: | Apache mod_proxy Reverse Proxy Security Bypass | State: NOT VULNERABLE | IDs: CVE:CVE-2011-3368 OSVDB:76079 | References: | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3368 |_ http://osvdb.org/76079
This library can also be combined with prerule and postrule actions if you need more flexibility. The online documentation of the NSE library vulns
can be found at http://nmap.org/nsedoc/lib/vulns.html.
The library vulns
can mark hosts with an exploitability status which is used to indicate to the Nmap Scripting Engine if certain vulnerabilities exist in a host.
The following is a snippet from the vulns
library that shows the supported states and the corresponding string message used in the reports:
STATE_MSG = { [STATE.LIKELY_VULN] = 'LIKELY VULNERABLE', [STATE.NOT_VULN] = 'NOT VULNERABLE', [STATE.VULN] = 'VULNERABLE', [STATE.DoS] = 'VULNERABLE (DoS)', [STATE.EXPLOIT] = 'VULNERABLE (Exploitable)', [bit.bor(STATE.DoS,STATE.VULN)] = 'VUNERABLE (DoS)', [bit.bor(STATE.EXPLOIT,STATE.VULN)] = 'VULNERABLE (Exploitable)', }
18.223.107.85