mirror of
https://github.com/nmap/nmap.git
synced 2026-01-21 13:49:04 +00:00
Modified smb-check-vulns.nse to check for Connficker infections. Got permission from authors of simple connficker scanner (scs.zip) to post this
This commit is contained in:
@@ -778,6 +778,79 @@ function srvsvc_netpathcompare(smbstate, server, path1, path2, pathtype, pathfla
|
||||
end
|
||||
|
||||
|
||||
---Call the NetPathCanonicalize() function, which is the target of ms08-067.
|
||||
--
|
||||
--@param smbstate The SMB state table
|
||||
--@param server The IP or Hostname of the server (seems to be ignored but it's a good idea to have it)
|
||||
--@param path The path to canonicalize
|
||||
--@return (status, result, error_result) If status is false, result is an error message and error_result is
|
||||
-- the result table. Otherwise, result is a table of values.
|
||||
function srvsvc_netpathcanonicalize(smbstate, server, path)
|
||||
local i, j
|
||||
local status, result
|
||||
local arguments
|
||||
local pos, align
|
||||
|
||||
stdnse.print_debug(2, "MSRPC: Calling NetPathCanonicalize(%s) [%s]", path, smbstate['ip'])
|
||||
|
||||
-- [in] [string,charset(UTF16)] uint16 *server_unc,
|
||||
arguments = msrpctypes.marshall_unicode_ptr(server, true)
|
||||
-- [in] [string,charset(UTF16)] uint16 path[],
|
||||
arguments = arguments .. msrpctypes.marshall_unicode(path, true)
|
||||
-- [out] [size_is(maxbuf)] uint8 can_path[],
|
||||
-- [in] uint32 maxbuf,
|
||||
arguments = arguments .. msrpctypes.marshall_int32(2)
|
||||
|
||||
-- [in] [string,charset(UTF16)] uint16 prefix[],
|
||||
arguments = arguments .. msrpctypes.marshall_unicode("\\", true)
|
||||
|
||||
-- [in,out] uint32 pathtype,
|
||||
arguments = arguments .. msrpctypes.marshall_int32(1)
|
||||
-- [in] uint32 pathflags
|
||||
arguments = arguments .. msrpctypes.marshall_int32(1)
|
||||
|
||||
|
||||
-- Do the call
|
||||
status, result = call_function(smbstate, 0x1F, arguments)
|
||||
if(status ~= true) then
|
||||
return false, result
|
||||
end
|
||||
|
||||
stdnse.print_debug(3, "MSRPC: NetPathCanonicalize() returned successfully")
|
||||
|
||||
-- Make arguments easier to use
|
||||
arguments = result['arguments']
|
||||
pos = 1
|
||||
|
||||
-- [in] [string,charset(UTF16)] uint16 *server_unc,
|
||||
-- [in] [string,charset(UTF16)] uint16 path[],
|
||||
-- [out] [size_is(maxbuf)] uint8 can_path[],A
|
||||
-- [in] uint32 maxbuf,
|
||||
-- [in] [string,charset(UTF16)] uint16 prefix[],
|
||||
-- [in,out] uint32 pathtype,
|
||||
-- [in] uint32 pathflags
|
||||
|
||||
-- NOTE: This isn't being done correctly.. due to Wireshark's broken parsing,
|
||||
-- and Samba's possibly-broken definition, I'm not sure how this is supposed
|
||||
-- to be parsed.
|
||||
pos, result['max_count'] = msrpctypes.unmarshall_int32(arguments, pos)
|
||||
pos, result['can_path'] = msrpctypes.unmarshall_int32(arguments, pos)
|
||||
pos, result['type'] = msrpctypes.unmarshall_int32(arguments, pos)
|
||||
pos, result['return'] = msrpctypes.unmarshall_int32(arguments, pos)
|
||||
|
||||
if(result['return'] == nil) then
|
||||
return false, "Read off the end of the packet (srvsvc.netpathcanonicalize)"
|
||||
end
|
||||
if(result['return'] ~= 0) then
|
||||
return false, smb.get_status_name(result['return']) .. " (srvsvc.netpathcanonicalize)", result
|
||||
end
|
||||
|
||||
return true, result
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---A proxy to a <code>msrpctypes</code> function that converts a PasswordProperties to an english string.
|
||||
|
||||
@@ -2283,6 +2283,7 @@ status_codes =
|
||||
NT_STATUS_OK = 0x0000,
|
||||
NT_STATUS_WERR_BADFILE = 0x00000002,
|
||||
NT_STATUS_WERR_ACCESS_DENIED = 0x00000005,
|
||||
NT_STATUS_WERR_UNKNOWN_57 = 0x00000057,
|
||||
NT_STATUS_WERR_INVALID_NAME = 0x0000007b,
|
||||
NT_STATUS_WERR_UNKNOWN_LEVEL = 0x0000007c,
|
||||
NT_STATUS_WERR_MORE_DATA = 0x000000ea,
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
description = [[
|
||||
Checks if a host is vulnerable to MS08-067, a Windows RPC vulnerability that
|
||||
can allow remote code execution. This script will be expanded to check for more
|
||||
vulnerabilities in the future.
|
||||
Check for vulnerabilities:
|
||||
* MS08-067, a Windows RPC vulnerability
|
||||
* Connficker, an infection by the Connficker worm
|
||||
* Unnamed regsvc DoS, a denial-of-service vulnerability I accidentically found in Windows 2003
|
||||
|
||||
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,
|
||||
@@ -18,6 +19,9 @@ If you set the script parameter 'unsafe', then scripts will run that are almost
|
||||
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
|
||||
@@ -27,6 +31,11 @@ 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.
|
||||
|
||||
Connficker -- Checks if a host is infected with a known Connficker strain. This check
|
||||
is based on the simple connficker 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 <code>smb-enum-sessions</code>, and discovered that it was repeatable. It's been
|
||||
@@ -39,10 +48,6 @@ or higher to work. It is considered <code>unsafe</code>.
|
||||
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).
|
||||
|
||||
---
|
||||
--@usage
|
||||
-- nmap --script smb-check-vulns.nse -p445 <host>
|
||||
@@ -52,11 +57,14 @@ on the Nmap-dev mailing list and I'll add it to my list [Ron Bowes]).
|
||||
-- Host script results:
|
||||
-- | smb-check-vulns:
|
||||
-- | MS08-067: FIXED
|
||||
-- | Connficker: Likely INFECTED
|
||||
-- |_ regsvc DoS: VULNERABLE
|
||||
--
|
||||
-- @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.
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
author = "Ron Bowes"
|
||||
@@ -94,9 +102,13 @@ local NOTRUN = 4
|
||||
--
|
||||
--@param host The host object.
|
||||
--@return (status, result) If status if alse, result is an error code; otherwise, result is either
|
||||
-- <code>VULNERABLE</code> for vulnerable, <code>PATCHED</code> for not vulnerable, or
|
||||
-- <code>UNKNOWN</code> if there was an error (likely vulnerable).
|
||||
-- <code>VULNERABLE</code> for vulnerable, <code>PATCHED</code> for not vulnerable,
|
||||
-- <code>UNKNOWN</code> if there was an error (likely vulnerable), and <code>NOTRUN</code>
|
||||
-- if this check was disabled.
|
||||
function check_ms08_067(host)
|
||||
if(nmap.registry.args.safe ~= nil) then
|
||||
return true, NOTRUN
|
||||
end
|
||||
local status, smbstate
|
||||
local bind_result, netpathcompare_result
|
||||
|
||||
@@ -135,6 +147,59 @@ function check_ms08_067(host)
|
||||
return true, VULNERABLE
|
||||
end
|
||||
|
||||
|
||||
---Check if the server is infected with Connficker. 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 Connficker 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>VULNERABLE</code> for infected or <code>PATCHED</code> for not infected.
|
||||
function check_connficker(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 path = "\\..\\"
|
||||
local error_result
|
||||
status, netpathcanonicalize_result, error_result = msrpc.srvsvc_netpathcanonicalize(smbstate, host.ip, path)
|
||||
|
||||
-- Stop the SMB session
|
||||
msrpc.stop_smb(smbstate)
|
||||
|
||||
if(status == false) then
|
||||
if(string.find(netpathcanonicalize_result, "INVALID_NAME")) then
|
||||
return true, PATCHED
|
||||
elseif(string.find(netpathcanonicalize_result, "UNKNOWN_57") ~= nil and error_result['can_path'] == 0x5c450000) then
|
||||
return true, VULNERABLE
|
||||
else
|
||||
return false, "Unexpected error: " .. netpathcanonicalize_result
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
return true, PATCHED
|
||||
end
|
||||
|
||||
---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
|
||||
@@ -147,13 +212,16 @@ end
|
||||
-- <code>VULNERABLE</code> for vulnerable or <code>PATCHED</code> for not vulnerable. If the check
|
||||
-- was skipped, <code>NOTRUN</code> is returned.
|
||||
function check_winreg_Enum_crash(host)
|
||||
local i, j
|
||||
local elements = {}
|
||||
|
||||
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
|
||||
@@ -195,9 +263,7 @@ action = function(host)
|
||||
status, result = check_ms08_067(host)
|
||||
if(status == false) then
|
||||
if(nmap.debugging() > 0) then
|
||||
return "MS08-067: ERROR: " .. result
|
||||
else
|
||||
return nil
|
||||
response = response .. "MS08-067: ERROR: " .. result .. "\n"
|
||||
end
|
||||
end
|
||||
if(result == VULNERABLE) then
|
||||
@@ -205,31 +271,51 @@ action = function(host)
|
||||
found = true
|
||||
elseif(result == UNKNOWN) then
|
||||
response = response .. "MS08-067: LIKELY VULNERABLE (host stopped responding)\n"
|
||||
elseif(result == NOTRUN) then
|
||||
response = response .. "MS08-067: NOT RUN\n"
|
||||
else
|
||||
if(nmap.verbosity() > 0) then
|
||||
response = response .. "MS08-067: FIXED\n"
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for Connficker
|
||||
status, result = check_connficker(host)
|
||||
if(status == false) then
|
||||
if(nmap.debugging() > 0) then
|
||||
if(result == "NT_STATUS_BAD_NETWORK_NAME") then
|
||||
response = response .. "Connficker: ERROR: Network name not found (required service has crashed)\n"
|
||||
else
|
||||
response = response .. "Connficker: ERROR: " .. result .. "\n"
|
||||
end
|
||||
end
|
||||
else
|
||||
if(result == PATCHED) then
|
||||
response = response .. "Connficker: Likely CLEAN\n"
|
||||
else
|
||||
response = response .. "Connficker: Likely INFECTED\n"
|
||||
found = true
|
||||
end
|
||||
end
|
||||
|
||||
-- Check for a winreg_Enum crash
|
||||
status, result = check_winreg_Enum_crash(host)
|
||||
if(status == false) then
|
||||
if(nmap.debugging() > 0) then
|
||||
return response .. "regsvc DoS: ERROR: " .. result
|
||||
else
|
||||
return nil
|
||||
end
|
||||
end
|
||||
if(result == VULNERABLE) then
|
||||
response = response .. "regsvc DoS: VULNERABLE\n"
|
||||
found = true
|
||||
elseif(result == NOTRUN) then
|
||||
if(nmap.verbosity() > 0) then
|
||||
response = response .. "regsvc DoS: NOT RUN (add --script-args=unsafe=1 to run)\n"
|
||||
response = response .. "regsvc DoS: ERROR: " .. result .. "\n"
|
||||
end
|
||||
else
|
||||
if(nmap.verbosity() > 0) then
|
||||
response = response .. "regsvc DoS: FIXED\n"
|
||||
if(result == VULNERABLE) then
|
||||
response = response .. "regsvc DoS: VULNERABLE\n"
|
||||
found = true
|
||||
elseif(result == NOTRUN) then
|
||||
if(nmap.verbosity() > 0) then
|
||||
response = response .. "regsvc DoS: NOT RUN (add --script-args=unsafe=1 to run)\n"
|
||||
end
|
||||
else
|
||||
if(nmap.verbosity() > 0) then
|
||||
response = response .. "regsvc DoS: FIXED\n"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user