@@ -30,8 +30,9 @@ def initialize
30
30
'Actions' => [
31
31
[ 'john' , { 'Description' => 'Use John the Ripper' } ] ,
32
32
[ 'hashcat' , { 'Description' => 'Use Hashcat' } ] ,
33
+ [ 'auto' , { 'Description' => 'Use either John the Ripper or Hashcat, if both are present, use Hashcat' } ]
33
34
] ,
34
- 'DefaultAction' => 'john ' ,
35
+ 'DefaultAction' => 'auto ' ,
35
36
'Notes' => {
36
37
'Stability' => [ CRASH_SAFE ] ,
37
38
'SideEffects' => [ ] ,
@@ -62,9 +63,11 @@ def half_lm_regex
62
63
def show_command ( cracker_instance )
63
64
return unless datastore [ 'ShowCommand' ]
64
65
65
- if action . name == 'john'
66
+ newaction = getaction ( )
67
+
68
+ if newaction == 'john'
66
69
cmd = cracker_instance . john_crack_command
67
- elsif action . name == 'hashcat'
70
+ elsif newaction == 'hashcat'
68
71
cmd = cracker_instance . hashcat_crack_command
69
72
end
70
73
print_status ( " Cracking Command: #{ cmd . join ( ' ' ) } " )
@@ -96,13 +99,16 @@ def process_cracker_results(results, cred)
96
99
end
97
100
98
101
def check_results ( passwords , results , hash_type , method )
102
+
103
+ newaction = getaction ( )
104
+
99
105
passwords . each do |password_line |
100
106
password_line . chomp!
101
107
next if password_line . blank?
102
108
103
109
fields = password_line . split ( ':' )
104
110
cred = { 'hash_type' => hash_type , 'method' => method }
105
- if action . name == 'john'
111
+ if newaction == 'john'
106
112
# If we don't have an expected minimum number of fields, this is probably not a hash line
107
113
next unless fields . count > 2
108
114
@@ -136,7 +142,7 @@ def check_results(passwords, results, hash_type, method)
136
142
cred [ 'password' ] = john_lm_upper_to_ntlm ( password , nt_hash )
137
143
end
138
144
next if cred [ 'password' ] . nil?
139
- elsif action . name == 'hashcat'
145
+ elsif newaction == 'hashcat'
140
146
next unless fields . count >= 2
141
147
142
148
cred [ 'core_id' ] = fields . shift
@@ -163,6 +169,9 @@ def check_results(passwords, results, hash_type, method)
163
169
end
164
170
165
171
def run
172
+
173
+ newaction = getaction ( )
174
+
166
175
tbl = cracker_results_table
167
176
168
177
# array of hashes in jtr_format in the db, converted to an OR combined regex
@@ -178,7 +187,7 @@ def run
178
187
179
188
# build our job list
180
189
hash_types_to_crack . each do |hash_type |
181
- job = hash_job ( hash_type , action . name )
190
+ job = hash_job ( hash_type , newaction )
182
191
if job . nil?
183
192
print_status ( "No #{ hash_type } found to crack" )
184
193
else
@@ -196,7 +205,7 @@ def run
196
205
# Inner array format: db_id, hash_type, username, password, method_of_crack
197
206
results = [ ]
198
207
199
- cracker = new_password_cracker ( action . name )
208
+ cracker = new_password_cracker ( newaction )
200
209
201
210
# generate our wordlist and close the file handle.
202
211
wordlist = wordlist_file
@@ -220,7 +229,7 @@ def run
220
229
# dupe our original cracker so we can safely change options between each run
221
230
cracker_instance = cracker . dup
222
231
cracker_instance . format = format
223
- if action . name == 'john'
232
+ if newaction == 'john'
224
233
cracker_instance . fork = datastore [ 'FORK' ]
225
234
end
226
235
@@ -231,7 +240,7 @@ def run
231
240
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
232
241
next if job [ 'cred_ids_left_to_crack' ] . empty?
233
242
234
- if action . name == 'john'
243
+ if newaction == 'john'
235
244
print_status "Cracking #{ format } hashes in single mode..."
236
245
cracker_instance . mode_single ( wordlist . path )
237
246
show_command cracker_instance
@@ -274,7 +283,7 @@ def run
274
283
print_status "Cracking #{ format } hashes in wordlist mode..."
275
284
cracker_instance . mode_wordlist ( wordlist . path )
276
285
# Turn on KoreLogic rules if the user asked for it
277
- if action . name == 'john' && datastore [ 'KORELOGIC' ]
286
+ if newaction == 'john' && datastore [ 'KORELOGIC' ]
278
287
cracker_instance . rules = 'KoreLogicRules'
279
288
print_status 'Applying KoreLogic ruleset...'
280
289
end
@@ -299,4 +308,24 @@ def run
299
308
end
300
309
end
301
310
end
311
+
312
+ def getaction
313
+ newaction = action . name
314
+ if action . name == 'auto'
315
+ path = Rex ::FileUtils . find_full_path ( 'hashcat' ) ||
316
+ Rex ::FileUtils . find_full_path ( 'hashcat.exe' )
317
+ if path
318
+ newaction = 'hashcat'
319
+ else
320
+ path = Rex ::FileUtils . find_full_path ( 'john' ) ||
321
+ Rex ::FileUtils . find_full_path ( 'john.exe' )
322
+ if path
323
+ newaction = 'john'
324
+ else
325
+ raise PasswordCrackerNotFoundError , 'No suitable john/hashcat binary was found on the system'
326
+ end
327
+ end
328
+ end
329
+ return newaction
330
+ end
302
331
end
0 commit comments