diff --git a/nselib/msrpc.lua b/nselib/msrpc.lua
index a7db422d9..eb6e6e866 100644
--- a/nselib/msrpc.lua
+++ b/nselib/msrpc.lua
@@ -4417,7 +4417,7 @@ end
--####################################################################--
--# 3) RRAS RASRPC OPERATIONS
--####################################################################--
-local RRAS_DEBUG_LVL = 3 --debug level for rras operations when calling stdnse.print_debug
+local RRAS_DEBUG_LVL = 2 --debug level for rras operations when calling stdnse.print_debug
--####################################################################--
--- RRAS operation numbers.
@@ -4466,6 +4466,9 @@ function RRAS_SubmitRequest(smbstate, pReqBuffer, dwcbBufSize)
req_blob = req_blob .. msrpctypes.marshall_int32(dwcbBufSize)
--call the function
local status, result
+ stdnse.print_debug(
+ RRAS_DEBUG_LVL,
+ "RRAS_SubmitRequest: Calling...")
status, result = call_function(
smbstate,
RRAS_Opnums["RasRpcSubmitRequest"],
@@ -4478,12 +4481,157 @@ function RRAS_SubmitRequest(smbstate, pReqBuffer, dwcbBufSize)
result)
return false, result
end
+ stdnse.print_debug(
+ RRAS_DEBUG_LVL,
+ "RRAS_SubmitRequest: Returned successfully")
--dissect the reply
local rep_blob
rep_blob = result
return true, rep_blob
end
+--####################################################################--
+--# 1) DNS SERVER MANAGEMENT SERVICE INTERFACE
+--####################################################################--
+DNSSERVER_UUID_STR = "50abc2a4-574d-40b3-9d66-ee4fd5fba076"
+DNSSERVER_UUID = string.char(0xa4, 0xc2,0xab, 0x50, 0x4d, 0x57, 0xb3, 0x40, 0x9d, 0x66, 0xee, 0x4f, 0xd5, 0xfb, 0xa0, 0x76)
+DNSSERVER_PATH = "\\DNSSERVER"
+DNSSERVER_VERSION = 5
+
+--####################################################################--
+--# 2) DNS SERVER MANAGEMENT SERVICE TYPES
+--####################################################################--
+---The list of names that are used in (name, value) pairs in DNS Server
+--Configuration information is given below.
+-- @see [MS-DNSP] 3.1.1.1 DNS Server Configuration Information
+DNSSERVER_ConfInfo =
+ {
+ DNSSERVER_IntProp = {},
+ DNSSERVER_AddrArrProp = {},
+ DNSSERVER_StrProp = {},
+ DNSSERVER_StrLstProp = {}
+ }
+
+--####################################################################--
+--# 3) DNS SERVER MANAGEMENT SERVICE OPERATIONS
+--####################################################################--
+local DNSSERVER_DEBUG_LVL = 2 --debug level for dnsserver operations when calling stdnse.print_debug
+
+--####################################################################--
+--- DNSSERVER operation numbers.
+-- @see [MS-DNSP] 3.1.4 Message Processing Events and Sequencing Rules
+--####################################################################--
+DNSSERVER_Opnums = {}
+DNSSERVER_Opnums['R_DnssrvOperation'] = 0
+DNSSERVER_Opnums['R_DnssrvQuery'] = 1
+DNSSERVER_Opnums['R_DnssrvComplexOperation'] = 2
+DNSSERVER_Opnums['R_DnssrvEnumRecords'] = 3
+DNSSERVER_Opnums['R_DnssrvUpdateRecord'] = 4
+DNSSERVER_Opnums['R_DnssrvOperation2'] = 5
+DNSSERVER_Opnums['R_DnssrvQuery2'] = 6
+DNSSERVER_Opnums['R_DnssrvComplexOperation2'] = 7
+DNSSERVER_Opnums['R_DnssrvEnumRecords2'] = 8
+DNSSERVER_Opnums['R_DnssrvUpdateRecord2'] = 9
+
+--####################################################################--
+--[[
+LONG R_DnssrvQuery(
+ [in, unique, string] LPCWSTR pwszServerName,
+ [in, unique, string] LPCSTR pszZone,
+ [in, unique, string] LPCSTR pszOperation,
+ [out] PDWORD pdwTypeId,
+ [out, switch_is(*pdwTypeId)] DNSSRV_RPC_UNION* ppData);
+--]]
+---Issues type specific information queries to server. This method is
+--obsoleted by R_DnssrvQuery2.
+-- @param smbstate The smb object.
+-- @param server_name String that designates a fully qualified domain
+--name of the target server. The server MUST ignore this value.
+-- @param zone String that designates the name of the zone to be queried.
+--For operations specific to a particular zone, this field MUST contain
+--the name of the zone. For all other operations, this field MUST be nil.
+-- @param operation String that designates the name of the operation to
+--be performed on the server. These are two sets of allowed values for
+--pszOperation:
+--* zone == nil -> see DNSSERVER_ConfInfo table.
+--* zone == "some_zone" -> see DNSSERVER_ZoneInfo table.
+-- @return (status, result)
+--* status == true ->
+--that indicates the type of result['data'].
+--** result['data'] - A DNSSRV_RPC_UNION blob that contains a
+--** result['type_id'] - Integer that on success contains a value of type DNS_RPC_TYPEID
+--data-structure as indicated by result['type_id'].
+--* status == false ->
+--** result - Is a error message that caused the fuzz.
+-- @see [MS-DNSP] 3.1.4.2 R_DnssrvQuery (Opnum 1)
+--####################################################################--
+function DNSSERVER_Query(smbstate, server_name, zone, operation)
+ local status
+ --call
+ local req_blob, srv_name_utf16, zone_ascii, operation_ascii
+ --[in, unique, string] LPCWSTR pwszServerName,
+ local unique_ptr
+ unique_ptr = 0x00020000
+ srv_name_utf16 = msrpctypes.string_to_unicode(server_name, true)
+ req_blob = bin.pack("VULNERABLE for vulnerable or PATCHED for not vulnerable. If the check
--- was skipped, NOTRUN is returned. If the service is not active then NOTUP
+--@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
@@ -437,6 +442,7 @@ function check_ms06_025(host)
msrpc.RRAS_RegTypes['GETDEVCONFIG'],
msrpc.random_crap(3000))
status, sr_result = msrpc.RRAS_SubmitRequest(smbstate, req)
+ msrpc.stop_smb(smbstate)
--sanity check
if(status == false) then
stdnse.print_debug(
@@ -448,11 +454,61 @@ function check_ms06_025(host)
return true, PATCHED
end
else
- msrpc.stop_smb(smbstate)
return true, PATHED
end
end
+---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)
+--* status == false -> result == NOTUP which designates
+--that the targeted Dns Server RPC service is not active.
+--* status == true ->
+-- ** result == VULNERABLE for vulnerable.
+-- ** result == PATCHED for not vulnerable.
+-- ** result == NOTRUN if check skipped.
+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
+ return false, NOTUP
+ end
+ --bind to DNSSERVER service
+ local bind_result
+ status, bind_result = msrpc.bind(smbstate, msrpc.DNSSERVER_UUID, msrpc.DNSSERVER_VERSION)
+ if(status == false) then
+ msrpc.stop_smb(smbstate)
+ stdnse.print_debug(
+ msrpc.DNSSERVER_DEBUG_LVL,
+ "DNSSERVER_Query: Bind failed: %s",
+ bind_result)
+ return false, NOTUP
+ 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.print_debug(
+ 3,
+ "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
+
---Returns the appropriate text to display, if any.
--
--@param check The name of the check; for example, 'ms08-067'.
@@ -548,19 +604,41 @@ action = function(host)
-- 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))
+ if(status == false) then
+ if(result == NOTUP) then
+ table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1))
+ else
+ table.insert(response, get_response("MS06-025", "ERROR", result, 0, 1))
+ end
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))
elseif(result == NOTUP) then
- table.insert(response, get_response("MS06-025", "NO SERVICE", "the vulnerable service is inactive", 1))
+ table.insert(response, get_response("MS06-025", "NO SERVICE", "the Ras RPC service is inactive", 1))
else
table.insert(response, get_response("MS06-025", "NOT VULNERABLE", nil, 1))
end
end
+
+ -- Check for ms07-029
+ status, result = check_ms07_029(host)
+ if(status == false) then
+ if(result == NOTUP) then
+ table.insert(response, get_response("MS07-029", "NO SERVICE", "the Dns Server RPC service is inactive", 1))
+ else
+ table.insert(response, get_response("MS07-029", "ERROR", result, 0, 1))
+ end
+ else
+ if(result == VULNERABLE) then
+ table.insert(response, get_response("MS07-029", "VULNERABLE", nil, 0))
+ elseif(result == NOTRUN) then
+ table.insert(response, get_response("MS07-029", "CHECK DISABLED", "remove 'safe=1' argument to run", 1))
+ else
+ table.insert(response, get_response("MS07-029", "NOT VULNERABLE", nil, 1))
+ end
+ end
return stdnse.format_output(true, response)
end