Skip to content

Commit 3e915e5

Browse files
committed
Merge branch 'staging/electro-release' into bug/MSP-10715/import-security-issues
Update deps Conflicts: Gemfile Gemfile.lock
2 parents 8fda4ee + ea72a7e commit 3e915e5

File tree

9 files changed

+325
-155
lines changed

9 files changed

+325
-155
lines changed

Gemfile.lock

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ PATH
55
activesupport (>= 3.0.0, < 4.0.0)
66
bcrypt
77
json
8+
metasploit-model (~> 0.26.1)
89
meterpreter_bins (= 0.0.6)
910
msgpack
1011
nokogiri
@@ -82,7 +83,7 @@ GEM
8283
msgpack (0.5.8)
8384
multi_json (1.0.4)
8485
network_interface (0.0.1)
85-
nokogiri (1.6.2.1)
86+
nokogiri (1.6.3.1)
8687
mini_portile (= 0.6.0)
8788
packetfu (1.1.9)
8889
pcaprub (0.11.3)
@@ -118,9 +119,9 @@ GEM
118119
rspec-collection_matchers (1.0.0)
119120
rspec-expectations (>= 2.99.0.beta1)
120121
rspec-core (2.99.1)
121-
rspec-expectations (2.99.1)
122+
rspec-expectations (2.99.2)
122123
diff-lcs (>= 1.1.3, < 2.0)
123-
rspec-mocks (2.99.1)
124+
rspec-mocks (2.99.2)
124125
rspec-rails (2.99.0)
125126
actionpack (>= 3.0)
126127
activemodel (>= 3.0)
@@ -132,13 +133,13 @@ GEM
132133
rspec-mocks (~> 2.99.0)
133134
rubyntlm (0.4.0)
134135
rubyzip (1.1.6)
135-
shoulda-matchers (2.6.1)
136+
shoulda-matchers (2.6.2)
136137
activesupport (>= 3.0.0)
137138
simplecov (0.5.4)
138139
multi_json (~> 1.0.3)
139140
simplecov-html (~> 0.5.3)
140141
simplecov-html (0.5.3)
141-
slop (3.5.0)
142+
slop (3.6.0)
142143
sprockets (2.2.2)
143144
hike (~> 1.2)
144145
multi_json (~> 1.0)

lib/metasploit/framework.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
require 'bcrypt'
1010
require 'json'
1111
require 'msgpack'
12+
require 'metasploit/model'
1213
require 'nokogiri'
1314
require 'packetfu'
1415
# railties has not autorequire defined
@@ -43,4 +44,4 @@ def self.root
4344
@root
4445
end
4546
end
46-
end
47+
end

lib/metasploit/framework/credential.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ class Credential
1212
# @return [Boolean] Whether BOTH a public and private are required
1313
# (defaults to `true`)
1414
attr_accessor :paired
15+
# @!attribute parent
16+
# @return [Object] the parent object that had .to_credential called on it to create this object
17+
attr_accessor :parent
1518
# @!attribute private
1619
# The private credential component (e.g. username)
1720
#

lib/metasploit/framework/login_scanner/base.rb

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ def each_credential
8383
# This could be a Credential object, or a Credential Core, or an Attempt object
8484
# so make sure that whatever it is, we end up with a Credential.
8585
credential = raw_cred.to_credential
86+
credential.parent = raw_cred
8687

8788
if credential.realm.present? && self.class::REALM_KEY.present?
8889
credential.realm_key = self.class::REALM_KEY
@@ -129,7 +130,14 @@ def scan!
129130
successful_users = Set.new
130131

131132
each_credential do |credential|
132-
next if successful_users.include?(credential.public)
133+
# For Pro bruteforce Reuse and Guess we need to note that we skipped an attempt.
134+
if successful_users.include?(credential.public)
135+
if credential.parent.respond_to?(:skipped)
136+
credential.parent.skipped = true
137+
credential.parent.save!
138+
end
139+
next
140+
end
133141

134142
result = attempt_login(credential)
135143
result.freeze

lib/msf/core/rpc/v10/rpc_db.rb

Lines changed: 52 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ module RPC
44
class RPC_Db < RPC_Base
55

66
private
7+
8+
include Metasploit::Credential::Creation
9+
710
def db
811
self.framework.db.active
912
end
@@ -15,6 +18,21 @@ def find_workspace(wspace = nil)
1518
self.framework.db.workspace
1619
end
1720

21+
def fix_cred_options(opts)
22+
new_opts = fix_options(opts)
23+
24+
# Convert some of are data back to symbols
25+
if new_opts[:origin_type]
26+
new_opts[:origin_type] = new_opts[:origin_type].to_sym
27+
end
28+
29+
if new_opts[:private_type]
30+
new_opts[:private_type] = new_opts[:private_type].to_sym
31+
end
32+
33+
new_opts
34+
end
35+
1836
def fix_options(opts)
1937
newopts = {}
2038
opts.each do |k,v|
@@ -88,6 +106,40 @@ def init_db_opts_workspace(xopts)
88106

89107
public
90108

109+
def rpc_create_cracked_credential(xopts)
110+
opts = fix_cred_options(xopts)
111+
create_credential(opts)
112+
end
113+
114+
def rpc_create_credential(xopts)
115+
opts = fix_cred_options(xopts)
116+
core = create_credential(opts)
117+
118+
ret = {
119+
username: core.public.try(:username),
120+
private: core.private.try(:data),
121+
private_type: core.private.try(:type),
122+
realm_value: core.realm.try(:value),
123+
realm_key: core.realm.try(:key)
124+
}
125+
126+
if opts[:last_attempted_at] && opts[:status]
127+
opts[:core] = core
128+
opts[:last_attempted_at] = opts[:last_attempted_at].to_datetime
129+
login = create_credential_login(opts)
130+
131+
ret[:host] = login.service.host.address,
132+
ret[:sname] = login.service.name
133+
ret[:status] = login.status
134+
end
135+
ret
136+
end
137+
138+
def rpc_invalidate_login(xopts)
139+
opts = fix_cred_options(xopts)
140+
invalidate_login(opts)
141+
end
142+
91143
def rpc_hosts(xopts)
92144
::ActiveRecord::Base.connection_pool.with_connection {
93145
opts, wspace = init_db_opts_workspace(xopts)
@@ -490,33 +542,6 @@ def rpc_notes(xopts)
490542
}
491543
end
492544

493-
def rpc_report_auth_info(xopts)
494-
::ActiveRecord::Base.connection_pool.with_connection {
495-
opts, wspace = init_db_opts_workspace(xopts)
496-
res = self.framework.db.report_auth_info(opts)
497-
return { :result => 'success' } if(res)
498-
{ :result => 'failed' }
499-
}
500-
end
501-
502-
def rpc_get_auth_info(xopts)
503-
::ActiveRecord::Base.connection_pool.with_connection {
504-
opts, wspace = init_db_opts_workspace(xopts)
505-
ret = {}
506-
ret[:auth_info] = []
507-
# XXX: This method doesn't exist...
508-
ai = self.framework.db.get_auth_info(opts)
509-
ai.each do |i|
510-
info = {}
511-
i.each do |k,v|
512-
info[k.to_sym] = v
513-
end
514-
ret[:auth_info] << info
515-
end
516-
ret
517-
}
518-
end
519-
520545
def rpc_get_ref(name)
521546
::ActiveRecord::Base.connection_pool.with_connection {
522547
db_check
@@ -828,42 +853,6 @@ def rpc_loots(xopts)
828853
}
829854
end
830855

831-
# requires host, port, user, pass, ptype, and active
832-
def rpc_report_cred(xopts)
833-
::ActiveRecord::Base.connection_pool.with_connection {
834-
opts, wspace = init_db_opts_workspace(xopts)
835-
res = framework.db.find_or_create_cred(opts)
836-
return { :result => 'success' } if res
837-
{ :result => 'failed' }
838-
}
839-
end
840-
841-
#right now workspace is the only option supported
842-
def rpc_creds(xopts)
843-
::ActiveRecord::Base.connection_pool.with_connection {
844-
opts, wspace = init_db_opts_workspace(xopts)
845-
limit = opts.delete(:limit) || 100
846-
offset = opts.delete(:offset) || 0
847-
848-
ret = {}
849-
ret[:creds] = []
850-
::Mdm::Cred.find(:all, :include => {:service => :host}, :conditions => ["hosts.workspace_id = ?",
851-
framework.db.workspace.id ], :limit => limit, :offset => offset).each do |c|
852-
cred = {}
853-
cred[:host] = c.service.host.address if(c.service.host)
854-
cred[:updated_at] = c.updated_at.to_i
855-
cred[:port] = c.service.port
856-
cred[:proto] = c.service.proto
857-
cred[:sname] = c.service.name
858-
cred[:type] = c.ptype
859-
cred[:user] = c.user
860-
cred[:pass] = c.pass
861-
cred[:active] = c.active
862-
ret[:creds] << cred
863-
end
864-
ret
865-
}
866-
end
867856

868857
def rpc_import_data(xopts)
869858
::ActiveRecord::Base.connection_pool.with_connection {

0 commit comments

Comments
 (0)