metasploit-credential 0.13.10 → 0.13.11
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/lib/metasploit/credential/creation.rb +2 -2
- data/lib/metasploit/credential/exporter/core.rb +7 -1
- data/lib/metasploit/credential/importer/core.rb +19 -6
- data/lib/metasploit/credential/version.rb +1 -1
- data/spec/dummy/config/database.yml +11 -11
- data/spec/factories/metasploit/credential/importer/cores.rb +28 -22
- data/spec/lib/metasploit/credential/exporter/core_spec.rb +24 -17
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ODI2ZjA2Nzg2ODU2YmRlNDlmODA5N2UzYTcyNmVlM2FlMjQ1MjdkYQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
YmNjNWJkM2UyMDVkYzMwZTQxODU3YTRiMThhMjA1NGIwYjJjODNjMg==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
Mjc3ODk2NTk3Mjg3NzZkODc0YzM4MmE1YTE5OTYxNzE1MDNiMjIxMGJjMmZl
|
10
|
+
Y2FhODdlOTllZThlOGMwZDhmNThhMDFlOWEzZTI4NDNmYjMzMTVjOWE5NjVk
|
11
|
+
YTk0YjcyZWNlZmUyZmEyNWViMTE1MGFmMzE1MjMzMmIzM2VjN2U=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
ZTYzMzIzMTNmNGNlODU4NjU4ZTVhNmEzMTU5N2EyNWFkOTgyZWVmNWEyNzQ3
|
14
|
+
YzhlY2IxYjU3OGVjNjFiOTcwZGFlNzY5Y2NiOTI3YTI5M2E0OWM0MDZmMTEw
|
15
|
+
ZmI2YTVjZWI4NjA0NGM4MDc2YjNkYTBmZjA2NmNkM2NlMmJhMDg=
|
@@ -208,10 +208,10 @@ module Metasploit
|
|
208
208
|
opts[:task_id] ||= self[:task].record.id
|
209
209
|
end
|
210
210
|
|
211
|
-
access_level = opts.fetch(:access_level, nil)
|
212
211
|
core = opts.fetch(:core)
|
212
|
+
access_level = opts.fetch(:access_level, nil)
|
213
213
|
last_attempted_at = opts.fetch(:last_attempted_at, nil)
|
214
|
-
status = opts.fetch(:status)
|
214
|
+
status = opts.fetch(:status, Metasploit::Model::Login::Status::UNTRIED)
|
215
215
|
|
216
216
|
login_object = nil
|
217
217
|
retry_transaction do
|
@@ -122,6 +122,9 @@ class Metasploit::Credential::Exporter::Core
|
|
122
122
|
# The hashes returned by this method will contain credentials for
|
123
123
|
# networked devices which may or may not successfully authenticate to those
|
124
124
|
# devices.
|
125
|
+
# Note that the order of columns here must match the order in
|
126
|
+
# Metasploit::Credential::Importer::Core::VALID_LONG_CSV_HEADERS or
|
127
|
+
# the headers and row values will be mismatched and break import.
|
125
128
|
# @param login [Metasploit::Credential::Login]
|
126
129
|
# @return [Hash]
|
127
130
|
def line_for_login(login)
|
@@ -130,7 +133,10 @@ class Metasploit::Credential::Exporter::Core
|
|
130
133
|
host_address: login.service.host.address,
|
131
134
|
service_port: login.service.port,
|
132
135
|
service_name: login.service.try(:name),
|
133
|
-
service_protocol: login.service.proto
|
136
|
+
service_protocol: login.service.proto,
|
137
|
+
status: login.status,
|
138
|
+
access_level: login.access_level,
|
139
|
+
last_attempted_at: login.last_attempted_at
|
134
140
|
})
|
135
141
|
end
|
136
142
|
|
@@ -21,7 +21,12 @@ class Metasploit::Credential::Importer::Core
|
|
21
21
|
BLANK_TOKEN = "<BLANK>"
|
22
22
|
|
23
23
|
# Valid headers for a CSV containing heterogenous {Metasploit::Credential::Private} types and values for {Metasploit::Credential::Realm}
|
24
|
-
VALID_LONG_CSV_HEADERS = [:username, :private_type, :private_data,
|
24
|
+
VALID_LONG_CSV_HEADERS = [:username, :private_type, :private_data,
|
25
|
+
:realm_key, :realm_value, :host_address,
|
26
|
+
:service_port, :service_name,
|
27
|
+
:service_protocol, :status, :access_level,
|
28
|
+
:last_attempted_at
|
29
|
+
]
|
25
30
|
|
26
31
|
# Valid headers for a "short" CSV containing only data for {Metasploit::Credential::Public} and {Metasploit::Credential::Private} objects
|
27
32
|
VALID_SHORT_CSV_HEADERS = [:username, :private_data]
|
@@ -107,10 +112,15 @@ class Metasploit::Credential::Importer::Core
|
|
107
112
|
private_data = row['private_data'].present? ? row['private_data'] : ''
|
108
113
|
|
109
114
|
# Host and Service information for Logins
|
110
|
-
host_address
|
111
|
-
service_port
|
112
|
-
service_protocol
|
113
|
-
service_name
|
115
|
+
host_address = row['host_address']
|
116
|
+
service_port = row['service_port']
|
117
|
+
service_protocol = row['service_protocol']
|
118
|
+
service_name = row['service_name']
|
119
|
+
# These were not initially included in the export, so handle
|
120
|
+
# legacy cases:
|
121
|
+
access_level = row['access_level'].present? ? row['access_level'] : ''
|
122
|
+
last_attempted_at = row['last_attempted_at'].present? ? row['last_attempted_at'] : ''
|
123
|
+
status = row['status'].present? ? row['status'] : ''
|
114
124
|
|
115
125
|
|
116
126
|
if realms[realm_value].nil?
|
@@ -140,13 +150,16 @@ class Metasploit::Credential::Importer::Core
|
|
140
150
|
if host_address.present? && service_port.present? && service_protocol.present?
|
141
151
|
login_opts = {
|
142
152
|
core: core,
|
143
|
-
status: Metasploit::Model::Login::Status::UNTRIED, # don't trust creds on import
|
144
153
|
address: host_address,
|
145
154
|
port: service_port,
|
146
155
|
protocol: service_protocol,
|
147
156
|
workspace_id: workspace.id,
|
148
157
|
service_name: service_name.present? ? service_name : ""
|
149
158
|
}
|
159
|
+
login_opts[:last_attempted_at] = last_attempted_at unless status.blank?
|
160
|
+
login_opts[:status] = status unless status.blank?
|
161
|
+
login_opts[:access_level] = access_level unless access_level.blank?
|
162
|
+
|
150
163
|
create_credential_login(login_opts)
|
151
164
|
end
|
152
165
|
end
|
@@ -7,7 +7,7 @@ module Metasploit
|
|
7
7
|
# The minor version number, scoped to the {MAJOR} version number.
|
8
8
|
MINOR = 13
|
9
9
|
# The patch number, scoped to the {MINOR} version number.
|
10
|
-
PATCH =
|
10
|
+
PATCH = 11
|
11
11
|
|
12
12
|
# The full version string, including the {MAJOR}, {MINOR}, {PATCH}, and optionally, the {PRERELEASE} in the
|
13
13
|
# {http://semver.org/spec/v2.0.0.html semantic versioning v2.0.0} format.
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# Please only use postgresql bound to a TCP port.
|
2
|
-
|
2
|
+
development: &pgsql
|
3
3
|
adapter: postgresql
|
4
|
-
|
5
|
-
password: pass123
|
4
|
+
database: metasploit_credential_development
|
6
5
|
host: localhost
|
7
6
|
port: 5432
|
8
|
-
pool:
|
7
|
+
pool: 5
|
9
8
|
timeout: 5
|
10
9
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
10
|
+
# Warning: The database defined as "test" will be erased and
|
11
|
+
# re-generated from your development database when you run "rake".
|
12
|
+
# Do not set this db to the same as development or production.
|
13
|
+
#
|
14
|
+
# Note also, sqlite3 is totally unsupported by Metasploit now.
|
15
15
|
test:
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
<<: *pgsql
|
17
|
+
database: metasploit_credential_test
|
18
|
+
|
@@ -1,20 +1,26 @@
|
|
1
1
|
FactoryGirl.define do
|
2
|
+
long_form_headers = 'username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol,status,access_level,last_attempted_at'
|
3
|
+
short_form_headers = 'username,private_data'
|
4
|
+
login_status = Metasploit::Model::Login::Status::ALL.select {|x| x != Metasploit::Model::Login::Status::UNTRIED }.sample
|
5
|
+
access_level = ['Admin', 'Foo'].sample
|
6
|
+
last_attempted_at = Time.now - 10
|
7
|
+
|
2
8
|
factory :metasploit_credential_core_importer,
|
3
9
|
class: Metasploit::Credential::Importer::Core do
|
4
|
-
|
5
|
-
|
6
|
-
input { generate(:well_formed_csv_compliant_header)}
|
10
|
+
origin { FactoryGirl.build :metasploit_credential_origin_import }
|
11
|
+
input { generate(:well_formed_csv_compliant_header) }
|
7
12
|
end
|
8
13
|
|
14
|
+
|
9
15
|
# Well-formed CSV
|
10
16
|
# Has a compliant header as defined by Metasploit::Credential::Importer::Core
|
11
17
|
# Contains 2 realms
|
12
18
|
sequence :well_formed_csv_compliant_header do |n|
|
13
19
|
csv_string =<<-eos
|
14
|
-
|
15
|
-
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
|
16
|
-
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
|
17
|
-
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins
|
20
|
+
#{long_form_headers}
|
21
|
+
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
|
22
|
+
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
|
23
|
+
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins,,,,,#{login_status},#{access_level},#{last_attempted_at}
|
18
24
|
eos
|
19
25
|
StringIO.new(csv_string)
|
20
26
|
end
|
@@ -24,10 +30,10 @@ lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit:
|
|
24
30
|
# Contains 2 logins
|
25
31
|
sequence :well_formed_csv_compliant_header_with_service_info do |n|
|
26
32
|
csv_string =<<-eos
|
27
|
-
|
28
|
-
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,10.0.1.1,1234,smb,tcp
|
29
|
-
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,10.0.1.2,1234,smb,tcp
|
30
|
-
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins
|
33
|
+
#{long_form_headers}
|
34
|
+
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,10.0.1.1,1234,smb,tcp,#{login_status},#{access_level},#{last_attempted_at}
|
35
|
+
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,10.0.1.2,1234,smb,tcp,#{login_status},#{access_level},#{last_attempted_at}
|
36
|
+
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins,#{login_status},#{access_level},#{last_attempted_at}
|
31
37
|
eos
|
32
38
|
StringIO.new(csv_string)
|
33
39
|
end
|
@@ -37,10 +43,10 @@ lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit:
|
|
37
43
|
# Contains no realm data
|
38
44
|
sequence :well_formed_csv_compliant_header_no_realm do |n|
|
39
45
|
csv_string =<<-eos
|
40
|
-
|
41
|
-
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief
|
42
|
-
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head
|
43
|
-
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun
|
46
|
+
#{long_form_headers}
|
47
|
+
han_solo-#{n},#{Metasploit::Credential::Password.name},falcon_chief,,,,,,#{login_status},#{access_level},#{last_attempted_at},,,,,#{login_status},#{access_level},#{last_attempted_at}
|
48
|
+
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,,,,,,#{login_status},#{access_level},#{last_attempted_at},,,,,#{login_status},#{access_level},#{last_attempted_at}
|
49
|
+
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,,,,,,#{login_status},#{access_level},#{last_attempted_at},,,,,#{login_status},#{access_level},#{last_attempted_at}
|
44
50
|
eos
|
45
51
|
StringIO.new(csv_string)
|
46
52
|
end
|
@@ -51,10 +57,10 @@ lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,,
|
|
51
57
|
# Contains core with a blank Public
|
52
58
|
sequence :well_formed_csv_compliant_header_missing_public do |n|
|
53
59
|
csv_string =<<-eos
|
54
|
-
|
55
|
-
,#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
|
56
|
-
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
|
57
|
-
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins
|
60
|
+
#{long_form_headers}
|
61
|
+
,#{Metasploit::Credential::Password.name},falcon_chief,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
|
62
|
+
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels,,,,,#{login_status},#{access_level},#{last_attempted_at}
|
63
|
+
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins,,,,,#{login_status},#{access_level},#{last_attempted_at}
|
58
64
|
eos
|
59
65
|
StringIO.new(csv_string)
|
60
66
|
end
|
@@ -65,7 +71,7 @@ lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit:
|
|
65
71
|
# Contains core with a blank Private
|
66
72
|
sequence :well_formed_csv_compliant_header_missing_private do |n|
|
67
73
|
csv_string =<<-eos
|
68
|
-
|
74
|
+
#{long_form_headers}
|
69
75
|
han_solo,,,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
|
70
76
|
princessl-#{n},#{Metasploit::Credential::Password.name},bagel_head,#{Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN},Rebels
|
71
77
|
lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER},dstar_admins
|
@@ -78,7 +84,7 @@ lord_vader-#{n},#{Metasploit::Credential::Password.name},evilisfun,#{Metasploit:
|
|
78
84
|
# Conforms to "short" form, in which only username and private_data are specified in the file
|
79
85
|
sequence :short_well_formed_csv do |n|
|
80
86
|
csv_string =<<-eos
|
81
|
-
|
87
|
+
#{short_form_headers}
|
82
88
|
han_solo-#{n},falC0nBaws
|
83
89
|
princessl-#{n},bagelHead
|
84
90
|
eos
|
@@ -116,7 +122,7 @@ foo,{"""}
|
|
116
122
|
# We have a header row but nothing else
|
117
123
|
sequence :empty_core_csv do |n|
|
118
124
|
csv_string =<<-eos
|
119
|
-
|
125
|
+
#{long_form_headers}
|
120
126
|
eos
|
121
127
|
StringIO.new(csv_string)
|
122
128
|
end
|
@@ -59,69 +59,76 @@ describe Metasploit::Credential::Exporter::Core do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
describe "#line_for_core" do
|
62
|
+
let(:result_hash) { core_exporter.line_for_core(core) }
|
63
|
+
|
62
64
|
it 'should produce values in the proper order' do
|
63
|
-
|
64
|
-
|
65
|
+
result_hash.values.should == [core.public.username, core.private.type,
|
66
|
+
core.private.data, core.realm.key, core.realm.value]
|
65
67
|
end
|
66
68
|
|
67
69
|
it 'should produce a hash with the public username' do
|
68
|
-
result_hash = core_exporter.line_for_core(core)
|
69
70
|
result_hash[:username].should == core.public.username
|
70
71
|
end
|
71
72
|
|
72
73
|
it 'should produce a hash with the private data' do
|
73
|
-
result_hash = core_exporter.line_for_core(core)
|
74
74
|
result_hash[:private_data].should == core.private.data
|
75
75
|
end
|
76
76
|
|
77
77
|
it 'should produce a hash with the name of the private type' do
|
78
|
-
result_hash = core_exporter.line_for_core(core)
|
79
78
|
result_hash[:private_type].should == core.private.type
|
80
79
|
end
|
81
80
|
end
|
82
81
|
|
83
82
|
describe "#line_for_login" do
|
84
83
|
let(:login){ FactoryGirl.create(:metasploit_credential_login, core: core, service: service) }
|
84
|
+
let(:result_hash) { core_exporter.line_for_login(login) }
|
85
85
|
|
86
86
|
it 'should produce values in the proper order' do
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
87
|
+
result_hash.values.should == [core.public.username, core.private.type,
|
88
|
+
core.private.data, core.realm.key, core.realm.value,
|
89
|
+
login.service.host.address, login.service.port,
|
90
|
+
login.service.name, login.service.proto,
|
91
|
+
login.status, login.access_level, login.last_attempted_at
|
92
|
+
]
|
91
93
|
end
|
92
94
|
|
93
95
|
it 'should produce a hash with the service host address' do
|
94
|
-
result_hash = core_exporter.line_for_login(login)
|
95
96
|
result_hash[:host_address].should == login.service.host.address
|
96
97
|
end
|
97
98
|
|
98
99
|
it 'should produce a hash with the service port' do
|
99
|
-
result_hash = core_exporter.line_for_login(login)
|
100
100
|
result_hash[:service_port].should == login.service.port
|
101
101
|
end
|
102
102
|
|
103
103
|
it 'should produce a hash with the service name' do
|
104
|
-
result_hash = core_exporter.line_for_login(login)
|
105
104
|
result_hash[:service_name].should == login.service.name
|
106
105
|
end
|
107
106
|
|
108
107
|
it 'should produce a hash with the service protocol' do
|
109
|
-
result_hash = core_exporter.line_for_login(login)
|
110
108
|
result_hash[:service_protocol].should == login.service.proto
|
111
109
|
end
|
112
110
|
|
111
|
+
it 'should produce a hash with the login status' do
|
112
|
+
result_hash[:status].should == login.status
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should produce a hash with the login access_level' do
|
116
|
+
result_hash[:access_level].should == login.access_level
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should produce a hash with the login last_attempted_at' do
|
120
|
+
result_hash[:last_attempted_at].should == login.last_attempted_at
|
121
|
+
end
|
122
|
+
|
113
123
|
it 'should produce a hash with the public information' do
|
114
|
-
result_hash = core_exporter.line_for_login(login)
|
115
124
|
result_hash[:username].should == login.core.public.username
|
116
125
|
end
|
117
126
|
|
118
127
|
it 'should produce a hash with the private data' do
|
119
|
-
result_hash = core_exporter.line_for_login(login)
|
120
128
|
result_hash[:private_data].should == login.core.private.data
|
121
129
|
end
|
122
130
|
|
123
|
-
it 'should produce a hash with the demodulized name of the
|
124
|
-
result_hash = core_exporter.line_for_login(login)
|
131
|
+
it 'should produce a hash with the demodulized name of the private type' do
|
125
132
|
result_hash[:private_type].should == login.core.private.type
|
126
133
|
end
|
127
134
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: metasploit-credential
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.13.
|
4
|
+
version: 0.13.11
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Imhoff
|
@@ -310,7 +310,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
310
310
|
version: '0'
|
311
311
|
requirements: []
|
312
312
|
rubyforge_project:
|
313
|
-
rubygems_version: 2.4.
|
313
|
+
rubygems_version: 2.4.5
|
314
314
|
signing_key:
|
315
315
|
specification_version: 4
|
316
316
|
summary: Credential models for metasploit-framework and Metasploit Pro
|