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/analyze/apply_pot.rb
Views: 11780
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##456class MetasploitModule < Msf::Auxiliary7include Msf::Auxiliary::PasswordCracker89def initialize10super(11'Name' => 'Apply Pot File To Hashes',12'Description' => %Q{13This module uses a John the Ripper or Hashcat .pot file to crack any password14hashes in the creds database instantly. JtR's --show functionality is used to15help combine all the passwords into an easy to use format.16},17'Author' => ['h00die'],18'License' => MSF_LICENSE,19'Actions' =>20[21['john', 'Description' => 'Use John the Ripper'],22# ['hashcat', 'Description' => 'Use Hashcat'], # removed for simplicity23],24'DefaultAction' => 'john',25)26deregister_options('ITERATION_TIMEOUT')27deregister_options('CUSTOM_WORDLIST')28deregister_options('KORELOGIC')29deregister_options('MUTATE')30deregister_options('USE_CREDS')31deregister_options('USE_DB_INFO')32deregister_options('USE_DEFAULT_WORDLIST')33deregister_options('USE_ROOT_WORDS')34deregister_options('USE_HOSTNAMES')3536end3738# Not all hash formats include an 'id' field, which corresponds which db entry39# an item is to its hash. This can be problematic, especially when a username40# is used as a salt. Due to all the variations, we make a small HashLookup41# class to handle all the fields for easier lookup later.42class HashLookup43attr_accessor :db_hash44attr_accessor :jtr_hash45attr_accessor :username46attr_accessor :id4748def initialize(db_hash, jtr_hash, username, id)49@db_hash = db_hash50@jtr_hash = jtr_hash51@username = username52@id = id53end54end5556def show_run_command(cracker_instance)57return unless datastore['ShowCommand']58cmd = cracker_instance.show_command59print_status(" Cracking Command: #{cmd.join(' ')}")60end6162def run63cracker = new_password_cracker(action.name)6465lookups = []6667# create one massive hash file with all the hashes68hashlist = Rex::Quickfile.new("hashes_tmp")69framework.db.creds(workspace: myworkspace).each do |core|70next if core.private.type == 'Metasploit::Credential::Password'71jtr_hash = Metasploit::Framework::PasswordCracker::JtR::Formatter.hash_to_jtr(core)72hashlist.puts jtr_hash73lookups << HashLookup.new(core.private.data, jtr_hash, core.public, core.id)74end75hashlist.close76cracker.hash_path = hashlist.path77print_status "Hashes Written out to #{hashlist.path}"78cleanup_files = [cracker.hash_path]7980# cycle through all hash types we dump asking jtr to show us81# cracked passwords. The advantage to this vs just comparing82# john.pot to the hashes directly is we use jtr to recombine83# lanman, and other assorted nuances84['bcrypt', 'bsdicrypt', 'crypt', 'descrypt', 'lm', 'nt',85'md5crypt', 'mysql', 'mysql-sha1', 'mssql', 'mssql05', 'mssql12',86'oracle', 'oracle11', 'oracle12c', 'dynamic_1506', #oracles87'dynamic_1034' #postgres88].each do |format|8990print_status("Checking #{format} hashes against pot file")91cracker.format = format92show_run_command(cracker)93cracker.each_cracked_password.each do |password_line|94password_line.chomp!95next if password_line.blank? || password_line.nil?96fields = password_line.split(":")97core_id = nil98case format99when 'descrypt'100next unless fields.count >=3101username = fields.shift102core_id = fields.pop1034.times { fields.pop } # Get rid of extra :104when 'md5crypt', 'descrypt', 'bsdicrypt', 'crypt', 'bcrypt'105next unless fields.count >=7106username = fields.shift107core_id = fields.pop1084.times { fields.pop }109when 'mssql', 'mssql05', 'mssql12', 'mysql', 'mysql-sha1',110'oracle', 'dynamic_1506', 'oracle11', 'oracle12c'111next unless fields.count >=3112username = fields.shift113core_id = fields.pop114when 'dynamic_1506' #oracle H code115next unless fields.count >=3116username = fields.shift117core_id = fields.pop118when 'dynamic_1034' #postgres119next unless fields.count >=2120username = fields.shift121password = fields.join(':')122# unfortunately to match up all the fields we need to pull the hash123# field as well, and it is only available in the pot file.124pot = cracker.pot || cracker.john_pot_file125126File.open(pot, 'rb').each do |line|127if line.start_with?('$dynamic_1034$') #postgres format128lookups.each do |l|129pot_hash = line.split(":")[0]130raw_pot_hash = pot_hash.split('$')[2]131if l.username.to_s == username &&132l.jtr_hash == "#{username}:$dynamic_1034$#{raw_pot_hash}" &&133l.db_hash == raw_pot_hash134core_id = l.id135break136end137end138end139end140when 'lm', 'nt'141next unless fields.count >=7142username = fields.shift143core_id = fields.pop1442.times{ fields.pop }145# get the NT and LM hashes146nt_hash = fields.pop147lm_hash = fields.pop148core_id = fields.pop149password = fields.join(':')150if format == 'lm'151if password.blank?152if nt_hash == Metasploit::Credential::NTLMHash::BLANK_NT_HASH153password = ''154else155next156end157end158password = john_lm_upper_to_ntlm(password, nt_hash)159next if password.nil?160end161fields = password.split(':') #for consistency on the following join out of the case162end163unless core_id.nil?164password = fields.join(':')165print_good "#{username}:#{password}"166create_cracked_credential( username: username, password: password, core_id: core_id)167end168end169end170if datastore['DeleteTempFiles']171cleanup_files.each do |f|172File.delete(f)173end174end175end176end177178179