Skip to content

Commit cf243b5

Browse files
committed
Adds auto option support, updates crack_database.rb accordingly
1 parent f454954 commit cf243b5

File tree

3 files changed

+26
-20
lines changed

3 files changed

+26
-20
lines changed

lib/metasploit/framework/password_crackers/cracker.rb

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ def binary_path
312312
end
313313
raise PasswordCrackerNotFoundError, 'No suitable john/hashcat binary was found on the system' unless path && ::File.file?(path)
314314

315-
path
315+
return path
316316
end
317317
end
318318

@@ -342,6 +342,7 @@ def cracker_version
342342
cmd = binary_path
343343
cmd << (' -V')
344344
end
345+
puts cmd
345346
::IO.popen(cmd, 'rb') do |fd|
346347
fd.each_line do |line|
347348
if cracker == 'john'
@@ -575,11 +576,13 @@ def show_command
575576

576577
def get_hashcat
577578
# Look in the Environment PATH for the hashcat binary
579+
self.cracker = 'hashcat'
578580
Rex::FileUtils.find_full_path('hashcat') ||
579581
Rex::FileUtils.find_full_path('hashcat.exe')
580582
end
581583

582584
def get_john
585+
self.cracker = 'john'
583586
# Look in the Environment PATH for the john binary
584587
Rex::FileUtils.find_full_path('john') ||
585588
Rex::FileUtils.find_full_path('john.exe')

lib/msf/core/auxiliary/password_cracker.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ def new_password_cracker(cracking_application)
8888
rescue Metasploit::Framework::PasswordCracker::PasswordCrackerNotFoundError => e
8989
fail_with(Msf::Module::Failure::BadConfig, e.message)
9090
end
91+
92+
# redefine cracker is action is auto
93+
9194
# throw this to a local variable since it causes a shell out to pull the version
9295
cracker_version = cracker.cracker_version
9396
if cracker.cracker == 'john' && (cracker_version.nil? || !cracker_version.include?('jumbo'))

modules/auxiliary/analyze/crack_databases.rb

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ def initialize
3434
'Actions' => [
3535
['john', { 'Description' => 'Use John the Ripper' }],
3636
['hashcat', { 'Description' => 'Use Hashcat' }],
37+
['auto', { 'Description' => 'Auto-selection of cracker' }]
3738
],
38-
'DefaultAction' => 'john',
39+
'DefaultAction' => 'auto',
3940
'Notes' => {
4041
'Stability' => [CRASH_SAFE],
4142
'SideEffects' => [],
@@ -58,29 +59,29 @@ def initialize
5859
def show_command(cracker_instance)
5960
return unless datastore['ShowCommand']
6061

61-
if action.name == 'john'
62+
if cracker_instance.cracker == 'john'
6263
cmd = cracker_instance.john_crack_command
63-
elsif action.name == 'hashcat'
64+
elsif cracker_instance.cracker == 'hashcat'
6465
cmd = cracker_instance.hashcat_crack_command
6566
end
6667
print_status(" Cracking Command: #{cmd.join(' ')}")
6768
end
6869

69-
def check_results(passwords, results, hash_type, method)
70+
def check_results(passwords, results, hash_type, method, cracker_type)
7071
passwords.each do |password_line|
7172
password_line.chomp!
7273
next if password_line.blank?
7374

7475
fields = password_line.split(':')
7576
cred = { 'hash_type' => hash_type, 'method' => method }
7677

77-
if action.name == 'john'
78+
if cracker_type == 'john'
7879
next unless fields.count >= 3
7980

8081
cred['username'] = fields.shift
8182
cred['core_id'] = fields.pop
8283
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
83-
elsif action.name == 'hashcat'
84+
elsif cracker_type == 'hashcat'
8485
next unless fields.count >= 2
8586

8687
cred['core_id'] = fields.shift
@@ -109,7 +110,8 @@ def check_results(passwords, results, hash_type, method)
109110
end
110111

111112
def run
112-
tbl = tbl = cracker_results_table
113+
tbl = cracker_results_table
114+
cracker = new_password_cracker(action.name)
113115

114116
# array of hashes in jtr_format in the db, converted to an OR combined regex
115117
hash_types_to_crack = []
@@ -128,7 +130,7 @@ def run
128130

129131
# hashcat requires a format we dont have all the data for
130132
# in the current dumper, so this is disabled in module and lib
131-
if action.name == 'john'
133+
if cracker.cracker == 'john'
132134
hash_types_to_crack << 'oracle'
133135
hash_types_to_crack << 'dynamic_1506'
134136
end
@@ -143,7 +145,7 @@ def run
143145

144146
# build our job list
145147
hash_types_to_crack.each do |hash_type|
146-
job = hash_job(hash_type, action.name)
148+
job = hash_job(hash_type, cracker.cracker)
147149
if job.nil?
148150
print_status("No #{hash_type} found to crack")
149151
else
@@ -161,8 +163,6 @@ def run
161163
# Inner array format: db_id, hash_type, username, password, method_of_crack
162164
results = []
163165

164-
cracker = new_password_cracker(action.name)
165-
166166
# generate our wordlist and close the file handle.
167167
wordlist = wordlist_file
168168
unless wordlist
@@ -187,25 +187,25 @@ def run
187187
cracker_instance = cracker.dup
188188
cracker_instance.format = format
189189

190-
if action.name == 'john'
190+
if cracker.cracker == 'john'
191191
cracker_instance.fork = datastore['FORK']
192192
end
193193

194194
# first check if anything has already been cracked so we don't report it incorrectly
195195
print_status "Checking #{format} hashes already cracked..."
196-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT')
196+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT', cracker.cracker)
197197
vprint_good(append_results(tbl, results)) unless results.empty?
198198
job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list
199199
next if job['cred_ids_left_to_crack'].empty?
200200

201-
if action.name == 'john'
201+
if cracker.cracker == 'john'
202202
print_status "Cracking #{format} hashes in single mode..."
203203
cracker_instance.mode_single(wordlist.path)
204204
show_command cracker_instance
205205
cracker_instance.crack do |line|
206206
vprint_status line.chomp
207207
end
208-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Single')
208+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Single', cracker.cracker)
209209
vprint_good(append_results(tbl, results)) unless results.empty?
210210
job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list
211211
next if job['cred_ids_left_to_crack'].empty?
@@ -216,7 +216,7 @@ def run
216216
cracker_instance.crack do |line|
217217
vprint_status line.chomp
218218
end
219-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal')
219+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal', cracker.cracker)
220220
vprint_good(append_results(tbl, results)) unless results.empty?
221221
job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list
222222
next if job['cred_ids_left_to_crack'].empty?
@@ -229,7 +229,7 @@ def run
229229
cracker_instance.crack do |line|
230230
vprint_status line.chomp
231231
end
232-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental')
232+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental', cracker.cracker)
233233
vprint_good(append_results(tbl, results)) unless results.empty?
234234
job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list
235235
next if job['cred_ids_left_to_crack'].empty?
@@ -239,7 +239,7 @@ def run
239239
print_status "Cracking #{format} hashes in wordlist mode..."
240240
cracker_instance.mode_wordlist(wordlist.path)
241241
# Turn on KoreLogic rules if the user asked for it
242-
if action.name == 'john' && datastore['KORELOGIC']
242+
if cracker.cracker == 'john' && datastore['KORELOGIC']
243243
cracker_instance.rules = 'KoreLogicRules'
244244
print_status 'Applying KoreLogic ruleset...'
245245
end
@@ -248,7 +248,7 @@ def run
248248
vprint_status line.chomp
249249
end
250250

251-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist')
251+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist', cracker.cracker)
252252
vprint_good(append_results(tbl, results)) unless results.empty?
253253
job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list
254254
next if job['cred_ids_left_to_crack'].empty?

0 commit comments

Comments
 (0)