Files
metasploit-gs/modules/auxiliary/analyze/apply_pot.rb
T
h00die 2cccd50160 creds command working
debuggin hashcat aix

remove word normal

get hashcat working on aix

add deprecated jtr_aix

prettying up crack_aix

custom wordlists should include the words themselves

make format transparent to user

aix cleanup, linux working

linux working, database in progress

crack databases working

crack windows working

spaces at eol

spec updates

spec updates

spec working

add version detection

crack_aix fixes and docs

refactoring crack modules

fix syntax error

docs for crackers

markup touchups

osx cracker

jenkins

fix jenkins

remove crypt fix osx for 10.7

doc fixes and osx sha512
2019-05-31 12:18:25 -04:00

166 lines
5.8 KiB
Ruby

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core/auxiliary/password_cracker'
class MetasploitModule < Msf::Auxiliary
include Msf::Auxiliary::PasswordCracker
def initialize
super(
'Name' => 'Apply Pot File To Hashes',
'Description' => %Q{
This module uses a John the Ripper or Hashcat .pot file to crack any password
hashes in the creds database instantly. JtR's --show functionality is used to
help combine all the passwords into an easy to use format.
},
'Author' => ['h00die'],
'License' => MSF_LICENSE
)
deregister_options('ITERATION_TIMEOUT')
deregister_options('CUSTOM_WORDLIST')
deregister_options('KORELOGIC')
deregister_options('MUTATE')
deregister_options('USE_CREDS')
deregister_options('USE_DB_INFO')
deregister_options('USE_DEFAULT_WORDLIST')
deregister_options('USE_ROOT_WORDS')
deregister_options('USE_HOSTNAMES')
end
# Not all hash formats include an 'id' field, which coresponds which db entry
# an item is to its hash. This can be problematic, especially when a username
# is used as a salt. Due to all the variations, we make a small HashLookup
# class to handle all the fields for easier lookup later.
class HashLookup
attr_accessor :db_hash
attr_accessor :jtr_hash
attr_accessor :username
attr_accessor :id
def initialize(db_hash, jtr_hash, username, id)
@db_hash = db_hash
@jtr_hash = jtr_hash
@username = username
@id = id
end
end
def run
cracker = new_john_cracker
lookups = []
# create one massive hash file with all the hashes
hashlist = Rex::Quickfile.new("hashes_tmp")
framework.db.creds(workspace: myworkspace).each do |core|
next if core.private.type == 'Metasploit::Credential::Password'
jtr_hash = hash_to_jtr(core)
hashlist.puts jtr_hash
lookups << HashLookup.new(core.private.data, jtr_hash, core.public, core.id)
end
hashlist.close
cracker.hash_path = hashlist.path
print_status "Hashes Written out to #{hashlist.path}"
cleanup_files = [cracker.hash_path]
# cycle through all hash types we dump asking jtr to show us
# cracked passwords. The advantage to this vs just comparing
# john.pot to the hashes directly is we use jtr to recombine
# lanman, and other assorted nuances
['bcrypt', 'bsdicrypt', 'crypt', 'descrypt', 'lm', 'nt',
'md5crypt', 'mysql', 'mysql-sha1', 'mssql', 'mssql05', 'mssql12',
'oracle', 'oracle11', 'oracle12c', 'dynamic_1506', #oracles
'dynamic_1034' #postgres
].each do |format|
print_status("Checking #{format} hashes against pot file")
cracker.format = format
cracker.each_cracked_password do |password_line|
password_line.chomp!
next if password_line.blank? || password_line.nil?
fields = password_line.split(":")
core_id = nil
case format
when 'descrypt'
next unless fields.count >=3
username = fields.shift
core_id = fields.pop
4.times { fields.pop } # Get rid of extra :
when 'md5crypt', 'descrypt', 'bsdicrypt', 'crypt', 'bcrypt'
next unless fields.count >=7
username = fields.shift
core_id = fields.pop
4.times { fields.pop }
when 'mssql', 'mssql05', 'mssql12', 'mysql', 'mysql-sha1',
'oracle', 'dynamic_1506', 'oracle11', 'oracle12c'
next unless fields.count >=3
username = fields.shift
core_id = fields.pop
when 'dynamic_1506' #oracle H code
next unless fields.count >=3
username = fields.shift
core_id = fields.pop
when 'dynamic_1034' #postgres
next unless fields.count >=2
username = fields.shift
password = fields.join(':')
# unfortunately to match up all the fields we need to pull the hash
# field as well, and it is only available in the pot file.
pot = cracker.pot || cracker.john_pot_file
File.open(pot, 'rb').each do |line|
if line.start_with?('$dynamic_1034$') #postgres format
lookups.each do |l|
pot_hash = line.split(":")[0]
raw_pot_hash = pot_hash.split('$')[2]
if l.username.to_s == username &&
l.jtr_hash == "#{username}:$dynamic_1034$#{raw_pot_hash}" &&
l.db_hash == raw_pot_hash
core_id = l.id
break
end
end
end
end
when 'lm', 'nt'
next unless fields.count >=7
username = fields.shift
core_id = fields.pop
2.times{ fields.pop }
# get the NT and LM hashes
nt_hash = fields.pop
lm_hash = fields.pop
core_id = fields.pop
password = fields.join(':')
if format == 'lm'
if password.blank?
if nt_hash == Metasploit::Credential::NTLMHash::BLANK_NT_HASH
password = ''
else
next
end
end
password = john_lm_upper_to_ntlm(password, nt_hash)
next if password.nil?
end
fields = password.split(':') #for consistency on the following join out of the case
end
unless core_id.nil?
password = fields.join(':')
print_good "#{username}:#{password}"
create_cracked_credential( username: username, password: password, core_id: core_id)
end
end
end
if datastore['DeleteTempFiles']
cleanup_files.each do |f|
File.delete(f)
end
end
end
end