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 for vulnerabilities:
* MS06-025, a Windows Ras 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.
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 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.
]]
---
--@usage
-- nmap --script smb-vuln-ms06-025.nse -p445
-- sudo nmap -sU -sS --script smb-vuln-ms06-025.nse -p U:137,T:139
--
--@output
-- Host script results:
-- | smb-check-vulns:
-- |_ MS06-025: NO SERVICE (the Ras RPC service is inactive)
--
-- @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"
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
local INFECTED2 = 6
local CLEAN = 7
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.
-- ** result == NOTRUN
if check skipped.
function check_ms06_025(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
--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 = 'Vulnerability in Routing and Remote Access Could Allow Remote Code Execution (MS06-025)',
state = vulns.STATE.NOT_VULN,
description = [[
Buffer overflow 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
-- table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1))
vuln_table.state = vulns.STATE.NOT_VULN
else
-- table.insert(response, get_response("MS06-025", "ERROR", result, 0, 1))
vuln_table.state = vulns.STATE.NOT_VULN
end
else
if(result == VULNERABLE) then
-- table.insert(response, get_response("MS06-025", "VULNERABLE", nil, 0))
vuln_table.state = vulns.STATE.VULN
elseif(result == NOTUP) then
-- table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1))
vuln_table.state = vulns.STATE.NOT_VULN
elseif(result == NOTRUN) then
vuln_table.state = vulns.STATE.LIKELY_VULN
vuln_table.check_results = "CHECK DISABLED. Add '--script-args=unsafe=1' to run"
else
-- table.insert(response, get_response("MS06-025", "NOT VULNERABLE", nil, 1))
vuln_table.state = vulns.STATE.NOT_VULN
end
end
return vuln_report:make_output(vuln_table)
end