@@ -24,8 +24,9 @@ def initialize
24
24
'Actions' => [
25
25
[ 'john' , { 'Description' => 'Use John the Ripper' } ] ,
26
26
[ 'hashcat' , { 'Description' => 'Use Hashcat' } ] ,
27
+ [ 'auto' , { 'Description' => 'Use either John the Ripper or Hashcat, if both are present, use Hashcat' } ]
27
28
] ,
28
- 'DefaultAction' => 'john ' ,
29
+ 'DefaultAction' => 'auto ' ,
29
30
'Notes' => {
30
31
'Stability' => [ CRASH_SAFE ] ,
31
32
'SideEffects' => [ ] ,
@@ -47,23 +48,28 @@ def initialize
47
48
def show_command ( cracker_instance )
48
49
return unless datastore [ 'ShowCommand' ]
49
50
50
- if action . name == 'john'
51
+ newaction = getaction ( )
52
+
53
+ if newaction == 'john'
51
54
cmd = cracker_instance . john_crack_command
52
- elsif action . name == 'hashcat'
55
+ elsif newaction == 'hashcat'
53
56
cmd = cracker_instance . hashcat_crack_command
54
57
end
55
58
print_status ( " Cracking Command: #{ cmd . join ( ' ' ) } " )
56
59
end
57
60
58
61
def check_results ( passwords , results , hash_type , method )
62
+
63
+ newaction = getaction ( )
64
+
59
65
passwords . each do |password_line |
60
66
password_line . chomp!
61
67
next if password_line . blank?
62
68
63
69
fields = password_line . split ( ':' )
64
70
cred = { 'hash_type' => hash_type , 'method' => method }
65
71
# If we don't have an expected minimum number of fields, this is probably not a hash line
66
- if action . name == 'john'
72
+ if newaction == 'john'
67
73
next unless fields . count >= 3
68
74
69
75
cred [ 'username' ] = fields . shift
@@ -72,7 +78,7 @@ def check_results(passwords, results, hash_type, method)
72
78
4 . times { fields . pop } # Get rid of extra :
73
79
end
74
80
cred [ 'password' ] = fields . join ( ':' ) # Anything left must be the password. This accounts for passwords with semi-colons in it
75
- elsif action . name == 'hashcat'
81
+ elsif newaction == 'hashcat'
76
82
next unless fields . count >= 3
77
83
78
84
cred [ 'core_id' ] = fields . shift
@@ -91,6 +97,9 @@ def check_results(passwords, results, hash_type, method)
91
97
end
92
98
93
99
def run
100
+
101
+ newaction = getaction ( )
102
+
94
103
tbl = tbl = cracker_results_table
95
104
96
105
# array of hashes in jtr_format in the db, converted to an OR combined regex
@@ -102,7 +111,7 @@ def run
102
111
103
112
# build our job list
104
113
hash_types_to_crack . each do |hash_type |
105
- job = hash_job ( hash_type , action . name )
114
+ job = hash_job ( hash_type , newaction )
106
115
if job . nil?
107
116
print_status ( "No #{ hash_type } found to crack" )
108
117
else
@@ -120,7 +129,7 @@ def run
120
129
# Inner array format: db_id, hash_type, username, password, method_of_crack
121
130
results = [ ]
122
131
123
- cracker = new_password_cracker ( action . name )
132
+ cracker = new_password_cracker ( newaction )
124
133
125
134
# generate our wordlist and close the file handle.
126
135
wordlist = wordlist_file
@@ -144,7 +153,7 @@ def run
144
153
# dupe our original cracker so we can safely change options between each run
145
154
cracker_instance = cracker . dup
146
155
cracker_instance . format = format
147
- if action . name == 'john'
156
+ if newaction == 'john'
148
157
cracker_instance . fork = datastore [ 'FORK' ]
149
158
end
150
159
@@ -153,7 +162,7 @@ def run
153
162
results = check_results ( cracker_instance . each_cracked_password , results , format , 'Already Cracked/POT' )
154
163
vprint_good ( append_results ( tbl , results ) ) unless results . empty?
155
164
156
- if action . name == 'john'
165
+ if newaction == 'john'
157
166
print_status "Cracking #{ format } hashes in single mode..."
158
167
cracker_instance . mode_single ( wordlist . path )
159
168
show_command cracker_instance
@@ -194,7 +203,7 @@ def run
194
203
print_status "Cracking #{ format } hashes in wordlist mode..."
195
204
cracker_instance . mode_wordlist ( wordlist . path )
196
205
# Turn on KoreLogic rules if the user asked for it
197
- if action . name == 'john' && datastore [ 'KORELOGIC' ]
206
+ if newaction == 'john' && datastore [ 'KORELOGIC' ]
198
207
cracker_instance . rules = 'KoreLogicRules'
199
208
print_status 'Applying KoreLogic ruleset...'
200
209
end
@@ -218,4 +227,24 @@ def run
218
227
end
219
228
end
220
229
end
230
+
231
+ def getaction
232
+ newaction = action . name
233
+ if action . name == 'auto'
234
+ path = Rex ::FileUtils . find_full_path ( 'hashcat' ) ||
235
+ Rex ::FileUtils . find_full_path ( 'hashcat.exe' )
236
+ if path
237
+ newaction = 'hashcat'
238
+ else
239
+ path = Rex ::FileUtils . find_full_path ( 'john' ) ||
240
+ Rex ::FileUtils . find_full_path ( 'john.exe' )
241
+ if path
242
+ newaction = 'john'
243
+ else
244
+ raise PasswordCrackerNotFoundError , 'No suitable john/hashcat binary was found on the system'
245
+ end
246
+ end
247
+ end
248
+ return newaction
249
+ end
221
250
end
0 commit comments