metasploit-credential 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/config/locales/en.yml +1 -1
- data/lib/metasploit/credential/importer/core.rb +87 -45
- data/lib/metasploit/credential/importer/multi.rb +3 -3
- data/lib/metasploit/credential/version.rb +1 -1
- data/spec/dummy/config/database.yml +12 -7
- data/spec/dummy/db/structure.sql +12 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebc112c987170f24341030c7376260c0404fbba9
|
4
|
+
data.tar.gz: b60d6f5382ce35a86eaf3a5b5be0c4cff748102b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b0f38e6cbeab4bca929efe31bd84dcebfa70009638a8fbc6ffb553eb39065f6ec81c6761315c4e4c35252023163305d58e537929baf74d9b6f178608405e439
|
7
|
+
data.tar.gz: 159a68c09d71add5c60a69fa7d1f8f79cbafb9e4507a8830f9fe232253ad4e388a8ace3d880a3a96377f5de3add255a99670ac65e0f30a167edad85b9041df2b
|
data/config/locales/en.yml
CHANGED
@@ -44,7 +44,7 @@ en:
|
|
44
44
|
data:
|
45
45
|
help: "Filters the results by private credentials that contain the specified value."
|
46
46
|
type:
|
47
|
-
help: "Filters the results by private credential type. The search value must be 'Password', 'NTLM hash', 'SSH key', or '
|
47
|
+
help: "Filters the results by private credential type. The search value must be 'Password', 'NTLM hash', 'SSH key', or 'Nonreplayable hash'."
|
48
48
|
metasploit/credential/public:
|
49
49
|
search:
|
50
50
|
operator:
|
@@ -82,11 +82,12 @@ class Metasploit::Credential::Importer::Core
|
|
82
82
|
# Otherwise, assume that this is a short form import and process accordingly.
|
83
83
|
# @return [void]
|
84
84
|
def import!
|
85
|
-
if
|
86
|
-
|
85
|
+
if csv_object.first.headers.include? 'private_type'
|
86
|
+
result = import_long_form
|
87
87
|
else
|
88
|
-
|
88
|
+
result = import_short_form
|
89
89
|
end
|
90
|
+
return result
|
90
91
|
end
|
91
92
|
|
92
93
|
# Performs an import of a "long" CSV - one that that contains realms and heterogenous private types
|
@@ -97,9 +98,13 @@ class Metasploit::Credential::Importer::Core
|
|
97
98
|
#
|
98
99
|
# @return [void]
|
99
100
|
def import_long_form
|
101
|
+
all_creds_valid = true
|
100
102
|
realms = Hash.new
|
101
103
|
Metasploit::Credential::Core.transaction do
|
104
|
+
core_opts = []
|
105
|
+
rows = []
|
102
106
|
csv_object.each do |row|
|
107
|
+
|
103
108
|
next if row.header_row?
|
104
109
|
next unless row['username'].present? || row['private_data'].present?
|
105
110
|
|
@@ -111,17 +116,6 @@ class Metasploit::Credential::Importer::Core
|
|
111
116
|
private_class = row['private_type'].present? ? row['private_type'].constantize : ''
|
112
117
|
private_data = row['private_data'].present? ? row['private_data'] : ''
|
113
118
|
|
114
|
-
# Host and Service information for Logins
|
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'] : ''
|
124
|
-
|
125
119
|
|
126
120
|
if realms[realm_value].nil?
|
127
121
|
realms[realm_value] = Metasploit::Credential::Realm.where(key: realm_key, value: realm_value).first_or_create
|
@@ -140,57 +134,105 @@ class Metasploit::Credential::Importer::Core
|
|
140
134
|
private_object_for_row = private_class.where(data: private_data).first_or_create
|
141
135
|
end
|
142
136
|
end
|
137
|
+
all_creds_valid = all_creds_valid && public_object && private_object_for_row && (public_object.valid? && private_object_for_row.valid?)
|
138
|
+
|
139
|
+
core_opts << {origin:origin, workspace_id: workspace.id,
|
140
|
+
public: public_object,
|
141
|
+
private: private_object_for_row,
|
142
|
+
realm: realm_object_for_row}
|
143
|
+
|
144
|
+
rows << row
|
145
|
+
|
146
|
+
|
147
|
+
|
148
|
+
end
|
149
|
+
if all_creds_valid
|
150
|
+
core_opts.each_index do |index|
|
151
|
+
row = rows[index]
|
152
|
+
|
153
|
+
|
154
|
+
# Host and Service information for Logins
|
155
|
+
host_address = row['host_address']
|
156
|
+
service_port = row['service_port']
|
157
|
+
service_protocol = row['service_protocol']
|
158
|
+
service_name = row['service_name']
|
159
|
+
# These were not initially included in the export, so handle
|
160
|
+
# legacy cases:
|
161
|
+
access_level = row['access_level'].present? ? row['access_level'] : ''
|
162
|
+
last_attempted_at = row['last_attempted_at'].present? ? row['last_attempted_at'] : ''
|
163
|
+
status = row['status'].present? ? row['status'] : ''
|
164
|
+
|
165
|
+
if Metasploit::Credential::Core.where(core_opts[index]).blank?
|
166
|
+
core = create_credential_core(core_opts[index])
|
167
|
+
else
|
168
|
+
core = Metasploit::Credential::Core.where(core_opts[index])
|
169
|
+
end
|
170
|
+
|
171
|
+
|
172
|
+
if host_address.present? && service_port.present? && service_protocol.present?
|
173
|
+
login_opts = {
|
174
|
+
core: core,
|
175
|
+
address: host_address,
|
176
|
+
port: service_port,
|
177
|
+
protocol: service_protocol,
|
178
|
+
workspace_id: workspace.id,
|
179
|
+
service_name: service_name.present? ? service_name : ""
|
180
|
+
}
|
181
|
+
login_opts[:last_attempted_at] = last_attempted_at unless status.blank?
|
182
|
+
login_opts[:status] = status unless status.blank?
|
183
|
+
login_opts[:access_level] = access_level unless access_level.blank?
|
143
184
|
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
realm: realm_object_for_row )
|
148
|
-
|
149
|
-
# Make Logins with attendant Host/Service information if we are doing that
|
150
|
-
if host_address.present? && service_port.present? && service_protocol.present?
|
151
|
-
login_opts = {
|
152
|
-
core: core,
|
153
|
-
address: host_address,
|
154
|
-
port: service_port,
|
155
|
-
protocol: service_protocol,
|
156
|
-
workspace_id: workspace.id,
|
157
|
-
service_name: service_name.present? ? service_name : ""
|
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
|
-
|
163
|
-
create_credential_login(login_opts)
|
185
|
+
create_credential_login(login_opts)
|
186
|
+
|
187
|
+
end
|
164
188
|
end
|
165
189
|
end
|
166
|
-
|
190
|
+
end
|
191
|
+
return all_creds_valid
|
167
192
|
end
|
168
193
|
|
169
194
|
|
170
195
|
# Performs an import of a "short" form of CSV - one that contains only one type of {Metasploit::Credential::Private}
|
171
196
|
# and no {Metasploit::Credential::Realm} data
|
172
|
-
# @return [
|
197
|
+
# @return [Boolean]
|
173
198
|
def import_short_form
|
199
|
+
core_opts = []
|
200
|
+
all_creds_valid = true
|
174
201
|
Metasploit::Credential::Core.transaction do
|
175
202
|
csv_object.each do |row|
|
176
203
|
next if row.header_row?
|
177
204
|
|
178
|
-
username = row['username']
|
179
|
-
private_data
|
205
|
+
username = row['username'].present? ? row['username'] : ''
|
206
|
+
private_data = row['private_data'].present? ? row['private_data'] : ''
|
180
207
|
|
181
208
|
public_object = create_public_from_field(username)
|
182
209
|
|
183
210
|
if private_data.strip == BLANK_TOKEN
|
184
211
|
private_object_for_row = Metasploit::Credential::BlankPassword.first_or_create
|
185
212
|
else
|
186
|
-
private_object_for_row = private_credential_type.constantize.where(data: row['private_data']).first_or_create
|
213
|
+
private_object_for_row = @private_credential_type.constantize.where(data: row['private_data']).first_or_create
|
187
214
|
end
|
188
215
|
|
189
|
-
|
216
|
+
# need to check private_object_for_row.valid? to raise a user facing message if any cred had invalid private
|
217
|
+
|
218
|
+
all_creds_valid = all_creds_valid && (public_object.valid? && private_object_for_row.valid?)
|
219
|
+
|
220
|
+
|
221
|
+
core_opts << {origin:origin, workspace_id: workspace.id,
|
190
222
|
public: public_object,
|
191
|
-
private: private_object_for_row
|
223
|
+
private: private_object_for_row}
|
192
224
|
end
|
225
|
+
if all_creds_valid
|
226
|
+
core_opts.each do |item|
|
227
|
+
if Metasploit::Credential::Core.where(private:item[:private]).blank?
|
228
|
+
create_credential_core(item)
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
232
|
+
|
233
|
+
|
193
234
|
end
|
235
|
+
return all_creds_valid
|
194
236
|
end
|
195
237
|
|
196
238
|
|
@@ -211,10 +253,10 @@ class Metasploit::Credential::Importer::Core
|
|
211
253
|
# @param csv_headers [Array] the headers in the CSV contained in {#input}
|
212
254
|
# @return [Boolean]
|
213
255
|
def csv_headers_are_correct?(csv_headers)
|
214
|
-
if
|
215
|
-
return csv_headers.map(&:to_sym) == VALID_SHORT_CSV_HEADERS
|
216
|
-
else
|
256
|
+
if csv_headers.include? 'private_type'
|
217
257
|
return csv_headers.map(&:to_sym) == VALID_LONG_CSV_HEADERS
|
258
|
+
else
|
259
|
+
return csv_headers.map(&:to_sym) == VALID_SHORT_CSV_HEADERS
|
218
260
|
end
|
219
261
|
end
|
220
262
|
|
@@ -247,7 +289,7 @@ class Metasploit::Credential::Importer::Core
|
|
247
289
|
# Returns true if the {#private_credential_type} is in {Metasploit::Credential::Importer::Base::ALLOWED_PRIVATE_TYPE_NAMES}
|
248
290
|
# @return [void]
|
249
291
|
def private_type_is_allowed
|
250
|
-
if Metasploit::Credential::Importer::Base::SHORT_FORM_ALLOWED_PRIVATE_TYPE_NAMES.include? private_credential_type
|
292
|
+
if Metasploit::Credential::Importer::Base::SHORT_FORM_ALLOWED_PRIVATE_TYPE_NAMES.include? @private_credential_type
|
251
293
|
true
|
252
294
|
else
|
253
295
|
errors.add(:private_credential_type, :invalid_type)
|
@@ -41,11 +41,11 @@ class Metasploit::Credential::Importer::Multi
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
-
# Perform the import
|
44
|
+
# Perform the import. Return true if import succeeded. Return false if any cred failed due to formatting.
|
45
45
|
#
|
46
|
-
# @return [
|
46
|
+
# @return [Boolean]
|
47
47
|
def import!
|
48
|
-
selected_importer.import!
|
48
|
+
return selected_importer.import!
|
49
49
|
end
|
50
50
|
|
51
51
|
|
@@ -1,17 +1,22 @@
|
|
1
|
+
# Please only use postgresql bound to a TCP port.
|
1
2
|
development: &pgsql
|
2
3
|
adapter: postgresql
|
3
4
|
database: metasploit_credential_development
|
4
|
-
username:
|
5
|
+
username: msf
|
5
6
|
password: pass123
|
6
7
|
host: localhost
|
7
8
|
port: 5432
|
8
|
-
pool:
|
9
|
+
pool: 5
|
9
10
|
timeout: 5
|
10
|
-
min_messages: WARNING
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
12
|
+
# Warning: The database defined as "test" will be erased and
|
13
|
+
# re-generated from your development database when you run "rake".
|
14
|
+
# Do not set this db to the same as development or production.
|
15
|
+
#
|
16
|
+
# Note also, sqlite3 is totally unsupported by Metasploit now.
|
15
17
|
test:
|
16
18
|
<<: *pgsql
|
17
|
-
database: metasploit_credential_test
|
19
|
+
database: metasploit_credential_test
|
20
|
+
password: pass123
|
21
|
+
username: msf
|
22
|
+
|
data/spec/dummy/db/structure.sql
CHANGED
@@ -2006,7 +2006,9 @@ CREATE TABLE vulns (
|
|
2006
2006
|
info character varying(65536),
|
2007
2007
|
exploited_at timestamp without time zone,
|
2008
2008
|
vuln_detail_count integer DEFAULT 0,
|
2009
|
-
vuln_attempt_count integer DEFAULT 0
|
2009
|
+
vuln_attempt_count integer DEFAULT 0,
|
2010
|
+
origin_id integer,
|
2011
|
+
origin_type character varying(255)
|
2010
2012
|
);
|
2011
2013
|
|
2012
2014
|
|
@@ -3662,6 +3664,13 @@ CREATE INDEX index_sessions_on_module_run_id ON sessions USING btree (module_run
|
|
3662
3664
|
CREATE INDEX index_vulns_on_name ON vulns USING btree (name);
|
3663
3665
|
|
3664
3666
|
|
3667
|
+
--
|
3668
|
+
-- Name: index_vulns_on_origin_id; Type: INDEX; Schema: public; Owner: -; Tablespace:
|
3669
|
+
--
|
3670
|
+
|
3671
|
+
CREATE INDEX index_vulns_on_origin_id ON vulns USING btree (origin_id);
|
3672
|
+
|
3673
|
+
|
3665
3674
|
--
|
3666
3675
|
-- Name: index_web_forms_on_path; Type: INDEX; Schema: public; Owner: -; Tablespace:
|
3667
3676
|
--
|
@@ -4065,6 +4074,8 @@ INSERT INTO schema_migrations (version) VALUES ('20150326183742');
|
|
4065
4074
|
|
4066
4075
|
INSERT INTO schema_migrations (version) VALUES ('20150421211719');
|
4067
4076
|
|
4077
|
+
INSERT INTO schema_migrations (version) VALUES ('20150514182921');
|
4078
|
+
|
4068
4079
|
INSERT INTO schema_migrations (version) VALUES ('21');
|
4069
4080
|
|
4070
4081
|
INSERT INTO schema_migrations (version) VALUES ('22');
|
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: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Imhoff
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-
|
12
|
+
date: 2015-08-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: metasploit-version
|