1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-15 04:09:01 +00:00

MS06-025:

-- Finished, tested and merged into smb-check-vulns
	-- msrpc.lua contains the code required to interface with the RASRPC interface
This commit is contained in:
drazen
2010-06-12 19:32:50 +00:00
parent e4162e6771
commit 62c2d97f93
2 changed files with 239 additions and 1 deletions

View File

@@ -311,7 +311,7 @@ local function call_function(smbstate, opnum, arguments)
0x18 + string.len(arguments), -- Frag length (0x18 = the size of this data) 0x18 + string.len(arguments), -- Frag length (0x18 = the size of this data)
0x0000, -- Auth length 0x0000, -- Auth length
0x41414141, -- Call ID (I use 'AAAA' because it's easy to recognize) 0x41414141, -- Call ID (I use 'AAAA' because it's easy to recognize)
0x0 + string.len(arguments), -- Alloc hint 0x00000038, -- Alloc hint
0x0000, -- Context ID 0x0000, -- Context ID
opnum, -- Opnum opnum, -- Opnum
arguments arguments
@@ -4347,4 +4347,173 @@ function get_share_info(host, name)
return true, netsharegetinfo_result return true, netsharegetinfo_result
end end
--####################################################################--
--# 1) RRAS RASRPC INTERFACE
--####################################################################--
ROUTER_PATH = "\\router" --also can be reached across "\\srvsvc" pipe in WinXP
RASRPC_UUID = string.char(0x36, 0x00, 0x61, 0x20, 0x22, 0xfa, 0xcf, 0x11, 0x98, 0x23, 0x00, 0xa0, 0xc9, 0x11, 0xe5, 0xdf)
RASRPC_VERSION = 1
--####################################################################--
--# 2) RRAS RASRPC TYPES
--####################################################################--
--####################################################################--
--typedef enum _ReqTypes{
-- REQTYPE_PORTENUM = 21,//Request to enumerate all the port information on the RRAS.
-- REQTYPE_GETINFO = 22,//Request to get information about a specific port on the RRAS.
-- REQTYPE_GETDEVCONFIG = 73,//Request to get device information on the RRAS.
-- REQTYPE_SETDEVICECONFIGINFO = 94,//Request to set device configuration information on RRAS.
-- REQTYPE_GETDEVICECONFIGINFO = 95,//Request to get device configuration information on RRAS.
-- REQTYPE_GETCALLEDID = 105,//Request to get CalledId information for a specific device on RRAS.
-- REQTYPE_SETCALLEDID = 106,//Request to set CalledId information for a specific device on RRAS.
-- REQTYPE_GETNDISWANDRIVERCAPS = 111//Request to get the encryption capabilities of the RRAS.
--} ReqTypes;
--- The <code>ReqTypes</code> enumerations indicate the different types of message requests that can be passed in
--the <code>RB_ReqType</code> field of <code>RequestBuffer</code> structure.
-- @see [MS-RRASM] <code>2.2.1.1.18 ReqTypes</code>
--####################################################################--
RRAS_RegTypes = {}
RRAS_RegTypes['PORTENUM'] = 21
RRAS_RegTypes['GETINFO'] = 22
RRAS_RegTypes['GETDEVCONFIG'] = 73 --this method is vulnerable to ms06-025
RRAS_RegTypes['SETDEVICECONFIGINFO'] = 94
RRAS_RegTypes['GETDEVICECONFIGINFO'] = 95
RRAS_RegTypes['GETCALLEDID'] = 105
RRAS_RegTypes['SETCALLEDID'] = 106
RRAS_RegTypes['GETNDISWANDRIVERCAPS'] = 111
--####################################################################--
--typedef struct _RequestBuffer {
-- DWORD RB_PCBIndex;//A unique identifier for the port.
-- ReqTypes RB_Reqtype;//A ReqTypes enumeration value indicating the request type sent to the server.
-- DWORD RB_Dummy;//MUST be set to the size of the ULONG_PTR on the client.
-- DWORD RB_Done;//MBZ
-- LONGLONG Alignment;//MBZ
-- BYTE RB_Buffer[1];//variable size
--} RequestBuffer;
--- The <code>RequestBuffer</code> is a generic information container used by the <code>RasRpcSubmitRequest</code>
--method to set or retrieve information on RRAS server. This method performs
--serialization of <code>RequestBuffer</code> structure.
-- @return Returns a blob of <code>RequestBuffer</code> structure.
-- @note This structure is not an IDL specification and as such is not translated into NDR.
-- @see [MS-RRASM] <code>2.2.1.2.218 RequestBuffer</code>
--####################################################################--
function RRAS_marshall_RequestBuffer(RB_PCBIndex, RB_ReqType, RB_Buffer)
local rb_blob, RB_Dummy, RB_Done, Alignment
RB_Dummy = 4
RB_Done = 0
Alignment = 0
rb_blob = bin.pack("<IIIILA",
RB_PCBIndex,
RB_ReqType,
RB_Dummy,
RB_Done,
Alignment,
RB_Buffer)
return rb_blob
end
--####################################################################--
--# 3) RRAS RASRPC OPERATIONS
--####################################################################--
local RRAS_DEBUG_LVL = 3 --debug level for rras operations when calling stdnse.print_debug
--####################################################################--
--- RRAS operation numbers.
-- @see [MS-RRASM] <code>3.3.4 Message Processing Events and Sequencing Rules</code>
--####################################################################--
RRAS_Opnums = {}
RRAS_Opnums["RasRpcDeleteEntry"] = 5
RRAS_Opnums["RasRpcGetUserPreferences"] = 9
RRAS_Opnums["RasRpcSetUserPreferences"] = 10
RRAS_Opnums["RasRpcGetSystemDirectory"] = 11
RRAS_Opnums["RasRpcSubmitRequest"] = 12
RRAS_Opnums["RasRpcGetInstalledProtocolsEx"] = 14
RRAS_Opnums["RasRpcGetVersion"] = 15
--####################################################################--
--DWORD RasRpcSubmitRequest(
-- [in] handle_t hServer,//An RPC binding handle. (not send)
-- [in, out, unique, size_is(dwcbBufSize)] PBYTE pReqBuffer,//A pointer to a buffer of size dwcbBufSize.
-- [in] DWORD dwcbBufSize//Size in byte of pReqBuffer.
--);
---The RasRpcSubmitRequest method retrieves or sets the configuration data on RRAS server.
-- @param smbstate The smb object.
-- @param pReqBuffer The buffer MUST be large enough to hold the <code>RequestBuffer</code>
--structure and <code>RequestBuffer.RB_Buffer</code> data. <code>RequestBuffer.RB_Reqtype</code>
--specifies the request type which will be processed by the server and
--<code>RequestBuffer.RB_Buffer</code> specifies the structure specific to <code>RB_Reqtype</code>
--to be processed. <code>RequestBuffer.RB_PCBIndex<code> MUST be set to the unique port identifier
--whose information is sought for <code>ReqTypes REQTYPE_GETINFO</code> and <code>REQTYPE_GETDEVCONFIG</code>.
--For other valid <code>ReqTypes</code>, <code>RequestBuffer.RB_PCBIndex</code> MUST be set to zero.
-- @param dwcbBufSize Integer representing the size of <code>pRegBuffer</code> in bytes.
-- @return (status, result)
--* <code>status == true</code> -> <code>result</code> is a blob that represent a <code>pRegBuffer</code> .
--* <code>status == false</code> -> <code>result</code> is a error message that caused the fuzz.
-- @see [MS-RRASM] <code>3.3.4.5 RasRpcSubmitRequest (Opnum 12)</code>
--####################################################################--
function RRAS_SubmitRequest(smbstate, pReqBuffer, dwcbBufSize)
--sanity check
if(dwcbBufSize == nil) then
dwcbBufSize = string.len(pReqBuffer)
end
--pack the request
local req_blob
--[in, out, unique, size_is(dwcbBufSize) PBYTE pReqBuffer,
req_blob = bin.pack("<IIAA", 0x20000, dwcbBufSize, pReqBuffer, get_pad(pReqBuffer,4)) --unique pointer see samba:ndr_push_unique_ptr
--[in] DWORD dwcbBufSize
req_blob = req_blob .. msrpctypes.marshall_int32(dwcbBufSize)
--call the function
local status, result
status, result = call_function(
smbstate,
RRAS_Opnums["RasRpcSubmitRequest"],
req_blob)
--sanity check
if(status == false) then
stdnse.print_debug(
RRAS_DEBUG_LVL,
"RRAS_SubmitRequest: Call function failed: %s",
result)
return false, result
end
--dissect the reply
local rep_blob
rep_blob = result
return true, rep_blob
end
--####################################################################--
--# UTILITY
--###################################################################--
--####################################################################--
---Makes a pad for alignment
-- @param data Data which needs to be padded for the sake of alignment.
-- @param align Integer representing the alignment boundary.
-- @param pad_byte The value for pad byte.
-- @return Returns the amount of pad calculated by <code>(align-datalen%align)%align</code>.
--####################################################################--
function get_pad(data, align, pad_byte)
pad_byte = pad_byte or "\00"
return string.rep(pad_byte, (align-string.len(data)%align)%align)
end
--####################################################################--
---Generates a random string of the requested length.
--@param length The length of the string to return.
--@param set The set of letters to choose from. Default: ASCII letters and numbers
--@return The random string.
--####################################################################--
function random_crap(length, charset)
charset = charset or "0123456789abcdefghijklmnoprstuvzxwyABCDEFGHIJKLMNOPRSTUVZXWY"
local random_str = ""
for i = 1, length, 1 do
local random = math.random(#charset)
random_str = random_str .. string.sub(charset, random, random)
end
return random_str
end

View File

@@ -397,6 +397,61 @@ local function check_smbv2_dos(host)
return true, PATCHED return true, PATCHED
end 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) 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. If the check
-- was skipped, <code>NOTRUN</code> is returned.
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
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 accessible across SRVSVC pipe
if(status == false) then
return false, err_msg
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, bind_result
end
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)
--sanity check
if(status == false) then
stdnse.print_debug(
3,
"check_ms06_025: RRAS_SubmitRequest failed")
msrpc.stop_smb(smbstate)
if(sr_result == "NT_STATUS_PIPE_BROKEN") then
return true, VULNERABLE
else
return true, PATCHED
end
else
return true, PATHED
end
end
---Returns the appropriate text to display, if any. ---Returns the appropriate text to display, if any.
-- --
--@param check The name of the check; for example, 'ms08-067'. --@param check The name of the check; for example, 'ms08-067'.
@@ -490,6 +545,20 @@ action = function(host)
end end
end end
-- Check for ms06-025
status, result = check_ms06_025(host)
if(status == false) then
table.insert(response, get_response("MS06-025", "ERROR", result, 0, 1))
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))
else
table.insert(response, get_response("MS06-025", "NOT VULNERABLE", nil, 1))
end
end
return stdnse.format_output(true, response) return stdnse.format_output(true, response)
end end