1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188
|
local msrpc = require "msrpc"
local nmap = require "nmap"
local smb = require "smb"
local string = require "string"
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 https://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
-- <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
|