Skip to content

Commit 533d0be

Browse files
committed
Merge remote-tracking branch 'upstream/staging/electro-release' into staging/electro-release
2 parents a4e5c36 + 7a49f21 commit 533d0be

File tree

13 files changed

+194
-275
lines changed

13 files changed

+194
-275
lines changed

.yardopts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
--exclude \.ut\.rb/
44
--exclude \.ts\.rb/
55
--files CONTRIBUTING.md,COPYING,HACKING,LICENSE
6+
app/**/*.rb
67
lib/msf/**/*.rb
8+
lib/metasploit/**/*.rb
79
lib/rex/**/*.rb
810
plugins/**/*.rb

Gemfile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ group :db do
77
# Needed for Msf::DbManager
88
gem 'activerecord', '>= 3.0.0', '< 4.0.0'
99
# Metasploit::Credential database models
10-
gem 'metasploit-credential', '~> 0.7.8'
10+
gem 'metasploit-credential', '>= 0.7.10.pre.core.pre.search', '< 0.8'
1111
# Database models shared between framework and Pro.
12-
gem 'metasploit_data_models', '>= 0.18.0', '< 0.19'
12+
gem 'metasploit_data_models', '~> 0.19'
1313
# Needed for module caching in Mdm::ModuleDetails
1414
gem 'pg', '>= 0.11'
1515
end

Gemfile.lock

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ GEM
4141
i18n (~> 0.6, >= 0.6.4)
4242
multi_json (~> 1.0)
4343
arel (3.0.3)
44+
arel-helpers (2.0.0)
45+
activerecord (>= 3.1.0, < 5)
4446
bcrypt (3.1.7)
4547
builder (3.0.4)
4648
coderay (1.1.0)
@@ -58,18 +60,19 @@ GEM
5860
json (1.8.1)
5961
metasploit-concern (0.1.1)
6062
activesupport (~> 3.0, >= 3.0.0)
61-
metasploit-credential (0.7.8)
63+
metasploit-credential (0.7.10.pre.core.pre.search)
6264
metasploit-concern (~> 0.1.0)
6365
metasploit-model (>= 0.25.6)
64-
metasploit_data_models (>= 0.18.0.pre.compatibility, < 0.19)
66+
metasploit_data_models (~> 0.19)
6567
pg
6668
rubyntlm
6769
rubyzip (~> 1.1)
6870
metasploit-model (0.25.6)
6971
activesupport
70-
metasploit_data_models (0.18.0)
72+
metasploit_data_models (0.19.0)
7173
activerecord (>= 3.2.13, < 4.0.0)
7274
activesupport
75+
arel-helpers
7376
metasploit-concern (~> 0.1.0)
7477
metasploit-model (>= 0.25.1, < 0.26)
7578
pg
@@ -156,9 +159,9 @@ DEPENDENCIES
156159
factory_girl (>= 4.1.0)
157160
factory_girl_rails
158161
fivemat (= 1.2.1)
159-
metasploit-credential (~> 0.7.8)
162+
metasploit-credential (>= 0.7.10.pre.core.pre.search, < 0.8)
160163
metasploit-framework!
161-
metasploit_data_models (>= 0.18.0, < 0.19)
164+
metasploit_data_models (~> 0.19)
162165
network_interface (~> 0.0.1)
163166
pcaprub
164167
pg (>= 0.11)
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
require 'metasploit/framework/credential'
2+
3+
module Metasploit
4+
module Framework
5+
6+
# This class is responsible for taking datastore options from the snmp_login module
7+
# and yielding appropriate {Metasploit::Framework::Credential}s to the {Metasploit::Framework::LoginScanner::SNMP}.
8+
# This one has to be different from {credentialCollection} as it will only have a {Metasploit::Framework::Credential#public}
9+
# It may be slightly confusing that the attribues are called password and pass_file, because this is what the legacy
10+
# module used. However, community Strings are now considered more to be public credentials than private ones.
11+
class CommunityStringCollection
12+
# @!attribute pass_file
13+
# Path to a file containing passwords, one per line
14+
# @return [String]
15+
attr_accessor :pass_file
16+
17+
# @!attribute password
18+
# @return [String]
19+
attr_accessor :password
20+
21+
# @!attribute prepended_creds
22+
# List of credentials to be tried before any others
23+
#
24+
# @see #prepend_cred
25+
# @return [Array<Credential>]
26+
attr_accessor :prepended_creds
27+
28+
# @option opts [String] :pass_file See {#pass_file}
29+
# @option opts [String] :password See {#password}
30+
# @option opts [Array<Credential>] :prepended_creds ([]) See {#prepended_creds}
31+
def initialize(opts = {})
32+
opts.each do |attribute, value|
33+
public_send("#{attribute}=", value)
34+
end
35+
self.prepended_creds ||= []
36+
end
37+
38+
# Combines all the provided credential sources into a stream of {Credential}
39+
# objects, yielding them one at a time
40+
#
41+
# @yieldparam credential [Metasploit::Framework::Credential]
42+
# @return [void]
43+
def each
44+
begin
45+
if pass_file.present?
46+
pass_fd = File.open(pass_file, 'r:binary')
47+
pass_fd.each_line do |line|
48+
line.chomp!
49+
yield Metasploit::Framework::Credential.new(public: line, paired: false)
50+
end
51+
end
52+
53+
if password.present?
54+
yield Metasploit::Framework::Credential.new(public: password, paired: false)
55+
end
56+
57+
ensure
58+
pass_fd.close if pass_fd && !pass_fd.closed?
59+
end
60+
end
61+
62+
# Add {Credential credentials} that will be yielded by {#each}
63+
#
64+
# @see prepended_creds
65+
# @param cred [Credential]
66+
# @return [self]
67+
def prepend_cred(cred)
68+
prepended_creds.unshift cred
69+
self
70+
end
71+
72+
end
73+
end
74+
end

lib/metasploit/framework/credential.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ def to_s
7878
end
7979

8080
def ==(other)
81-
other.public == self.public && other.private == self.private && other.realm == self.realm
81+
other.respond_to?(:public) && other.public == self.public &&
82+
other.respond_to?(:private) && other.private == self.private &&
83+
other.respond_to?(:realm) && other.realm == self.realm
8284
end
8385

8486
def to_credential

lib/metasploit/framework/jtr/cracker.rb

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ def crack_command
119119

120120
if config.present?
121121
cmd << ( "--config=" + config )
122+
else
123+
cmd << ( "--config=" + john_config_file )
122124
end
123125

124126
if pot.present?
@@ -162,6 +164,13 @@ def each_cracked_password
162164
end
163165
end
164166

167+
# This method returns the path to a default john.conf file.
168+
#
169+
# @return [String] the path to the default john.conf file
170+
def john_config_file
171+
::File.join( ::Msf::Config.data_directory, "john", "confs", "john.conf" )
172+
end
173+
165174
# This method returns the path to a default john.pot file.
166175
#
167176
# @return [String] the path to the default john.pot file
@@ -189,6 +198,8 @@ def show_command
189198

190199
if config
191200
cmd << "--config=#{config}"
201+
else
202+
cmd << ( "--config=" + john_config_file )
192203
end
193204

194205
cmd << hash_path
@@ -199,11 +210,11 @@ def show_command
199210
# This method tries to identify the correct version of the pre-shipped
200211
# JtR binaries to use based on the platform.
201212
#
202-
# @return [NilClass] if the correct bianry could not be determined
213+
# @return [NilClass] if the correct binary could not be determined
203214
# @return [String] the path to the selected binary
204215
def select_shipped_binary
205216
cpuinfo_base = ::File.join(Msf::Config.data_directory, "cpuinfo")
206-
runpath = nil
217+
run_path = nil
207218
if File.directory?(cpuinfo_base)
208219
data = nil
209220

@@ -215,11 +226,11 @@ def select_shipped_binary
215226
end
216227
case data
217228
when /sse2/
218-
run_path ||= "run.win32.sse2/john.exe"
229+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.win32.sse2", "john.exe")
219230
when /mmx/
220-
run_path ||= "run.win32.mmx/john.exe"
231+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.win32.mmx", "john.exe")
221232
else
222-
run_path ||= "run.win32.any/john.exe"
233+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.win32.any", "john.exe")
223234
end
224235
when /x86_64-linux/
225236
fname = "#{cpuinfo_base}/cpuinfo.ia64.bin"
@@ -229,9 +240,9 @@ def select_shipped_binary
229240
end
230241
case data
231242
when /mmx/
232-
run_path ||= "run.linux.x64.mmx/john"
243+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.linux.x64.mmx", "john")
233244
else
234-
run_path ||= "run.linux.x86.any/john"
245+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.linux.x86.any", "john")
235246
end
236247
when /i[\d]86-linux/
237248
fname = "#{cpuinfo_base}/cpuinfo.ia32.bin"
@@ -241,15 +252,15 @@ def select_shipped_binary
241252
end
242253
case data
243254
when /sse2/
244-
run_path ||= "run.linux.x86.sse2/john"
255+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.linux.x86.sse2", "john")
245256
when /mmx/
246-
run_path ||= "run.linux.x86.mmx/john"
257+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.linux.x86.mmx", "john")
247258
else
248-
run_path ||= "run.linux.x86.any/john"
259+
run_path ||= ::File.join(Msf::Config.data_directory, "john", "run.linux.x86.any", "john")
249260
end
250261
end
251262
end
252-
runpath
263+
run_path
253264
end
254265

255266

lib/metasploit/framework/login_scanner/http.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,8 @@ def set_sane_defaults
9696
self.connection_timeout ||= 20
9797
self.max_send_size = 0 if self.max_send_size.nil?
9898
self.send_delay = 0 if self.send_delay.nil?
99+
self.uri = '/' if self.uri.blank?
100+
self.method = 'GET' if self.method.blank?
99101

100102
# Note that this doesn't cover the case where ssl is unset and
101103
# port is something other than a default. In that situtation,

lib/metasploit/framework/login_scanner/mysql.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def attempt_login(credential)
7878
# This method sets the sane defaults for things
7979
# like timeouts and TCP evasion options
8080
def set_sane_defaults
81-
self.connection_timeout || 30
81+
self.connection_timeout ||= 30
8282
self.port ||= DEFAULT_PORT
8383
self.max_send_size ||= 0
8484
self.send_delay ||= 0

lib/msf/core/auxiliary/jtr.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ def initialize(info = {})
4141

4242
end
4343

44+
# @param pwd [String] Password recovered from cracking an LM hash
45+
# @param hash [String] NTLM hash for this password
46+
# @return [String] `pwd` converted to the correct case to match the
47+
# given NTLM hash
48+
# @return [nil] if no case matches the NT hash. This can happen when
49+
# `pwd` came from a john run that only cracked half of the LM hash
4450
def john_lm_upper_to_ntlm(pwd, hash)
4551
pwd = pwd.upcase
4652
hash = hash.upcase

modules/auxiliary/analyze/jtr_crack_fast.rb

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ def initialize
3030
def run
3131
cracker = new_john_cracker
3232

33-
#generate our wordlist and close the file handle
33+
# generate our wordlist and close the file handle
3434
wordlist = wordlist_file
3535
wordlist.close
3636
print_status "Wordlist file written out to #{wordlist.path}"
@@ -53,10 +53,10 @@ def run
5353
end
5454

5555
if format == 'lm'
56-
print_status "Cracking #{format} hashes in incremental mode (LanMan)..."
56+
print_status "Cracking #{format} hashes in incremental mode (All4)..."
5757
cracker_instance.rules = nil
5858
cracker_instance.wordlist = nil
59-
cracker_instance.incremental = 'LanMan'
59+
cracker_instance.incremental = 'All4'
6060
cracker_instance.crack do |line|
6161
print_status line.chomp
6262
end
@@ -98,6 +98,12 @@ def run
9898
end
9999
end
100100
password = john_lm_upper_to_ntlm(password, nt_hash)
101+
# password can be nil if the hash is broken (i.e., the NT and
102+
# LM sides don't actually match) or if john was only able to
103+
# crack one half of the LM hash. In the latter case, we'll
104+
# have a line like:
105+
# username:???????WORD:...:...:::
106+
next if password.nil?
101107
end
102108

103109
print_good "#{username}:#{password}:#{core_id}"

0 commit comments

Comments
 (0)