diff --git a/modules/auxiliary/analyze/jtr_crack_fast.rb b/modules/auxiliary/analyze/jtr_crack_fast.rb index 0c281b27b3..7fcaacc21d 100644 --- a/modules/auxiliary/analyze/jtr_crack_fast.rb +++ b/modules/auxiliary/analyze/jtr_crack_fast.rb @@ -5,6 +5,7 @@ require 'msf/core' +require 'msf/core/auxiliary/jtr' class Metasploit3 < Msf::Auxiliary @@ -27,132 +28,96 @@ class Metasploit3 < Msf::Auxiliary end def run - wordlist = Rex::Quickfile.new("jtrtmp") - hashlist = Rex::Quickfile.new("jtrtmp") + cracker = new_john_cracker - begin - # Seed the wordlist with usernames, passwords, and hostnames - seed = [] + #generate our wordlist and close the file handle + wordlist = wordlist_file + wordlist.close + print_status "Wordlist file written out to #{wordlist.path}" + cracker.wordlist = wordlist.path + cracker.hash_path = hash_file - myworkspace.hosts.find(:all).each {|o| seed << john_expand_word( o.name ) if o.name } - myworkspace.creds.each do |o| - seed << john_expand_word( o.user ) if o.user - seed << john_expand_word( o.pass ) if (o.pass and o.ptype !~ /hash/) + ['lm','nt'].each do |format| + # dupe our original cracker so we can safely change options between each run + cracker_instance = cracker.dup + cracker_instance.format = format + print_status "Cracking #{format} hashes in normal wordlist mode..." + cracker_instance.crack do |line| + print_status line.chomp end - # Grab any known passwords out of the john.pot file - john_cracked_passwords.values {|v| seed << v } - - # Write the seed file - wordlist.write( seed.flatten.uniq.join("\n") + "\n" ) - - print_status("Seeded the password database with #{seed.length} words...") - - # Append the standard JtR wordlist as well - ::File.open(john_wordlist_path, "rb") do |fd| - wordlist.write fd.read(fd.stat.size) + print_status "Cracking #{format} hashes in single mode..." + cracker_instance.rules = 'single' + cracker_instance.crack do |line| + print_status line.chomp end - # Close the wordlist to prevent sharing violations (windows) - wordlist.close - - # Create a PWDUMP style input file for SMB Hashes - smb_hashes = myworkspace.creds.select{|x| x.ptype == "smb_hash" } - smb_hashes.each do |cred| - hashlist.write( "cred_#{cred[:id]}:#{cred[:id]}:#{cred[:pass]}:::\n" ) - end - hashlist.close - - if smb_hashes.length > 0 - cracked_ntlm = {} - cracked_lm = {} - added = [] - - john_crack(hashlist.path, :wordlist => datastore['Wordlist'], :format => 'lm') - john_crack(hashlist.path, :wordlist => datastore['Wordlist'], :format => 'nt') - - # Crack this in LANMAN format using wordlist mode with tweaked rules - john_crack(hashlist.path, :wordlist => wordlist.path, :rules => 'single', :format => 'lm') - - # Crack this in LANMAN format using various incremntal modes - john_crack(hashlist.path, :incremental => "All4", :format => 'lm') - john_crack(hashlist.path, :incremental => "Digits5", :format => 'lm') - - # Parse cracked passwords and permute LANMAN->NTLM as needed - cracked = john_show_passwords(hashlist.path, 'lm') - cracked[:users].each_pair do |k,v| - next if v == "" - next if (v[0,7] == "???????" or v[7,7] == "???????") - next if not k =~ /^cred_(\d+)/m - cid = $1.to_i - - cracked_lm[k] = v - - cred_find = smb_hashes.select{|x| x[:id] == cid} - next if cred_find.length == 0 - - cred = cred_find.first - ntlm = cred.pass.split(":", 2).last - done = john_lm_upper_to_ntlm(v, ntlm) - cracked_ntlm[k] = done if done - end - - # Append any cracked values to the wordlist - tfd = ::File.open(wordlist.path, "ab") - cracked_lm.values.each {|w| if not added.include?(w); tfd.write( w + "\n" ); added << w; end } - cracked_ntlm.values.each {|w| if not added.include?(w); tfd.write( w + "\n" ); added << w; end } - tfd.close - - # Crack this in NTLM format - john_crack(hashlist.path, :wordlist => wordlist.path, :rules => 'single', :format => 'nt') - - # Crack this in NTLM format using various incremntal modes - john_crack(hashlist.path, :incremental => "All4", :format => 'nt') - john_crack(hashlist.path, :incremental => "Digits5", :format => 'nt') - - # Parse cracked passwords - cracked = john_show_passwords(hashlist.path, 'nt') - cracked[:users].each_pair do |k,v| - next if cracked_ntlm[k] - cracked_ntlm[k] = v - end - - # Append any cracked values to the wordlist - tfd = ::File.open(wordlist.path, "ab") - cracked_ntlm.values.each {|w| if not added.include?(w); tfd.write( w + "\n" ); added << w; end } - tfd.close - - # Store the cracked results based on user_id => cred.id - cracked_ntlm.each_pair do |k,v| - next if not k =~ /^cred_(\d+)/m - cid = $1.to_i - - cred_find = smb_hashes.select{|x| x[:id] == cid} - next if cred_find.length == 0 - cred = cred_find.first - next if cred.user.to_s.strip.length == 0 - - print_good("Cracked: #{cred.user}:#{v} (#{cred.service.host.address}:#{cred.service.port})") - report_auth_info( - :host => cred.service.host, - :service => cred.service, - :user => cred.user, - :pass => v, - :type => "password", - :source_id => cred[:id], - :source_type => 'cracked' - ) + if format == 'lm' + print_status "Cracking #{format} hashes in incremental mode (LanMan)..." + cracker_instance.rules = nil + cracker_instance.wordlist = nil + cracker_instance.incremental = 'LanMan' + cracker_instance.crack do |line| + print_status line.chomp end end - # XXX: Enter other hash types here (shadow, etc) + print_status "Cracking #{format} hashes in incremental mode (Digits)..." + cracker_instance.rules = nil + cracker_instance.wordlist = nil + cracker_instance.incremental = 'Digits' + cracker_instance.crack do |line| + print_status line.chomp + end - rescue ::Timeout::Error - ensure - wordlist.close rescue nil - hashlist.close rescue nil - ::File.unlink(wordlist.path) rescue nil - ::File.unlink(hashlist.path) rescue nil + print_status "Cracked Passwords this run:" + cracker_instance.each_cracked_password do |password_line| + password_line.chomp! + next if password_line.blank? + + fields = password_line.split(":") + # If we don't have an expected minimum number of fields, this is probably not a hash line + next unless fields.count >=7 + username = fields.shift + core_id = fields.pop + + # pop off dead space here + 2.times{ fields.pop } + + # get the NT and LM hashes + nt_hash = fields.pop + lm_hash = 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) + end + + print_good "#{username}:#{password}:#{core_id}" + create_cracked_credential( username: username, password: password, core_id: core_id) + end end end + + def hash_file + hashlist = Rex::Quickfile.new("hashes_tmp") + Metasploit::Credential::NTLMHash.joins(:cores).where(metasploit_credential_cores: { workspace_id: myworkspace.id } ).each do |hash| + hash.cores.each do |core| + user = core.public.username + hash_string = "#{hash.data}" + id = core.id + hashlist.puts "#{user}:#{id}:#{hash_string}:::#{id}" + end + end + hashlist.close + print_status "Hashes Written out to #{hashlist.path}" + hashlist.path + end end diff --git a/modules/auxiliary/analyze/jtr_mssql_fast.rb b/modules/auxiliary/analyze/jtr_mssql_fast.rb index faee4ff6c3..56c88b67bc 100644 --- a/modules/auxiliary/analyze/jtr_mssql_fast.rb +++ b/modules/auxiliary/analyze/jtr_mssql_fast.rb @@ -54,16 +54,8 @@ class Metasploit3 < Msf::Auxiliary print_status line.chomp end - print_status "Cracking #{format} hashes in incremental mode (All4)..." - cracker_instance.rules = nil - cracker_instance.wordlist = nil - cracker_instance.incremental = 'All4' - cracker_instance.crack do |line| - print_status line.chomp - end - - print_status "Cracking #{format} hashes in incremental mode (Digits5)..." - cracker_instance.incremental = 'Digits5' + print_status "Cracking #{format} hashes in incremental mode (Digits)..." + cracker_instance.incremental = 'Digits' cracker_instance.crack do |line| print_status line.chomp end @@ -92,7 +84,7 @@ class Metasploit3 < Msf::Auxiliary @formats << hash.jtr_format hash.cores.each do |core| user = core.public.username - hash_string = "0x#{hash.data}" + hash_string = "#{hash.data}" id = core.id hashlist.puts "#{user}:#{hash_string}:#{id}:" end diff --git a/modules/auxiliary/scanner/mssql/mssql_hashdump.rb b/modules/auxiliary/scanner/mssql/mssql_hashdump.rb index 72a771179a..d8af493858 100644 --- a/modules/auxiliary/scanner/mssql/mssql_hashdump.rb +++ b/modules/auxiliary/scanner/mssql/mssql_hashdump.rb @@ -132,7 +132,7 @@ class Metasploit3 < Msf::Auxiliary module_fullname: self.fullname, origin_type: :service, private_type: :nonreplayable_hash, - private_data: row[1], + private_data: "0x#{row[1]}", username: row[0], jtr_format: hashtype }