Skip to content

Commit d3f6faa

Browse files
committed
Adjust cracker modules
1 parent cf243b5 commit d3f6faa

File tree

7 files changed

+107
-74
lines changed

7 files changed

+107
-74
lines changed

lib/metasploit/framework/password_crackers/cracker.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,10 @@ def initialize(attributes = {})
119119
public_send("#{attribute}=", value)
120120
end
121121
end
122+
123+
def get_type
124+
self.cracker
125+
end
122126

123127
# This method takes a {framework.db.cred.private.jtr_format} (string), and
124128
# returns the string number associated to the hashcat format
@@ -573,7 +577,7 @@ def show_command
573577
end
574578
cmd << hash_path
575579
end
576-
580+
577581
def get_hashcat
578582
# Look in the Environment PATH for the hashcat binary
579583
self.cracker = 'hashcat'

modules/auxiliary/analyze/crack_aix.rb

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,9 @@ def initialize
2525
'Actions' => [
2626
['john', { 'Description' => 'Use John the Ripper' }],
2727
['hashcat', { 'Description' => 'Use Hashcat' }],
28+
['auto', { 'Description' => 'Auto-selection of cracker' ]}
2829
],
29-
'DefaultAction' => 'john',
30+
'DefaultAction' => 'auto',
3031
'Notes' => {
3132
'Stability' => [CRASH_SAFE],
3233
'SideEffects' => [],
@@ -45,9 +46,9 @@ def initialize
4546
def show_command(cracker_instance)
4647
return unless datastore['ShowCommand']
4748

48-
if action.name == 'john'
49+
if @cracker_type == 'john'
4950
cmd = cracker_instance.john_crack_command
50-
elsif action.name == 'hashcat'
51+
elsif @cracker_type == 'hashcat'
5152
cmd = cracker_instance.hashcat_crack_command
5253
end
5354
print_status(" Cracking Command: #{cmd.join(' ')}")
@@ -63,12 +64,12 @@ def check_results(passwords, results, hash_type, method)
6364
next unless fields.count >= 3
6465

6566
cred = { 'hash_type' => hash_type, 'method' => method }
66-
if action.name == 'john'
67+
if @cracker_type == 'john'
6768
cred['username'] = fields.shift
6869
cred['core_id'] = fields.pop
6970
4.times { fields.pop } # Get rid of extra :
7071
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
71-
elsif action.name == 'hashcat'
72+
elsif @cracker_type == 'hashcat'
7273
cred['core_id'] = fields.shift
7374
cred['hash'] = fields.shift
7475
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
@@ -86,13 +87,19 @@ def check_results(passwords, results, hash_type, method)
8687

8788
def run
8889
tbl = tbl = cracker_results_table
90+
cracker = new_password_cracker(action.name)
91+
if action.name == 'auto'
92+
@cracker_type = cracker.get_type
93+
else
94+
@cracker_type = action.name
95+
end
8996

9097
hash_types_to_crack = ['descrypt']
9198
jobs_to_do = []
9299

93100
# build our job list
94101
hash_types_to_crack.each do |hash_type|
95-
job = hash_job(hash_type, action.name)
102+
job = hash_job(hash_type, @cracker_type)
96103
if job.nil?
97104
print_status("No #{hash_type} found to crack")
98105
else
@@ -110,8 +117,6 @@ def run
110117
# Inner array format: db_id, hash_type, username, password, method_of_crack
111118
results = []
112119

113-
cracker = new_password_cracker(action.name)
114-
115120
# generate our wordlist and close the file handle. max length of DES is 8
116121
wordlist = wordlist_file(8)
117122
unless wordlist
@@ -136,7 +141,7 @@ def run
136141
cracker_instance = cracker.dup
137142
cracker_instance.format = format
138143

139-
if action.name == 'john'
144+
if @cracker_type == 'john'
140145
cracker_instance.fork = datastore['FORK']
141146
end
142147

@@ -147,7 +152,7 @@ def run
147152
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
148153
next if job['cred_ids_left_to_crack'].empty?
149154

150-
if action.name == 'john'
155+
if @cracker_type == 'john'
151156
print_status "Cracking #{format} hashes in single mode..."
152157
cracker_instance.mode_single(wordlist.path)
153158
show_command cracker_instance
@@ -189,7 +194,7 @@ def run
189194
print_status "Cracking #{format} hashes in wordlist mode..."
190195
cracker_instance.mode_wordlist(wordlist.path)
191196
# Turn on KoreLogic rules if the user asked for it
192-
if action.name == 'john' && datastore['KORELOGIC']
197+
if @cracker_type == 'john' && datastore['KORELOGIC']
193198
cracker_instance.rules = 'KoreLogicRules'
194199
print_status 'Applying KoreLogic ruleset...'
195200
end

modules/auxiliary/analyze/crack_databases.rb

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -59,29 +59,29 @@ def initialize
5959
def show_command(cracker_instance)
6060
return unless datastore['ShowCommand']
6161

62-
if cracker_instance.cracker == 'john'
62+
if @cracker_type == 'john'
6363
cmd = cracker_instance.john_crack_command
64-
elsif cracker_instance.cracker == 'hashcat'
64+
elsif @cracker_type == 'hashcat'
6565
cmd = cracker_instance.hashcat_crack_command
6666
end
6767
print_status(" Cracking Command: #{cmd.join(' ')}")
6868
end
6969

70-
def check_results(passwords, results, hash_type, method, cracker_type)
70+
def check_results(passwords, results, hash_type, method)
7171
passwords.each do |password_line|
7272
password_line.chomp!
7373
next if password_line.blank?
7474

7575
fields = password_line.split(':')
7676
cred = { 'hash_type' => hash_type, 'method' => method }
7777

78-
if cracker_type == 'john'
78+
if @cracker_type == 'john'
7979
next unless fields.count >= 3
8080

8181
cred['username'] = fields.shift
8282
cred['core_id'] = fields.pop
8383
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
84-
elsif cracker_type == 'hashcat'
84+
elsif @cracker_type == 'hashcat'
8585
next unless fields.count >= 2
8686

8787
cred['core_id'] = fields.shift
@@ -112,6 +112,11 @@ def check_results(passwords, results, hash_type, method, cracker_type)
112112
def run
113113
tbl = cracker_results_table
114114
cracker = new_password_cracker(action.name)
115+
if action.name == 'auto'
116+
@cracker_type = cracker.get_type
117+
else
118+
@cracker_type = action.name
119+
end
115120

116121
# array of hashes in jtr_format in the db, converted to an OR combined regex
117122
hash_types_to_crack = []
@@ -130,7 +135,7 @@ def run
130135

131136
# hashcat requires a format we dont have all the data for
132137
# in the current dumper, so this is disabled in module and lib
133-
if cracker.cracker == 'john'
138+
if @cracker_type == 'john'
134139
hash_types_to_crack << 'oracle'
135140
hash_types_to_crack << 'dynamic_1506'
136141
end
@@ -187,25 +192,25 @@ def run
187192
cracker_instance = cracker.dup
188193
cracker_instance.format = format
189194

190-
if cracker.cracker == 'john'
195+
if @cracker_type == 'john'
191196
cracker_instance.fork = datastore['FORK']
192197
end
193198

194199
# first check if anything has already been cracked so we don't report it incorrectly
195200
print_status "Checking #{format} hashes already cracked..."
196-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT', cracker.cracker)
201+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT')
197202
vprint_good(append_results(tbl, results)) unless results.empty?
198203
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
199204
next if job['cred_ids_left_to_crack'].empty?
200205

201-
if cracker.cracker == 'john'
206+
if @cracker_type == 'john'
202207
print_status "Cracking #{format} hashes in single mode..."
203208
cracker_instance.mode_single(wordlist.path)
204209
show_command cracker_instance
205210
cracker_instance.crack do |line|
206211
vprint_status line.chomp
207212
end
208-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Single', cracker.cracker)
213+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Single')
209214
vprint_good(append_results(tbl, results)) unless results.empty?
210215
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
211216
next if job['cred_ids_left_to_crack'].empty?
@@ -216,7 +221,7 @@ def run
216221
cracker_instance.crack do |line|
217222
vprint_status line.chomp
218223
end
219-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal', cracker.cracker)
224+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal')
220225
vprint_good(append_results(tbl, results)) unless results.empty?
221226
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
222227
next if job['cred_ids_left_to_crack'].empty?
@@ -229,7 +234,7 @@ def run
229234
cracker_instance.crack do |line|
230235
vprint_status line.chomp
231236
end
232-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental', cracker.cracker)
237+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental')
233238
vprint_good(append_results(tbl, results)) unless results.empty?
234239
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
235240
next if job['cred_ids_left_to_crack'].empty?
@@ -239,7 +244,7 @@ def run
239244
print_status "Cracking #{format} hashes in wordlist mode..."
240245
cracker_instance.mode_wordlist(wordlist.path)
241246
# Turn on KoreLogic rules if the user asked for it
242-
if cracker.cracker == 'john' && datastore['KORELOGIC']
247+
if @cracker_type == 'john' && datastore['KORELOGIC']
243248
cracker_instance.rules = 'KoreLogicRules'
244249
print_status 'Applying KoreLogic ruleset...'
245250
end
@@ -248,7 +253,7 @@ def run
248253
vprint_status line.chomp
249254
end
250255

251-
results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist', cracker.cracker)
256+
results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist')
252257
vprint_good(append_results(tbl, results)) unless results.empty?
253258
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
254259
next if job['cred_ids_left_to_crack'].empty?

modules/auxiliary/analyze/crack_linux.rb

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,9 @@ def initialize
3232
'Actions' => [
3333
['john', { 'Description' => 'Use John the Ripper' }],
3434
['hashcat', { 'Description' => 'Use Hashcat' }],
35+
['auto', { 'Description' => 'Auto-selection of cracker' }]
3536
],
36-
'DefaultAction' => 'john',
37+
'DefaultAction' => 'auto',
3738
'Notes' => {
3839
'Stability' => [CRASH_SAFE],
3940
'SideEffects' => [],
@@ -58,9 +59,9 @@ def initialize
5859
def show_command(cracker_instance)
5960
return unless datastore['ShowCommand']
6061

61-
if action.name == 'john'
62+
if @cracker_type == 'john'
6263
cmd = cracker_instance.john_crack_command
63-
elsif action.name == 'hashcat'
64+
elsif @cracker_type == 'hashcat'
6465
cmd = cracker_instance.hashcat_crack_command
6566
end
6667
print_status(" Cracking Command: #{cmd.join(' ')}")
@@ -74,14 +75,14 @@ def check_results(passwords, results, hash_type, method)
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 # If we don't have an expected minimum number of fields, this is probably not a hash line
7980

8081
cred['username'] = fields.shift
8182
cred['core_id'] = fields.pop
8283
4.times { fields.pop } # Get rid of extra :
8384
cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it
84-
elsif action.name == 'hashcat'
85+
elsif @cracker_type == 'hashcat'
8586
next unless fields.count >= 2 # If we don't have an expected minimum number of fields, this is probably not a hash line
8687

8788
cred['core_id'] = fields.shift
@@ -100,7 +101,13 @@ def check_results(passwords, results, hash_type, method)
100101
end
101102

102103
def run
103-
tbl = tbl = cracker_results_table
104+
tbl = cracker_results_table
105+
cracker = new_password_cracker(action.name)
106+
if action.name == 'auto'
107+
@cracker_type = cracker.get_type
108+
else
109+
@cracker_type = action.name
110+
end
104111

105112
# array of hashes in jtr_format in the db, converted to an OR combined regex
106113
hash_types_to_crack = []
@@ -115,7 +122,7 @@ def run
115122

116123
# build our job list
117124
hash_types_to_crack.each do |hash_type|
118-
job = hash_job(hash_type, action.name)
125+
job = hash_job(hash_type, @cracker_type)
119126
if job.nil?
120127
print_status("No #{hash_type} found to crack")
121128
else
@@ -133,8 +140,6 @@ def run
133140
# Inner array format: db_id, hash_type, username, password, method_of_crack
134141
results = []
135142

136-
cracker = new_password_cracker(action.name)
137-
138143
# generate our wordlist and close the file handle.
139144
wordlist = wordlist_file
140145
unless wordlist
@@ -158,7 +163,7 @@ def run
158163
cracker_instance = cracker.dup
159164
cracker_instance.format = format
160165

161-
if action.name == 'john'
166+
if @cracker_type == 'john'
162167
cracker_instance.fork = datastore['FORK']
163168
end
164169

@@ -169,7 +174,7 @@ def run
169174
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
170175
next if job['cred_ids_left_to_crack'].empty?
171176

172-
if action.name == 'john'
177+
if @cracker_type == 'john'
173178
print_status "Cracking #{format} hashes in single mode..."
174179
cracker_instance.mode_single(wordlist.path)
175180
show_command cracker_instance
@@ -211,7 +216,7 @@ def run
211216
print_status "Cracking #{format} hashes in wordlist mode..."
212217
cracker_instance.mode_wordlist(wordlist.path)
213218
# Turn on KoreLogic rules if the user asked for it
214-
if action.name == 'john' && datastore['KORELOGIC']
219+
if @cracker_type == 'john' && datastore['KORELOGIC']
215220
cracker_instance.rules = 'KoreLogicRules'
216221
print_status 'Applying KoreLogic ruleset...'
217222
end

0 commit comments

Comments
 (0)