diff --git a/CHANGELOG b/CHANGELOG index d50724c46..1ca261cb7 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,16 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Modified the following vulnerability scripts to use the new + vulnerability library. + - ftp-libopie.nse + - http-vuln-cve2011-3192.nse + - ftp-vuln-cve2010-4221.nse + - ftp-vsftpd-backdoor.nse + - smtp-vuln-cve2011-1720.nse + - smtp-vuln-cve2011-1764.nse + - afp-path-vuln.nse + [Djalal, Henri] + o [NSE] Add irc-botnet-channels.nse, to check an IRC server for channel names that may be used by botnets. [David, Ange Gutek] diff --git a/scripts/afp-path-vuln.nse b/scripts/afp-path-vuln.nse index 00202fa4b..b9d595408 100644 --- a/scripts/afp-path-vuln.nse +++ b/scripts/afp-path-vuln.nse @@ -25,15 +25,27 @@ For additional information: --@output -- PORT STATE SERVICE -- 548/tcp open afp --- | afp-path-vuln: --- | Patrik Karlsson's Public Folder/../ (5 first items) --- | .bash_history --- | .bash_profile --- | .CFUserTextEncoding --- | .config/ --- | .crash_report_checksum --- | --- |_AFP path traversal (CVE-2010-0533): VULNERABLE +-- | afp-path-vuln: +-- | VULNERABLE: +-- | Apple Mac OS X AFP server directory traversal +-- | State: VULNERABLE (Exploitable) +-- | IDs: CVE:CVE-2010-0533 +-- | Risk factor: High CVSSv2: 7.5 (HIGH) (AV:N/AC:L/Au:N/C:P/I:P/A:P) +-- | Description: +-- | Directory traversal vulnerability in AFP Server in Apple Mac OS X before +-- | 10.6.3 allows remote attackers to list a share root's parent directory. +-- | Disclosure date: 2010-03-29 +-- | Exploit results: +-- | Patrik Karlsson's Public Folder/../ (5 first items) +-- | .bash_history +-- | .bash_profile +-- | .CFUserTextEncoding +-- | .config/ +-- | .crash_report_checksum +-- | References: +-- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0533 +-- | http://support.apple.com/kb/HT1222 +-- |_ http://www.cqure.net/wp/2010/03/detecting-apple-mac-os-x-afp-vulnerability-cve-2010-0533-with-nmap -- -- @@ -43,6 +55,7 @@ For additional information: -- Revised 05/03/2010 - v0.2 - cleaned up and added dependency to afp-brute and added support -- for credentials by argument or registry -- Revised 10/03/2010 - v0.3 - combined afp-path-exploit and afp-path-vuln into this script +-- Revised 21/10/2011 - v0.4 - Use the vulnerability library vulns.lua author = "Patrik Karlsson" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -51,6 +64,7 @@ categories = {"exploit", "intrusive", "vuln"} require 'shortport' require 'stdnse' require 'afp' +require 'vulns' dependencies = {"afp-brute"} @@ -110,7 +124,6 @@ end action = function(host, port) local status, response, shares - local result = {} local afp_helper = afp.Helper:new() local args = nmap.registry.args local users = nmap.registry.afp or { ['nil'] = 'nil' } @@ -118,10 +131,32 @@ action = function(host, port) local MAX_FILES = 5 + local afp_vuln = { + title = "Apple Mac OS X AFP server directory traversal", + IDS = {CVE = 'CVE-2010-0533'}, + risk_factor = "High", + scores = { + CVSSv2 = "7.5 (HIGH) (AV:N/AC:L/Au:N/C:P/I:P/A:P)", + }, + description = [[ +Directory traversal vulnerability in AFP Server in Apple Mac OS X before +10.6.3 allows remote attackers to list a share root's parent directory.]], + references = { +'http://www.cqure.net/wp/2010/03/detecting-apple-mac-os-x-afp-vulnerability-cve-2010-0533-with-nmap', +'http://support.apple.com/kb/HT1222', + }, + dates = { + disclosure = {year = '2010', month = '03', day = '29'}, + }, + exploit_results = {}, + } + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + if ( args['afp.username'] ) then users = {} users[args['afp.username']] = args['afp.password'] - end + end for username, password in pairs(users) do @@ -156,21 +191,27 @@ action = function(host, port) vulnerable = true if(nmap.verbosity() > 1) then response = processResponse( response ) - response.name = share .. "/../" + local name = share .. "/../" + table.insert(afp_vuln.exploit_results, + name) else response = processResponse( response, MAX_FILES ) - response.name = share .. ("/../ (%d first items)"):format(MAX_FILES) + local name = share .. ("/../ (%d first items)"):format(MAX_FILES) + table.insert(afp_vuln.exploit_results, + name) end - table.insert(result, response) + table.insert(afp_vuln.exploit_results, + response) end end end end if ( vulnerable ) then - table.insert(result, "\n\nAFP path traversal (CVE-2010-0533): VULNERABLE") + afp_vuln.state = vulns.STATE.EXPLOIT + else + afp_vuln.state = vulns.STATE.NOT_VULN end - return stdnse.format_output(true, result) - + return report:make_output(afp_vuln) end diff --git a/scripts/ftp-libopie.nse b/scripts/ftp-libopie.nse index 957eaa4d8..a13714d80 100644 --- a/scripts/ftp-libopie.nse +++ b/scripts/ftp-libopie.nse @@ -9,9 +9,23 @@ Be advised that, if launched against a vulnerable host, this script will crash t -- @output -- PORT STATE SERVICE -- 21/tcp open ftp --- | ftp-libopie: Warning: Looks like the service has crashed! --- | Likely prone to CVE-2010-1938 (OPIE off-by-one stack overflow) --- |_See http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc +-- | ftp-libopie: +-- | VULNERABLE: +-- | OPIE off-by-one stack overflow +-- | State: LIKELY VULNERABLE +-- | IDs: CVE:CVE-2010-1938 OSVDB:64949 +-- | Risk factor: High CVSSv2: 9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C) +-- | Description: +-- | An off-by-one error in OPIE library 2.4.1-test1 and earlier, allows remote +-- | attackers to cause a denial of service or possibly execute arbitrary code +-- | via a long username. +-- | Disclosure date: 2010-05-27 +-- | References: +-- | http://osvdb.org/64949 +-- | http://site.pi3.com.pl/adv/libopie-adv.txt +-- | http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc +-- |_ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-1938 +-- author = "Ange Gutek" @@ -19,10 +33,33 @@ license = "Same as Nmap--See http://nmap.org/book/man-legal.html" categories = {"vuln","intrusive"} require "shortport" +require "vulns" portrule = shortport.port_or_service(21, "ftp") action = function(host, port) + local opie_vuln = { + title = "OPIE off-by-one stack overflow", + IDS = {CVE = 'CVE-2010-1938', OSVDB = '64949'}, + risk_factor = "High", + scores = { + CVSSv2 = "9.3 (HIGH) (AV:N/AC:M/Au:N/C:C/I:C/A:C)", + }, + description = [[ +An off-by-one error in OPIE library 2.4.1-test1 and earlier, allows remote +attackers to cause a denial of service or possibly execute arbitrary code +via a long username.]], + references = { +'http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc', +'http://site.pi3.com.pl/adv/libopie-adv.txt', + }, + dates = { + disclosure = {year = '2010', month = '05', day = '27'}, + }, + } + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + local socket = nmap.new_socket() local result -- If we use more that 31 chars for username, ftpd will crash (quoted from the advisory). @@ -51,12 +88,11 @@ action = function(host, port) status, result = socket:receive_lines(1); if status then - return + opie_vuln.state = vulns.STATE.NOT_VULN else -- if the server does not answer anymore we may have reached a stack overflow condition - return "Warning: Looks like the service has crashed!\nLikely prone to CVE-2010-1938 (OPIE off-by-one stack overflow)\nSee http://security.freebsd.org/advisories/FreeBSD-SA-10:05.opie.asc" + opie_vuln.state = vulns.STATE.LIKELY_VULN end - else - return end + return report:make_output(opie_vuln) end diff --git a/scripts/ftp-vsftpd-backdoor.nse b/scripts/ftp-vsftpd-backdoor.nse index 187baae72..8449fbd7d 100644 --- a/scripts/ftp-vsftpd-backdoor.nse +++ b/scripts/ftp-vsftpd-backdoor.nse @@ -21,10 +21,24 @@ References: -- @output -- PORT STATE SERVICE -- 21/tcp open ftp --- | ftp-vsftpd-backdoor: --- | This installation has been backdoored (CVE-2011-2523): VULNERABLE --- | Shell command: id --- |_ Results: uid=0(root) gid=0(root) groups=0(root) +-- | ftp-vsftpd-backdoor: +-- | VULNERABLE: +-- | vsFTPd version 2.3.4 backdoor +-- | State: VULNERABLE (Exploitable) +-- | IDs: CVE:CVE-2011-2523 OSVDB:73573 +-- | Description: +-- | vsFTPd version 2.3.4 backdoor, this was reported on 2011-07-04. +-- | Disclosure date: 2011-07-03 +-- | Exploit results: +-- | The backdoor was already triggered +-- | Shell command: id +-- | Results: uid=0(root) gid=0(root) groups=0(root) +-- | References: +-- | http://osvdb.org/73573 +-- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-2523 +-- | http://scarybeastsecurity.blogspot.com/2011/07/alert-vsftpd-download-backdoored.html +-- |_ https://dev.metasploit.com/redmine/projects/framework/repository/revisions/13093 +-- author = "Daniel Miller" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -34,6 +48,7 @@ require("ftp") require("nmap") require("shortport") require("stdnse") +require("vulns") local CMD_FTP = "USER X:)\r\nPASS X\r\n" local CMD_SHELL_ID = "id" @@ -60,15 +75,16 @@ local function finish_ftp(socket, status, message) end -- Returns true, results if vsFTPd was backdoored -local function check_backdoor(host, shell_cmd) +local function check_backdoor(host, shell_cmd, vuln) local socket = nmap.new_socket("tcp") socket:set_timeout(10000) local status, ret = socket:connect(host, 6200, "tcp") if not status then - return finish_ftp(socket, false, - string.format("can't connect to tcp port 6200: NOT VULNERABLE ", - ret)) + stdnse.print_debug(3, "%s: can't connect to tcp port 6200: NOT VULNERABLE", + SCRIPT_NAME) + vuln.state = vulns.STATE.NOT_VULN + return finish_ftp(socket, true) end status, ret = socket:send(CMD_SHELL_ID.."\n") @@ -84,8 +100,11 @@ local function check_backdoor(host, shell_cmd) end if not ret:match("uid=") then - return finish_ftp(socket, false, - "service on port 6200 is not the vsFTPd backdoor: NOT VULNERABLE") + stdnse.print_debug(3, + "%s: service on port 6200 is not the vsFTPd backdoor: NOT VULNERABLE", + SCRIPT_NAME) + vuln.state = vulns.STATE.NOT_VULN + return finish_ftp(socket, true) else if shell_cmd ~= CMD_SHELL_ID then status, ret = socket:send(shell_cmd.."\n") @@ -102,8 +121,15 @@ local function check_backdoor(host, shell_cmd) socket:send("exit\n"); end end + + vuln.state = vulns.STATE.EXPLOIT + table.insert(vuln.exploit_results, + string.format("Shell command: %s", shell_cmd)) + local result = string.gsub(ret, "^%s*(.-)\n*$", "%1") + table.insert(vuln.exploit_results, + string.format("Results: %s", result)) - return finish_ftp(socket, true, string.gsub(ret, "^%s*(.-)\n*$", "%1")) + return finish_ftp(socket, true) end action = function(host, port) @@ -111,17 +137,26 @@ action = function(host, port) local cmd = stdnse.get_script_args("ftp-vsftpd-backdoor.cmd") or stdnse.get_script_args("exploit.cmd") or CMD_SHELL_ID - local results = { - "This installation has been backdoored (CVE-2011-2523): VULNERABLE", - " Shell command: " .. cmd, + local vsftp_vuln = { + title = "vsFTPd version 2.3.4 backdoor", + IDS = {CVE = 'CVE-2011-2523', OSVDB = '73573'}, + description = [[ +vsFTPd version 2.3.4 backdoor, this was reported on 2011-07-04.]], + references = { +'http://scarybeastsecurity.blogspot.com/2011/07/alert-vsftpd-download-backdoored.html', +'https://dev.metasploit.com/redmine/projects/framework/repository/revisions/13093', + }, + dates = { + disclosure = {year = '2011', month = '07', day = '03'}, + }, + exploit_results = {}, } + local report = vulns.Report:new(SCRIPT_NAME, host, port) -- check to see if the vsFTPd backdoor was already triggered - local status, ret = check_backdoor(host, cmd) + local status, ret = check_backdoor(host, cmd, vsftp_vuln) if status then - table.insert(results, 2, "The backdoor was already triggered") - table.insert(results, string.format(" Results: %s", ret)) - return stdnse.format_output(true, results) + return report:make_output(vsftp_vuln) end -- Create socket. @@ -153,7 +188,7 @@ action = function(host, port) stdnse.sleep(1) -- check if vsFTPd was backdoored - status, ret = check_backdoor(host, cmd) + status, ret = check_backdoor(host, cmd, vsftp_vuln) if not status then stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, ret) return nil @@ -161,6 +196,5 @@ action = function(host, port) -- delay ftp socket cleaning sock:close() - table.insert(results, string.format(" Results: %s", ret)) - return stdnse.format_output(true, results) + return report:make_output(vsftp_vuln) end diff --git a/scripts/ftp-vuln-cve2010-4221.nse b/scripts/ftp-vuln-cve2010-4221.nse index b04d968a8..93289ad70 100644 --- a/scripts/ftp-vuln-cve2010-4221.nse +++ b/scripts/ftp-vuln-cve2010-4221.nse @@ -19,10 +19,25 @@ Reference: -- @output -- PORT STATE SERVICE -- 21/tcp open ftp --- | ftp-vuln-cve2010-4221: --- | ProFTPD version: 1.3.2e --- | ProFTPD Telnet IAC buffer overflow (CVE-2011-4221): --- |_ ProFTPD (CVE-2011-4221): VULNERABLE +-- | ftp-vuln-cve2010-4221: +-- | VULNERABLE: +-- | ProFTPD server TELNET IAC stack overflow +-- | State: VULNERABLE +-- | IDs: CVE:CVE-2010-4221 BID:44562 OSVDB:68985 +-- | Risk factor: High CVSSv2: 10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C) +-- | Description: +-- | ProFTPD server (version 1.3.2rc3 through 1.3.3b) is vulnerable to +-- | stack-based buffer overflow. By sending a large number of TELNET_IAC +-- | escape sequence, a remote attacker will be able to corrup the stack and +-- | execute arbitrary code. +-- | Disclosure date: 2010-11-02 +-- | References: +-- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-4221 +-- | http://osvdb.org/68985 +-- | http://www.metasploit.com/modules/exploit/freebsd/ftp/proftp_telnet_iac +-- | http://bugs.proftpd.org/show_bug.cgi?id=3521 +-- |_ http://www.securityfocus.com/bid/44562 +-- author = "Djalal Harouni" license = "Same as Nmap--See http://nmap.org/book/man-legal.html" @@ -31,6 +46,7 @@ categories = {"intrusive", "vuln"} require "ftp" require "shortport" require "stdnse" +require "vulns" portrule = function (host, port) if port.version.product ~= nil and port.version.product ~= "ProFTPD" then @@ -75,7 +91,7 @@ local function is_version_vulnerable(version) end elseif relnum == '3' then if extra:len() == 0 or extra:match("[abrc]") then - return true + return true end end end @@ -112,9 +128,7 @@ local function kill_proftpd(socket) end local function check_proftpd(ftp_opts) - local out, ftp_server = {}, {} - local cve, proftpd_vuln = "CVE-2010-4221" - local proftpd_str = "ProFTPD Telnet IAC buffer overflow ("..cve.."):" + local ftp_server = {} local socket, ret = ftp.connect(ftp_opts.host, ftp_opts.port, {recv_before = true}) if not socket then @@ -128,40 +142,60 @@ local function check_proftpd(ftp_opts) return ftp_finish(socket, false, "not a ProFTPD server.") end + local vuln = ftp_opts.vuln -- check if this version is vulnerable if ftp_server.version then if not is_version_vulnerable(ftp_server.version) then - return ftp_finish(socket, false, "ProFTPD is NOT VULENRABLE.") + vuln.state = vulns.STATE.NOT_VULN + return ftp_finish(socket, true) end - table.insert(out, string.format("ProFTPD version: %s", - ftp_server.version)) - proftpd_vuln = string.format(" ProFTPD (%s): LIKELY VULNERABLE", cve) + vuln.state = vulns.STATE.LIKELY_VULN end local status, killed = kill_proftpd(socket) if not status then return ftp_finish(socket, false, killed) elseif killed then - proftpd_vuln = string.format(" ProFTPD (%s): VULNERABLE", cve) - elseif not proftpd_vuln then - return ftp_finish(socket, false, - 'server ProFTPD seems NOT VULNERABLE.') + vuln.state = vulns.STATE.VULN + elseif not vuln.state then + vuln.state = vulns.STATE.NOT_VULN end - table.insert(out, proftpd_str) - table.insert(out, proftpd_vuln) - return ftp_finish(socket, true, out) + return ftp_finish(socket, true) end action = function(host, port) local ftp_opts = { host = host, port = port, + vuln = { + title = 'ProFTPD server TELNET IAC stack overflow', + IDS = {CVE = 'CVE-2010-4221', OSVDB = '68985', BID = '44562'}, + risk_factor = "High", + scores = { + CVSSv2 = "10.0 (HIGH) (AV:N/AC:L/Au:N/C:C/I:C/A:C)", + }, + description = [[ +ProFTPD server (version 1.3.2rc3 through 1.3.3b) is vulnerable to +stack-based buffer overflow. By sending a large number of TELNET_IAC +escape sequence, a remote attacker will be able to corrup the stack and +execute arbitrary code.]], + references = { +'http://bugs.proftpd.org/show_bug.cgi?id=3521', +'http://www.metasploit.com/modules/exploit/freebsd/ftp/proftp_telnet_iac', + }, + dates = { + disclosure = {year = 2011, month = 11, day = 02}, + }, + } } - local status, output = check_proftpd(ftp_opts) + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + + local status, err = check_proftpd(ftp_opts) if not status then - stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, output) + stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, err) return nil end - return stdnse.format_output(status, output) + return report:make_output(ftp_opts.vuln) end diff --git a/scripts/http-vuln-cve2011-3192.nse b/scripts/http-vuln-cve2011-3192.nse index f5c1dd99d..9885bb5ae 100644 --- a/scripts/http-vuln-cve2011-3192.nse +++ b/scripts/http-vuln-cve2011-3192.nse @@ -1,5 +1,6 @@ description = [[ -Detects a denial of service vulnerability in the way the Apache web server handles requests for multiple overlapping/simple ranges of a page. +Detects a denial of service vulnerability in the way the Apache web server +handles requests for multiple overlapping/simple ranges of a page. References: * http://seclists.org/fulldisclosure/2011/Aug/175 @@ -13,8 +14,20 @@ References: -- -- @output -- Host script results: --- | http-vuln-cve2011-3192: --- |_ Apache byterange filter DoS: VULNERABLE +-- | 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://seclists.org/fulldisclosure/2011/Aug/175 +-- | http://nessus.org/plugins/index.php?view=single&id=55976 +-- | http://osvdb.org/74721 +-- |_ http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3192 -- -- @args http-vuln-cve2011-3192.hostname Define the host name to be used in the HEAD request sent to the server -- @args http-vuln-cve2011-3192.path Define the request path @@ -26,6 +39,8 @@ References: -- * Changes based on Henri Doreau and David Fifield sugestions -- 2011-08-20 Duarte Silva -- * First version ;) +-- 2011-11-07 Henri Doreau +-- * Use the vulns library to report results ----------------------------------------------------------------------- author = "Duarte Silva " @@ -34,10 +49,28 @@ categories = {"vuln", "safe"} require "shortport" require "http" +require "vulns" portrule = shortport.http action = function(host, port) + local vuln = { + title = 'Apache byterange filter DoS', + state = vulns.STATE.NOT_VULN, -- default + 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.]], + references = { + 'http://seclists.org/fulldisclosure/2011/Aug/175', + 'http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-3192', + 'http://nessus.org/plugins/index.php?view=single&id=55976', + }, + dates = { + disclosure = {year = '2011', month = '08', day = '19'}, + }, + } + local vuln_report = vulns.Report:new(SCRIPT_NAME, host, port) local hostname, path = stdnse.get_script_args('http-vuln-cve2011-3192.hostname', 'http-vuln-cve2011-3192.path') @@ -80,7 +113,7 @@ action = function(host, port) stdnse.print_debug(1, "%s: Invalid response from server to the vulnerability check", SCRIPT_NAME) elseif response.status == 206 then - return stdnse.format_output(true, "Apache byterange filter DoS: VULNERABLE") + vuln.state = vulns.STATE.VULN else stdnse.print_debug(1, "%s: Server isn't vulnerable (%i status code)", SCRIPT_NAME, response.status) @@ -89,5 +122,6 @@ action = function(host, port) stdnse.print_debug(1, "%s: Server ignores the range header (%i status code)", SCRIPT_NAME, response.status) end + return vuln_report:make_output(vuln) end diff --git a/scripts/smtp-vuln-cve2011-1720.nse b/scripts/smtp-vuln-cve2011-1720.nse index 356485e3e..8dd517df2 100644 --- a/scripts/smtp-vuln-cve2011-1720.nse +++ b/scripts/smtp-vuln-cve2011-1720.nse @@ -15,11 +15,24 @@ Reference: -- @output -- PORT STATE SERVICE -- 25/tcp open smtp --- | smtp-vuln-cve2011-1720: --- | Postfix Cyrus SASL (CVE-2011-1720): --- | AUTH MECHANISMS: CRAM-MD5 DIGEST-MD5 NTLM PLAIN LOGIN --- | AUTH tests: CRAM-MD5 --- |_ Postfix Cyrus SASL authentication: VULNERABLE (CRAM-MD5 => DIGEST-MD5) +-- | smtp-vuln-cve2011-1720: +-- | VULNERABLE: +-- | Postfix SMTP server Cyrus SASL Memory Corruption +-- | State: VULNERABLE +-- | IDs: CVE:CVE-2011-1720 OSVDB:72259 +-- | Description: +-- | The Postfix SMTP server is vulnerable to a memory corruption vulnerability +-- | when the Cyrus SASL library is used with authentication mechanisms other +-- | than PLAIN and LOGIN. +-- | Disclosure date: 2011-05-08 +-- | Check results: +-- | AUTH tests: CRAM-MD5 NTLM +-- | Extra information: +-- | Available AUTH MECHANISMS: CRAM-MD5 DIGEST-MD5 NTLM PLAIN LOGIN +-- | References: +-- | http://www.postfix.org/CVE-2011-1720.html +-- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1720 +-- |_ http://osvdb.org/72259 -- -- @args smtp.domain Define the domain to be used in the SMTP EHLO command. @@ -30,6 +43,7 @@ categories = {"intrusive", "vuln"} require "shortport" require "smtp" require "stdnse" +require "vulns" portrule = shortport.port_or_service({25, 465, 587}, {"smtp", "smtps", "submission"}) @@ -87,11 +101,11 @@ local function chk_auth_mechanisms(ehlo_res, auth_mlist) end -- Close any remaining connection -local function smtp_finish(socket, status, msg) +local function smtp_finish(socket, status, err) if socket then smtp.quit(socket) end - return status, msg + return status, err end -- Tries to kill the smtpd server @@ -134,8 +148,6 @@ end -- Postfix Cyrus SASL authentication memory corruption -- http://www.postfix.org/CVE-2011-1720.html local function check_smtpd(smtp_opts) - local postfix_vuln = "Postfix Cyrus SASL authentication" - local socket, ret = smtp.connect(smtp_opts.host, smtp_opts.port, {ssl = false, @@ -186,10 +198,12 @@ local function check_smtpd(smtp_opts) end end - local output = {} - output.name = "Postfix Cyrus SASL (CVE-2011-1720):" + local vuln = smtp_opts.vuln + vuln.check_results = {} if (#auth_mech_str > 0) then - table.insert(output, string.format("AUTH MECHANISMS: %s", auth_mech_str)) + vuln.extra_info = {} + table.insert(vuln.extra_info, + string.format("Available AUTH MECHANISMS: %s", auth_mech_str)) -- maybe vulnerable if next(auth_mech_list) then @@ -210,12 +224,12 @@ local function check_smtpd(smtp_opts) end if ret then - table.insert(output, - string.format("AUTH tests:%s", auth_tests)) - table.insert(output, - string.format("%s: VULNERABLE (%s => %s)", - postfix_vuln, mech, mkill)) - return smtp_finish(nil, true, output) + vuln.state = vulns.STATE.VULN + table.insert(vuln.check_results, + string.format("AUTH tests:%s", auth_tests)) + table.insert(vuln.check_results, + string.format("VULNERABLE (%s => %s)", mech, mkill)) + return smtp_finish(nil, true) end end @@ -225,14 +239,17 @@ local function check_smtpd(smtp_opts) end end - table.insert(output, string.format("AUTH tests:%s", auth_tests)) + table.insert(vuln.check_results, string.format("AUTH tests:%s", + auth_tests)) end else - table.insert(output, "Authentication is not available") + stdnse.print_debug(2, "%s: Authentication is not available", + SCRIPT_NAME) + table.insert(vuln.check_results, "Authentication is not available") end - - table.insert(output, string.format("%s: NOT VULNERABLE", postfix_vuln)) - return smtp_finish(socket, true, output) + + vuln.state = vulns.STATE.NOT_VULN + return smtp_finish(socket, true) end action = function(host, port) @@ -241,11 +258,27 @@ action = function(host, port) port = port, domain = stdnse.get_script_args('smtp-vuln-cve2011-1720.domain') or smtp.get_domain(host), + vuln = { + title = 'Postfix SMTP server Cyrus SASL Memory Corruption', + IDS = {CVE = 'CVE-2011-1720', OSVDB = '72259'}, + description = [[ +The Postfix SMTP server is vulnerable to a memory corruption vulnerability +when the Cyrus SASL library is used with authentication mechanisms other +than PLAIN and LOGIN.]], + references = { + 'http://www.postfix.org/CVE-2011-1720.html', + }, + dates = { + disclosure = {year = '2011', month = '05', day = '08'}, + }, + }, } - local status, output = check_smtpd(smtp_opts) + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + local status, err = check_smtpd(smtp_opts) if not status then - stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, output) + stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, err) return nil end - return stdnse.format_output(status, output) + return report:make_output(smtp_opts.vuln) end diff --git a/scripts/smtp-vuln-cve2011-1764.nse b/scripts/smtp-vuln-cve2011-1764.nse index 6382f9224..02eaf606f 100644 --- a/scripts/smtp-vuln-cve2011-1764.nse +++ b/scripts/smtp-vuln-cve2011-1764.nse @@ -1,5 +1,10 @@ description = [[ -Checks for a format string vulnerability in the Exim SMTP server (version 4.70 through 4.75) with DomainKeys Identified Mail (DKIM) support (CVE-2011-1764). The DKIM logging mechanism did not use format string specifiers when logging some parts of the DKIM-Signature header field. A remote attacker who is able to send emails, can exploit this vulnerability and execute arbitrary code with the privileges of the Exim daemon. +Checks for a format string vulnerability in the Exim SMTP server +(version 4.70 through 4.75) with DomainKeys Identified Mail (DKIM) support +(CVE-2011-1764). The DKIM logging mechanism did not use format string +specifiers when logging some parts of the DKIM-Signature header field. +A remote attacker who is able to send emails, can exploit this vulnerability +and execute arbitrary code with the privileges of the Exim daemon. Reference: * http://bugs.exim.org/show_bug.cgi?id=1106 @@ -15,10 +20,22 @@ Reference: -- @output -- PORT STATE SERVICE -- 25/tcp open smtp --- | smtp-vuln-cve2011-1764: --- | Exim version: 4.72 --- | Exim DKIM Signatures Format String (CVE-2011-1764): --- |_ Exim (CVE-2011-1764): VULNERABLE +-- | smtp-vuln-cve2011-1764: +-- | VULNERABLE: +-- | Exim DKIM format string +-- | State: VULNERABLE +-- | IDs: CVE:CVE-2011-1764 OSVDB:72156 +-- | Risk factor: High CVSSv2: 7.5 (HIGH) (AV:N/AC:L/Au:N/C:P/I:P/A:P) +-- | Description: +-- | Exim SMTP server (version 4.70 through 4.75) with DomainKeys Identified +-- | Mail (DKIM) support is vulnerable to a format string. A remote attacker +-- | who is able to send emails, can exploit this vulnerability and execute +-- | arbitrary code with the privileges of the Exim daemon. +-- | Disclosure date: 2011-04-29 +-- | References: +-- | http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-1764 +-- | http://osvdb.org/72156 +-- |_ http://bugs.exim.org/show_bug.cgi?id=1106 -- -- @args smtp.domain Define the domain to be used in the SMTP EHLO command. -- @args smtp-vuln-cve2011-1764.mailfrom Define the source email address to @@ -33,6 +50,7 @@ categories = {"intrusive", "vuln"} require "shortport" require "smtp" require "stdnse" +require "vulns" portrule = function (host, port) if port.version.product ~= nil and port.version.product ~= "Exim smtpd" then @@ -115,11 +133,8 @@ end -- Checks if the Exim server is vulnerable to CVE-2011-1764 local function check_exim(smtp_opts) - local out, smtp_server = {}, {} + local smtp_server = {} local exim_ver_min, exim_ver_max = 4.70, 4.75 - local cve = 'CVE-2011-1764' - local exim_dkim_str = "Exim DKIM Signatures Format String ("..cve.."):" - local exim_dkim_result local socket, ret = smtp.connect(smtp_opts.host, smtp_opts.port, @@ -141,16 +156,17 @@ local function check_exim(smtp_opts) 'not a Exim server: NOT VULNERABLE') end + local vuln = smtp_opts.vuln + vuln.extra_info = {} if smtp_server.version then if smtp_server.version <= exim_ver_max and smtp_server.version >= exim_ver_min then - exim_dkim_result = string.format(" Exim (%s): LIKELY VULNERABLE", cve) - table.insert(out, + vuln.state = vulns.STATE.LIKELY_VULN + table.insert(vuln.extra_info, string.format("Exim version: %.02f", smtp_server.version)) else - return smtp_finish(socket, false, - string.format("Exim version %.02f is NOT VULNERABLE.", - smtp_server.version)) + vuln.state = vulns.STATE.NOT_VULN + return smtp_finish(socket, true) end end @@ -173,14 +189,12 @@ local function check_exim(smtp_opts) if not status then return smtp_finish(socket, status, ret) elseif ret then - exim_dkim_result = string.format(" Exim (%s): VULNERABLE", cve) - elseif not exim_dkim_result then - return smtp_finish(socket, false, 'Exim server seems NOT VULNERABLE.') + vuln.state = vulns.STATE.VULN + elseif not vuln.state then + vuln.state = vulns.STATE.NOT_VULN end - table.insert(out, exim_dkim_str) - table.insert(out, exim_dkim_result) - return smtp_finish(socket, true, out) + return smtp_finish(socket, true) end action = function(host, port) @@ -191,11 +205,32 @@ action = function(host, port) 'nmap.scanme.org', mailfrom = stdnse.get_script_args('smtp-vuln-cve2011-1764.mailfrom'), mailto = stdnse.get_script_args('smtp-vuln-cve2011-1764.mailto'), + vuln = { + title = 'Exim DKIM format string', + IDS = {CVE = 'CVE-2011-1764', OSVDB = '72156'}, + risk_factor = "High", + scores = { + CVSSv2 = "7.5 (HIGH) (AV:N/AC:L/Au:N/C:P/I:P/A:P)", + }, + description = [[ +Exim SMTP server (version 4.70 through 4.75) with DomainKeys Identified +Mail (DKIM) support is vulnerable to a format string. A remote attacker +who is able to send emails, can exploit this vulnerability and execute +arbitrary code with the privileges of the Exim daemon.]], + references = { + 'http://bugs.exim.org/show_bug.cgi?id=1106', + }, + dates = { + disclosure = {year = '2011', month = '04', day = '29'}, + }, + }, } - local status, output = check_exim(smtp_opts) + + local report = vulns.Report:new(SCRIPT_NAME, host, port) + local status, err = check_exim(smtp_opts) if not status then - stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, output) + stdnse.print_debug(1, "%s: %s", SCRIPT_NAME, err) return nil end - return stdnse.format_output(status, output) + return report:make_output(smtp_opts.vuln) end