@@ -34,8 +34,9 @@ def initialize
34
34
'Actions' => [
35
35
[ 'john' , { 'Description' => 'Use John the Ripper' } ] ,
36
36
[ 'hashcat' , { 'Description' => 'Use Hashcat' } ] ,
37
+ [ 'auto' , { 'Description' => 'Use either John the Ripper or Hashcat, if both are present, use Hashcat' } ]
37
38
] ,
38
- 'DefaultAction' => 'john ' ,
39
+ 'DefaultAction' => 'auto ' ,
39
40
'Notes' => {
40
41
'Stability' => [ CRASH_SAFE ] ,
41
42
'SideEffects' => [ ] ,
@@ -58,29 +59,34 @@ def initialize
58
59
def show_command ( cracker_instance )
59
60
return unless datastore [ 'ShowCommand' ]
60
61
61
- if action . name == 'john'
62
+ newaction = getaction ( )
63
+
64
+ if newaction == 'john'
62
65
cmd = cracker_instance . john_crack_command
63
- elsif action . name == 'hashcat'
66
+ elsif newaction == 'hashcat'
64
67
cmd = cracker_instance . hashcat_crack_command
65
68
end
66
69
print_status ( " Cracking Command: #{ cmd . join ( ' ' ) } " )
67
70
end
68
71
69
72
def check_results ( passwords , results , hash_type , method )
73
+
74
+ newaction = getaction ( )
75
+
70
76
passwords . each do |password_line |
71
77
password_line . chomp!
72
78
next if password_line . blank?
73
79
74
80
fields = password_line . split ( ':' )
75
81
cred = { 'hash_type' => hash_type , 'method' => method }
76
82
77
- if action . name == 'john'
83
+ if newaction == 'john'
78
84
next unless fields . count >= 3
79
85
80
86
cred [ 'username' ] = fields . shift
81
87
cred [ 'core_id' ] = fields . pop
82
88
cred [ 'password' ] = fields . join ( ':' ) # Anything left must be the password. This accounts for passwords with semi-colons in it
83
- elsif action . name == 'hashcat'
89
+ elsif newaction == 'hashcat'
84
90
next unless fields . count >= 2
85
91
86
92
cred [ 'core_id' ] = fields . shift
@@ -109,6 +115,9 @@ def check_results(passwords, results, hash_type, method)
109
115
end
110
116
111
117
def run
118
+
119
+ newaction = getaction ( )
120
+
112
121
tbl = tbl = cracker_results_table
113
122
114
123
# array of hashes in jtr_format in the db, converted to an OR combined regex
@@ -128,7 +137,7 @@ def run
128
137
129
138
# hashcat requires a format we dont have all the data for
130
139
# in the current dumper, so this is disabled in module and lib
131
- if action . name == 'john'
140
+ if newaction == 'john'
132
141
hash_types_to_crack << 'oracle'
133
142
hash_types_to_crack << 'dynamic_1506'
134
143
end
@@ -143,7 +152,7 @@ def run
143
152
144
153
# build our job list
145
154
hash_types_to_crack . each do |hash_type |
146
- job = hash_job ( hash_type , action . name )
155
+ job = hash_job ( hash_type , newaction )
147
156
if job . nil?
148
157
print_status ( "No #{ hash_type } found to crack" )
149
158
else
@@ -161,7 +170,7 @@ def run
161
170
# Inner array format: db_id, hash_type, username, password, method_of_crack
162
171
results = [ ]
163
172
164
- cracker = new_password_cracker ( action . name )
173
+ cracker = new_password_cracker ( newaction )
165
174
166
175
# generate our wordlist and close the file handle.
167
176
wordlist = wordlist_file
@@ -187,7 +196,7 @@ def run
187
196
cracker_instance = cracker . dup
188
197
cracker_instance . format = format
189
198
190
- if action . name == 'john'
199
+ if newaction == 'john'
191
200
cracker_instance . fork = datastore [ 'FORK' ]
192
201
end
193
202
@@ -198,7 +207,7 @@ def run
198
207
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
199
208
next if job [ 'cred_ids_left_to_crack' ] . empty?
200
209
201
- if action . name == 'john'
210
+ if newaction == 'john'
202
211
print_status "Cracking #{ format } hashes in single mode..."
203
212
cracker_instance . mode_single ( wordlist . path )
204
213
show_command cracker_instance
@@ -239,7 +248,7 @@ def run
239
248
print_status "Cracking #{ format } hashes in wordlist mode..."
240
249
cracker_instance . mode_wordlist ( wordlist . path )
241
250
# Turn on KoreLogic rules if the user asked for it
242
- if action . name == 'john' && datastore [ 'KORELOGIC' ]
251
+ if newaction == 'john' && datastore [ 'KORELOGIC' ]
243
252
cracker_instance . rules = 'KoreLogicRules'
244
253
print_status 'Applying KoreLogic ruleset...'
245
254
end
@@ -263,4 +272,25 @@ def run
263
272
end
264
273
end
265
274
end
275
+
276
+ def getaction
277
+ newaction = action . name
278
+ if action . name == 'auto'
279
+ path = Rex ::FileUtils . find_full_path ( 'hashcat' ) ||
280
+ Rex ::FileUtils . find_full_path ( 'hashcat.exe' )
281
+ if path
282
+ newaction = 'hashcat'
283
+ else
284
+ path = Rex ::FileUtils . find_full_path ( 'john' ) ||
285
+ Rex ::FileUtils . find_full_path ( 'john.exe' )
286
+ if path
287
+ newaction = 'john'
288
+ else
289
+ raise PasswordCrackerNotFoundError , 'No suitable john/hashcat binary was found on the system'
290
+ end
291
+ end
292
+ end
293
+ return newaction
294
+ end
295
+
266
296
end
0 commit comments