metasploit-credential 2.0.3 → 2.0.4
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
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/lib/metasploit/credential/creation.rb +86 -1
- data/lib/metasploit/credential/version.rb +1 -1
- data/spec/dummy/config/database.yml +2 -2
- data/spec/lib/metasploit/credential/creation_spec.rb +376 -41
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a56ce07c1860329469314749756ff7ca1cae3155
|
4
|
+
data.tar.gz: 2bf103c57ab677118ff33f078d9a6acd6c2cbc81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 65b4dfd7ed3a2e18291ff22c849ccb3d1c117d71d896dff96bf127b079e59c282350cf007d445d8a4a419ef86876ec5ffc6dfcad647eb3484755a99489a14a81
|
7
|
+
data.tar.gz: 557568c2baa26e11281694c5fc843034a9526e1f75a149462c8add24f093f39871da8f8270b28f9232a2a7e95673507cbfc4e0aa77d1b6f2093b5783809f0909
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
@@ -125,7 +125,7 @@ module Metasploit::Credential::Creation
|
|
125
125
|
if opts.has_key?(:realm_key) && opts.has_key?(:realm_value)
|
126
126
|
core_opts[:realm] = create_credential_realm(opts)
|
127
127
|
end
|
128
|
-
|
128
|
+
|
129
129
|
if opts.has_key?(:private_type) && opts.has_key?(:private_data)
|
130
130
|
core_opts[:private] = create_credential_private(opts)
|
131
131
|
end
|
@@ -140,6 +140,91 @@ module Metasploit::Credential::Creation
|
|
140
140
|
|
141
141
|
create_credential_core(core_opts)
|
142
142
|
end
|
143
|
+
|
144
|
+
# This method is responsible for creation {Metasploit::Credential::Core} and
|
145
|
+
# {Metasploit::Credential::Login}.
|
146
|
+
# This method is responsible for creating a {Metasploit::Credential::Login} object
|
147
|
+
# which ties a {Metasploit::Credential::Core} to the `Mdm::Service` it is a valid
|
148
|
+
# credential for.
|
149
|
+
#
|
150
|
+
# NOTE: for origin_type: service it must be the same service your going to create a login for.
|
151
|
+
#
|
152
|
+
# {Metasploit::Credential::Core} options
|
153
|
+
# @option opts [String] :jtr_format The format for John the ripper to use to try and crack this
|
154
|
+
# @option opts [Symbol] :origin_type The Origin type we are trying to create
|
155
|
+
# @option opts [String] :address The address of the `Mdm::Host` to link this Origin to
|
156
|
+
# @option opts [Fixnum] :port The port number of the `Mdm::Service` to link this Origin to
|
157
|
+
# @option opts [String] :service_name The service name to use for the `Mdm::Service`
|
158
|
+
# @option opts [String] :protocol The protocol type of the `Mdm::Service` to link this Origin to
|
159
|
+
# @option opts [String] :module_fullname The fullname of the Metasploit Module to link this Origin to
|
160
|
+
# @option opts [Fixnum] :workspace_id The ID of the `Mdm::Workspace` to use for the `Mdm::Host`
|
161
|
+
# @option opts [Fixnum] :task_id The ID of the `Mdm::Task` to link this Origin and Core to
|
162
|
+
# @option opts [String] :filename The filename of the file that was imported
|
163
|
+
# @option opts [Fixnum] :user_id The ID of the `Mdm::User` to link this Origin to
|
164
|
+
# @option opts [Fixnum] :session_id The ID of the `Mdm::Session` to link this Origin to
|
165
|
+
# @option opts [String] :post_reference_name The reference name of the Metasploit Post module to link the origin to
|
166
|
+
# @option opts [String] :private_data The actual data for the private (e.g. password, hash, key etc)
|
167
|
+
# @option opts [Symbol] :private_type The type of {Metasploit::Credential::Private} to create
|
168
|
+
# {Metasploit::Credential::Login}
|
169
|
+
# @option opts [String] :access_level The access level to assign to this login if we know it
|
170
|
+
# @option opts [String] :status The status for the Login object
|
171
|
+
# @raise [KeyError] if a required option is missing
|
172
|
+
# @raise [ArgumentError] if an invalid :private_type is specified
|
173
|
+
# @raise [ArgumentError] if an invalid :origin_type is specified
|
174
|
+
# @return [NilClass] if there is no active database connection
|
175
|
+
# @return [Metasploit::Credential::Core]
|
176
|
+
# @example Reporting a Bruteforced Credential and Login
|
177
|
+
# create_credential_and_login(
|
178
|
+
# origin_type: :service,
|
179
|
+
# address: '192.168.1.100',
|
180
|
+
# port: 445,
|
181
|
+
# service_name: 'smb',
|
182
|
+
# protocol: 'tcp',
|
183
|
+
# module_fullname: 'auxiliary/scanner/smb/smb_login',
|
184
|
+
# workspace_id: myworkspace.id,
|
185
|
+
# private_data: 'password1',
|
186
|
+
# private_type: :password,
|
187
|
+
# username: 'Administrator',
|
188
|
+
# service_name: 'smb',
|
189
|
+
# status: status: Metasploit::Model::Login::Status::UNTRIED
|
190
|
+
# )
|
191
|
+
|
192
|
+
|
193
|
+
def create_credential_and_login(opts={})
|
194
|
+
return nil unless active_db?
|
195
|
+
|
196
|
+
if self.respond_to?(:[]) and self[:task]
|
197
|
+
opts[:task_id] ||= self[:task].record.id
|
198
|
+
end
|
199
|
+
|
200
|
+
core = opts.fetch(:core, create_credential(opts))
|
201
|
+
access_level = opts.fetch(:access_level, nil)
|
202
|
+
last_attempted_at = opts.fetch(:last_attempted_at, nil)
|
203
|
+
status = opts.fetch(:status, Metasploit::Model::Login::Status::UNTRIED)
|
204
|
+
|
205
|
+
login_object = nil
|
206
|
+
retry_transaction do
|
207
|
+
service_object = create_credential_service(opts)
|
208
|
+
login_object = Metasploit::Credential::Login.where(core_id: core.id, service_id: service_object.id).first_or_initialize
|
209
|
+
|
210
|
+
if opts[:task_id]
|
211
|
+
login_object.tasks << Mdm::Task.find(opts[:task_id])
|
212
|
+
end
|
213
|
+
|
214
|
+
login_object.access_level = access_level if access_level
|
215
|
+
login_object.last_attempted_at = last_attempted_at if last_attempted_at
|
216
|
+
if status == Metasploit::Model::Login::Status::UNTRIED
|
217
|
+
if login_object.last_attempted_at.nil?
|
218
|
+
login_object.status = status
|
219
|
+
end
|
220
|
+
else
|
221
|
+
login_object.status = status
|
222
|
+
end
|
223
|
+
login_object.save!
|
224
|
+
end
|
225
|
+
|
226
|
+
login_object
|
227
|
+
end
|
143
228
|
|
144
229
|
# This method is responsible for creating {Metasploit::Credential::Core} objects.
|
145
230
|
#
|
@@ -1,6 +1,6 @@
|
|
1
1
|
development: &pgsql
|
2
2
|
adapter: postgresql
|
3
|
-
database: metasploit-
|
3
|
+
database: metasploit-credential_development0
|
4
4
|
username: msf
|
5
5
|
password: pass123
|
6
6
|
host: localhost
|
@@ -10,4 +10,4 @@ development: &pgsql
|
|
10
10
|
min_messages: warning
|
11
11
|
test:
|
12
12
|
<<: *pgsql
|
13
|
-
database: metasploit-
|
13
|
+
database: metasploit-credential_test0
|
@@ -15,6 +15,358 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
15
15
|
let(:workspace) { FactoryGirl.create(:mdm_workspace) }
|
16
16
|
|
17
17
|
subject(:test_object) { dummy_class.new }
|
18
|
+
|
19
|
+
context '#create_credential' do
|
20
|
+
let(:workspace) { FactoryGirl.create(:mdm_workspace) }
|
21
|
+
let(:service) { FactoryGirl.create(:mdm_service, host: FactoryGirl.create(:mdm_host, workspace: workspace)) }
|
22
|
+
let(:task) { FactoryGirl.create(:mdm_task, workspace: workspace) }
|
23
|
+
{
|
24
|
+
cracked_password: Metasploit::Credential::Origin::CrackedPassword,
|
25
|
+
import: Metasploit::Credential::Origin::Import,
|
26
|
+
manual: Metasploit::Credential::Origin::Manual,
|
27
|
+
service: Metasploit::Credential::Origin::Service,
|
28
|
+
session: Metasploit::Credential::Origin::Session
|
29
|
+
}.each_pair do |origin_type, origin_class|
|
30
|
+
context "Origin[#{origin_type}], Public[Username], Private[Password]" do
|
31
|
+
let(:service) { FactoryGirl.create(:mdm_service) }
|
32
|
+
let!(:origin_data) {{
|
33
|
+
cracked_password: {
|
34
|
+
originating_core_id: FactoryGirl.create(
|
35
|
+
:metasploit_credential_core, workspace: workspace, origin_factory: :metasploit_credential_origin_manual).id
|
36
|
+
},
|
37
|
+
import: {
|
38
|
+
filename: FactoryGirl.generate(:metasploit_credential_origin_import_filename)
|
39
|
+
},
|
40
|
+
manual: {user_id: user.id},
|
41
|
+
service: {
|
42
|
+
module_fullname: "exploit/" + FactoryGirl.generate(:metasploit_credential_origin_service_reference_name),
|
43
|
+
address: service.host.address,
|
44
|
+
port: service.port,
|
45
|
+
service_name: service.name,
|
46
|
+
protocol: service.proto
|
47
|
+
},
|
48
|
+
session: {
|
49
|
+
session_id: FactoryGirl.create(:mdm_session, workspace: workspace, host: service.host),
|
50
|
+
post_reference_name: FactoryGirl.generate(:metasploit_credential_origin_session_post_reference_name)
|
51
|
+
}
|
52
|
+
}}
|
53
|
+
let(:credential_data) {{
|
54
|
+
workspace_id: workspace.id,
|
55
|
+
origin_type: origin_type,
|
56
|
+
username: 'admin',
|
57
|
+
private_data: 'password',
|
58
|
+
private_type: :password,
|
59
|
+
workspace_id: workspace.id
|
60
|
+
}.merge(origin_data[origin_type])}
|
61
|
+
it 'creates a credential core' do
|
62
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
63
|
+
end
|
64
|
+
it "creates a Origin of type #{origin_type}" do
|
65
|
+
expect{ test_object.create_credential(credential_data) }.to change{ origin_class.count }.by(1)
|
66
|
+
end
|
67
|
+
it 'creates a Private with data \'password\'' do
|
68
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Private.where(data: 'password').count }.by(1)
|
69
|
+
end
|
70
|
+
it 'creates a Public with username \'username\'' do
|
71
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Public.where(username: 'admin').count }.by(1)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
[
|
76
|
+
Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
|
77
|
+
Metasploit::Model::Realm::Key::DB2_DATABASE,
|
78
|
+
Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER,
|
79
|
+
Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE,
|
80
|
+
Metasploit::Model::Realm::Key::RSYNC_MODULE,
|
81
|
+
Metasploit::Model::Realm::Key::WILDCARD
|
82
|
+
].each do |realm_type|
|
83
|
+
context "Origin[manual], Realm[#{realm_type}], Public[Username], Private[Password]" do
|
84
|
+
let(:credential_data) {{
|
85
|
+
workspace_id: workspace.id,
|
86
|
+
user_id: user.id,
|
87
|
+
realm_key: realm_type,
|
88
|
+
realm_value: 'Some Value',
|
89
|
+
origin_type: :manual,
|
90
|
+
username: 'admin',
|
91
|
+
private_data: 'password',
|
92
|
+
private_type: :password,
|
93
|
+
workspace_id: workspace.id
|
94
|
+
}}
|
95
|
+
it 'creates a credential core' do
|
96
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
97
|
+
end
|
98
|
+
it "creates a Realm with #{realm_type} key" do
|
99
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Realm.where(key: realm_type).count }.by(1)
|
100
|
+
end
|
101
|
+
it 'creates a Private with data \'password\'' do
|
102
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Private.where(data: 'password').count }.by(1)
|
103
|
+
end
|
104
|
+
it 'creates a Public with username \'username\'' do
|
105
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Public.where(username: 'admin').count }.by(1)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
{
|
110
|
+
"Metasploit::Credential::Username" => 'admin',
|
111
|
+
"Metasploit::Credential::BlankUsername" => ''
|
112
|
+
}.each_pair do |public_type, public_value|
|
113
|
+
context "Origin[manual], Public[#{public_type}], Private[Password]" do
|
114
|
+
let(:credential_data) {{
|
115
|
+
workspace_id: workspace.id,
|
116
|
+
user_id: user.id,
|
117
|
+
origin_type: :manual,
|
118
|
+
username: public_value,
|
119
|
+
private_data: 'password',
|
120
|
+
private_type: :password,
|
121
|
+
workspace_id: workspace.id
|
122
|
+
}}
|
123
|
+
it 'creates a credential core' do
|
124
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
125
|
+
end
|
126
|
+
it 'creates a Private with data \'password\'' do
|
127
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Private.where(data: 'password').count }.by(1)
|
128
|
+
end
|
129
|
+
it 'creates a Public with username \'username\'' do
|
130
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Public.where(type: public_type).count }.by(1)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
{
|
135
|
+
password: "Metasploit::Credential::Password",
|
136
|
+
blank_password: "Metasploit::Credential::BlankPassword",
|
137
|
+
nonreplayable_hash: "Metasploit::Credential::NonreplayableHash",
|
138
|
+
ntlm_hash: "Metasploit::Credential::NTLMHash",
|
139
|
+
postgres_md5: "Metasploit::Credential::PostgresMD5",
|
140
|
+
ssh_key: "Metasploit::Credential::SSHKey"
|
141
|
+
}.each_pair do |private_type, public_class|
|
142
|
+
context "Origin[manual], Public[Username], Private[#{private_type}]" do
|
143
|
+
let(:ssh_key) {
|
144
|
+
key_class = OpenSSL::PKey.const_get(:RSA)
|
145
|
+
key_class.generate(512).to_s
|
146
|
+
}
|
147
|
+
let(:private_data) { {
|
148
|
+
password: 'password',
|
149
|
+
blank_password: '',
|
150
|
+
nonreplayable_hash: '435ba65d2e46d35bc656086694868d1ab2c0f9fd',
|
151
|
+
ntlm_hash: 'aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0',
|
152
|
+
postgres_md5: 'md5ac4bbe016b808c3c0b816981f240dcae',
|
153
|
+
ssh_key: ssh_key
|
154
|
+
}}
|
155
|
+
let(:credential_data) {{
|
156
|
+
workspace_id: workspace.id,
|
157
|
+
user_id: user.id,
|
158
|
+
origin_type: :manual,
|
159
|
+
username: 'admin',
|
160
|
+
private_data: private_data[private_type],
|
161
|
+
private_type: private_type,
|
162
|
+
workspace_id: workspace.id
|
163
|
+
}}
|
164
|
+
it 'creates a credential core' do
|
165
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
166
|
+
end
|
167
|
+
it 'creates a Private with data \'password\'' do
|
168
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Private.where(type: public_class).count }.by(1)
|
169
|
+
end
|
170
|
+
it 'creates a Public with username \'username\'' do
|
171
|
+
expect{ test_object.create_credential(credential_data) }.to change{ Metasploit::Credential::Public.where(username: 'admin').count }.by(1)
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
context '#create_credential_and_login' do
|
178
|
+
let(:workspace) { FactoryGirl.create(:mdm_workspace) }
|
179
|
+
let(:service) { FactoryGirl.create(:mdm_service, host: FactoryGirl.create(:mdm_host, workspace: workspace)) }
|
180
|
+
let(:task) { FactoryGirl.create(:mdm_task, workspace: workspace) }
|
181
|
+
{
|
182
|
+
cracked_password: Metasploit::Credential::Origin::CrackedPassword,
|
183
|
+
import: Metasploit::Credential::Origin::Import,
|
184
|
+
manual: Metasploit::Credential::Origin::Manual,
|
185
|
+
service: Metasploit::Credential::Origin::Service,
|
186
|
+
session: Metasploit::Credential::Origin::Session
|
187
|
+
}.each_pair do |origin_type, origin_class|
|
188
|
+
context "Origin[#{origin_type}], Public[Username], Private[Password]" do
|
189
|
+
let!(:origin_data) {{
|
190
|
+
cracked_password: {
|
191
|
+
originating_core_id: FactoryGirl.create(
|
192
|
+
:metasploit_credential_core, workspace: workspace, origin_factory: :metasploit_credential_origin_manual).id
|
193
|
+
},
|
194
|
+
import: {
|
195
|
+
filename: FactoryGirl.generate(:metasploit_credential_origin_import_filename)
|
196
|
+
},
|
197
|
+
manual: {user_id: user.id},
|
198
|
+
service: {
|
199
|
+
module_fullname: "exploit/" + FactoryGirl.generate(:metasploit_credential_origin_service_reference_name),
|
200
|
+
address: service.host.address,
|
201
|
+
port: service.port,
|
202
|
+
service_name: service.name,
|
203
|
+
protocol: service.proto
|
204
|
+
},
|
205
|
+
session: {
|
206
|
+
session_id: FactoryGirl.create(:mdm_session, workspace: workspace, host: service.host),
|
207
|
+
post_reference_name: FactoryGirl.generate(:metasploit_credential_origin_session_post_reference_name)
|
208
|
+
}
|
209
|
+
}}
|
210
|
+
let(:login_data) {{
|
211
|
+
workspace_id: workspace.id,
|
212
|
+
origin_type: origin_type,
|
213
|
+
username: 'admin',
|
214
|
+
private_data: 'password',
|
215
|
+
private_type: :password,
|
216
|
+
workspace_id: workspace.id,
|
217
|
+
address: service.host.address,
|
218
|
+
port: service.port,
|
219
|
+
service_name: service.name,
|
220
|
+
protocol: service.proto,
|
221
|
+
last_attempted_at: DateTime.current,
|
222
|
+
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
223
|
+
}.merge(origin_data[origin_type])}
|
224
|
+
it 'creates a credential core' do
|
225
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
226
|
+
end
|
227
|
+
it "creates a Origin of type #{origin_type}" do
|
228
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ origin_class.count }.by(1)
|
229
|
+
end
|
230
|
+
it 'creates a Private with data \'password\'' do
|
231
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Private.where(data: 'password').count }.by(1)
|
232
|
+
end
|
233
|
+
it 'creates a Public with username \'username\'' do
|
234
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Public.where(username: 'admin').count }.by(1)
|
235
|
+
end
|
236
|
+
it 'creates a Login with status for the service' do
|
237
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Login.where(service_id: service.id, status: login_data[:status]).count }.by(1)
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
241
|
+
[
|
242
|
+
Metasploit::Model::Realm::Key::ACTIVE_DIRECTORY_DOMAIN,
|
243
|
+
Metasploit::Model::Realm::Key::DB2_DATABASE,
|
244
|
+
Metasploit::Model::Realm::Key::ORACLE_SYSTEM_IDENTIFIER,
|
245
|
+
Metasploit::Model::Realm::Key::POSTGRESQL_DATABASE,
|
246
|
+
Metasploit::Model::Realm::Key::RSYNC_MODULE,
|
247
|
+
Metasploit::Model::Realm::Key::WILDCARD
|
248
|
+
].each do |realm_type|
|
249
|
+
context "Origin[manual], Realm[#{realm_type}], Public[Username], Private[Password]" do
|
250
|
+
let(:login_data) {{
|
251
|
+
workspace_id: workspace.id,
|
252
|
+
user_id: user.id,
|
253
|
+
realm_key: realm_type,
|
254
|
+
realm_value: 'Some Value',
|
255
|
+
origin_type: :manual,
|
256
|
+
username: 'admin',
|
257
|
+
private_data: 'password',
|
258
|
+
private_type: :password,
|
259
|
+
workspace_id: workspace.id,
|
260
|
+
address: service.host.address,
|
261
|
+
port: service.port,
|
262
|
+
service_name: service.name,
|
263
|
+
protocol: service.proto,
|
264
|
+
last_attempted_at: DateTime.current,
|
265
|
+
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
266
|
+
}}
|
267
|
+
it 'creates a credential core' do
|
268
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
269
|
+
end
|
270
|
+
it "creates a Realm with #{realm_type} key" do
|
271
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Realm.where(key: realm_type).count }.by(1)
|
272
|
+
end
|
273
|
+
it 'creates a Private with data \'password\'' do
|
274
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Private.where(data: 'password').count }.by(1)
|
275
|
+
end
|
276
|
+
it 'creates a Public with username \'username\'' do
|
277
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Public.where(username: 'admin').count }.by(1)
|
278
|
+
end
|
279
|
+
it 'creates a Login with status for the service' do
|
280
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Login.where(service_id: service.id, status: login_data[:status]).count }.by(1)
|
281
|
+
end
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
{
|
286
|
+
"Metasploit::Credential::Username" => 'admin',
|
287
|
+
"Metasploit::Credential::BlankUsername" => ''
|
288
|
+
}.each_pair do |public_type, public_value|
|
289
|
+
context "Origin[manual], Public[#{public_type}], Private[Password]" do
|
290
|
+
let(:login_data) {{
|
291
|
+
workspace_id: workspace.id,
|
292
|
+
user_id: user.id,
|
293
|
+
origin_type: :manual,
|
294
|
+
username: public_value,
|
295
|
+
private_data: 'password',
|
296
|
+
private_type: :password,
|
297
|
+
workspace_id: workspace.id,
|
298
|
+
address: service.host.address,
|
299
|
+
port: service.port,
|
300
|
+
service_name: service.name,
|
301
|
+
protocol: service.proto,
|
302
|
+
last_attempted_at: DateTime.current,
|
303
|
+
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
304
|
+
}}
|
305
|
+
it 'creates a credential core' do
|
306
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
307
|
+
end
|
308
|
+
it 'creates a Private with data \'password\'' do
|
309
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Private.where(data: 'password').count }.by(1)
|
310
|
+
end
|
311
|
+
it 'creates a Public with username \'username\'' do
|
312
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Public.where(type: public_type).count }.by(1)
|
313
|
+
end
|
314
|
+
it 'creates a Login with status for the service' do
|
315
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Login.where(service_id: service.id, status: login_data[:status]).count }.by(1)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
end
|
319
|
+
{
|
320
|
+
password: "Metasploit::Credential::Password",
|
321
|
+
blank_password: "Metasploit::Credential::BlankPassword",
|
322
|
+
nonreplayable_hash: "Metasploit::Credential::NonreplayableHash",
|
323
|
+
ntlm_hash: "Metasploit::Credential::NTLMHash",
|
324
|
+
postgres_md5: "Metasploit::Credential::PostgresMD5",
|
325
|
+
ssh_key: "Metasploit::Credential::SSHKey"
|
326
|
+
}.each_pair do |private_type, public_class|
|
327
|
+
context "Origin[manual], Public[Username], Private[#{private_type}]" do
|
328
|
+
let(:ssh_key) {
|
329
|
+
key_class = OpenSSL::PKey.const_get(:RSA)
|
330
|
+
key_class.generate(512).to_s
|
331
|
+
}
|
332
|
+
let(:private_data) { {
|
333
|
+
password: 'password',
|
334
|
+
blank_password: '',
|
335
|
+
nonreplayable_hash: '435ba65d2e46d35bc656086694868d1ab2c0f9fd',
|
336
|
+
ntlm_hash: 'aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0',
|
337
|
+
postgres_md5: 'md5ac4bbe016b808c3c0b816981f240dcae',
|
338
|
+
ssh_key: ssh_key
|
339
|
+
}}
|
340
|
+
let(:login_data) {{
|
341
|
+
workspace_id: workspace.id,
|
342
|
+
user_id: user.id,
|
343
|
+
origin_type: :manual,
|
344
|
+
username: 'admin',
|
345
|
+
private_data: private_data[private_type],
|
346
|
+
private_type: private_type,
|
347
|
+
workspace_id: workspace.id,
|
348
|
+
address: service.host.address,
|
349
|
+
port: service.port,
|
350
|
+
service_name: service.name,
|
351
|
+
protocol: service.proto,
|
352
|
+
last_attempted_at: DateTime.current,
|
353
|
+
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
354
|
+
}}
|
355
|
+
it 'creates a credential core' do
|
356
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Core.count }.by(1)
|
357
|
+
end
|
358
|
+
it 'creates a Private with data \'password\'' do
|
359
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Private.where(type: public_class).count }.by(1)
|
360
|
+
end
|
361
|
+
it 'creates a Public with username \'username\'' do
|
362
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Public.where(username: 'admin').count }.by(1)
|
363
|
+
end
|
364
|
+
it 'creates a Login with status for the service' do
|
365
|
+
expect{ test_object.create_credential_and_login(login_data) }.to change{ Metasploit::Credential::Login.where(service_id: service.id, status: login_data[:status]).count }.by(1)
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
369
|
+
end
|
18
370
|
|
19
371
|
context '#create_cracked_credential' do
|
20
372
|
let(:public) { FactoryGirl.create(:metasploit_credential_public) }
|
@@ -34,7 +386,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
34
386
|
username: public.username,
|
35
387
|
password: password
|
36
388
|
)
|
37
|
-
}.to change{Metasploit::Credential::Core.count}.by(1)
|
389
|
+
}.to change{ Metasploit::Credential::Core.count }.by(1)
|
38
390
|
expect(Metasploit::Credential::Private.last).to be_a Metasploit::Credential::Password
|
39
391
|
end
|
40
392
|
|
@@ -46,7 +398,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
46
398
|
username: public.username,
|
47
399
|
password: password
|
48
400
|
)
|
49
|
-
}.to change{Metasploit::Credential::Core.count}.by(1)
|
401
|
+
}.to change{ Metasploit::Credential::Core.count }.by(1)
|
50
402
|
expect(Metasploit::Credential::Core.last.realm).to eq(realm)
|
51
403
|
end
|
52
404
|
|
@@ -85,7 +437,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
85
437
|
opts = {
|
86
438
|
filename: "test_import.xml",
|
87
439
|
}
|
88
|
-
expect { test_object.create_credential_origin_import(opts)}.to change{Metasploit::Credential::Origin::Import.count}.by(1)
|
440
|
+
expect { test_object.create_credential_origin_import(opts)}.to change{ Metasploit::Credential::Origin::Import.count }.by(1)
|
89
441
|
end
|
90
442
|
|
91
443
|
it 'should return nil if there is no database connection' do
|
@@ -100,7 +452,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
100
452
|
task_id: task.id
|
101
453
|
}
|
102
454
|
test_object.create_credential_origin_import(opts)
|
103
|
-
expect { test_object.create_credential_origin_import(opts)}.to_not change{Metasploit::Credential::Origin::Import.count}
|
455
|
+
expect { test_object.create_credential_origin_import(opts)}.to_not change{ Metasploit::Credential::Origin::Import.count }
|
104
456
|
end
|
105
457
|
end
|
106
458
|
|
@@ -119,7 +471,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
119
471
|
opts = {
|
120
472
|
user_id: user.id
|
121
473
|
}
|
122
|
-
expect { test_object.create_credential_origin_manual(opts)}.to change{Metasploit::Credential::Origin::Manual.count}.by(1)
|
474
|
+
expect { test_object.create_credential_origin_manual(opts)}.to change{ Metasploit::Credential::Origin::Manual.count }.by(1)
|
123
475
|
end
|
124
476
|
|
125
477
|
it 'should return nil if there is no database connection' do
|
@@ -133,7 +485,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
133
485
|
user_id: user.id
|
134
486
|
}
|
135
487
|
test_object.create_credential_origin_manual(opts)
|
136
|
-
expect { test_object.create_credential_origin_manual(opts)}.to_not change{Metasploit::Credential::Origin::Manual.count}
|
488
|
+
expect { test_object.create_credential_origin_manual(opts)}.to_not change{ Metasploit::Credential::Origin::Manual.count }
|
137
489
|
end
|
138
490
|
end
|
139
491
|
|
@@ -173,7 +525,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
173
525
|
workspace_id: workspace.id,
|
174
526
|
origin_type: :service
|
175
527
|
}
|
176
|
-
expect { test_object.create_credential_origin_service(opts)}.to change{Metasploit::Credential::Origin::Service.count}.by(1)
|
528
|
+
expect { test_object.create_credential_origin_service(opts)}.to change{ Metasploit::Credential::Origin::Service.count }.by(1)
|
177
529
|
end
|
178
530
|
|
179
531
|
it 'should return nil if there is no database connection' do
|
@@ -194,7 +546,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
194
546
|
origin_type: :service
|
195
547
|
}
|
196
548
|
FactoryGirl.create(:mdm_host, address: opts[:address], workspace_id: opts[:workspace_id])
|
197
|
-
expect { test_object.create_credential_origin_service(opts)}.to_not change{Mdm::Host.count}
|
549
|
+
expect { test_object.create_credential_origin_service(opts)}.to_not change{Mdm::Host.count }
|
198
550
|
end
|
199
551
|
end
|
200
552
|
|
@@ -209,7 +561,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
209
561
|
workspace_id: workspace.id,
|
210
562
|
origin_type: :service
|
211
563
|
}
|
212
|
-
expect { test_object.create_credential_origin_service(opts)}.to change{Mdm::Host.count}.by(1)
|
564
|
+
expect { test_object.create_credential_origin_service(opts)}.to change{Mdm::Host.count }.by(1)
|
213
565
|
end
|
214
566
|
end
|
215
567
|
|
@@ -226,7 +578,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
226
578
|
}
|
227
579
|
host = FactoryGirl.create(:mdm_host, address: opts[:address], workspace_id: opts[:workspace_id])
|
228
580
|
FactoryGirl.create(:mdm_service, host_id: host.id, port: opts[:port], proto: opts[:protocol])
|
229
|
-
expect { test_object.create_credential_origin_service(opts)}.to_not change{Mdm::Service.count}
|
581
|
+
expect { test_object.create_credential_origin_service(opts)}.to_not change{Mdm::Service.count }
|
230
582
|
end
|
231
583
|
end
|
232
584
|
|
@@ -241,7 +593,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
241
593
|
workspace_id: workspace.id,
|
242
594
|
origin_type: :service
|
243
595
|
}
|
244
|
-
expect { test_object.create_credential_origin_service(opts)}.to change{Mdm::Service.count}.by(1)
|
596
|
+
expect { test_object.create_credential_origin_service(opts)}.to change{Mdm::Service.count }.by(1)
|
245
597
|
end
|
246
598
|
end
|
247
599
|
|
@@ -257,7 +609,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
257
609
|
origin_type: :service
|
258
610
|
}
|
259
611
|
test_object.create_credential_origin_service(opts)
|
260
|
-
expect { test_object.create_credential_origin_service(opts)}.to_not change{Metasploit::Credential::Origin::Service.count}
|
612
|
+
expect { test_object.create_credential_origin_service(opts)}.to_not change{ Metasploit::Credential::Origin::Service.count }
|
261
613
|
end
|
262
614
|
end
|
263
615
|
|
@@ -275,7 +627,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
275
627
|
post_reference_name: 'windows/gather/hashdump',
|
276
628
|
session_id: session.id
|
277
629
|
}
|
278
|
-
expect { test_object.create_credential_origin_session(opts)}.to change{Metasploit::Credential::Origin::Session.count}.by(1)
|
630
|
+
expect { test_object.create_credential_origin_session(opts)}.to change{ Metasploit::Credential::Origin::Session.count }.by(1)
|
279
631
|
end
|
280
632
|
|
281
633
|
it 'should return nil if there is no database connection' do
|
@@ -290,7 +642,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
290
642
|
session_id: session.id
|
291
643
|
}
|
292
644
|
test_object.create_credential_origin_session(opts)
|
293
|
-
expect { test_object.create_credential_origin_session(opts)}.to_not change{Metasploit::Credential::Origin::Session.count}
|
645
|
+
expect { test_object.create_credential_origin_session(opts)}.to_not change{ Metasploit::Credential::Origin::Session.count }
|
294
646
|
end
|
295
647
|
end
|
296
648
|
|
@@ -359,7 +711,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
359
711
|
post_reference_name: 'windows/gather/hashdump',
|
360
712
|
session_id: session.id
|
361
713
|
}
|
362
|
-
expect{test_object.create_credential_origin(opts)}.to raise_error ArgumentError, "Unknown Origin Type "
|
714
|
+
expect{ test_object.create_credential_origin(opts)}.to raise_error ArgumentError, "Unknown Origin Type "
|
363
715
|
end
|
364
716
|
|
365
717
|
it 'raises an exception if given an invalid origin type' do
|
@@ -368,7 +720,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
368
720
|
post_reference_name: 'windows/gather/hashdump',
|
369
721
|
session_id: session.id
|
370
722
|
}
|
371
|
-
expect{test_object.create_credential_origin(opts)}.to raise_error ArgumentError, "Unknown Origin Type aaaaa"
|
723
|
+
expect{ test_object.create_credential_origin(opts)}.to raise_error ArgumentError, "Unknown Origin Type aaaaa"
|
372
724
|
end
|
373
725
|
end
|
374
726
|
|
@@ -378,7 +730,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
378
730
|
realm_key: 'Active Directory Domain',
|
379
731
|
realm_value: 'contosso'
|
380
732
|
}
|
381
|
-
expect { test_object.create_credential_realm(opts)}.to change{Metasploit::Credential::Realm.count}.by(1)
|
733
|
+
expect { test_object.create_credential_realm(opts)}.to change{ Metasploit::Credential::Realm.count }.by(1)
|
382
734
|
end
|
383
735
|
|
384
736
|
it 'should return nil if there is no database connection' do
|
@@ -393,7 +745,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
393
745
|
realm_value: 'contosso'
|
394
746
|
}
|
395
747
|
test_object.create_credential_realm(opts)
|
396
|
-
expect { test_object.create_credential_realm(opts)}.to_not change{Metasploit::Credential::Realm.count}
|
748
|
+
expect { test_object.create_credential_realm(opts)}.to_not change{ Metasploit::Credential::Realm.count }
|
397
749
|
end
|
398
750
|
end
|
399
751
|
|
@@ -424,7 +776,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
424
776
|
private_data: 'password1',
|
425
777
|
private_type: :password
|
426
778
|
}
|
427
|
-
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::Password.count}.by(1)
|
779
|
+
expect{ test_object.create_credential_private(opts) }.to change{ Metasploit::Credential::Password.count }.by(1)
|
428
780
|
end
|
429
781
|
end
|
430
782
|
|
@@ -434,7 +786,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
434
786
|
private_data: OpenSSL::PKey::RSA.generate(2048).to_s,
|
435
787
|
private_type: :ssh_key
|
436
788
|
}
|
437
|
-
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::SSHKey.count}.by(1)
|
789
|
+
expect{ test_object.create_credential_private(opts) }.to change{ Metasploit::Credential::SSHKey.count }.by(1)
|
438
790
|
end
|
439
791
|
end
|
440
792
|
|
@@ -444,7 +796,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
444
796
|
private_data: Metasploit::Credential::NTLMHash.data_from_password_data('password1'),
|
445
797
|
private_type: :ntlm_hash
|
446
798
|
}
|
447
|
-
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::NTLMHash.count}.by(1)
|
799
|
+
expect{ test_object.create_credential_private(opts) }.to change{ Metasploit::Credential::NTLMHash.count }.by(1)
|
448
800
|
end
|
449
801
|
end
|
450
802
|
|
@@ -454,7 +806,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
454
806
|
private_data: '10b222970537b97919db36ec757370d2',
|
455
807
|
private_type: :nonreplayable_hash
|
456
808
|
}
|
457
|
-
expect{ test_object.create_credential_private(opts) }.to change{Metasploit::Credential::NonreplayableHash.count}.by(1)
|
809
|
+
expect{ test_object.create_credential_private(opts) }.to change{ Metasploit::Credential::NonreplayableHash.count }.by(1)
|
458
810
|
end
|
459
811
|
end
|
460
812
|
|
@@ -469,23 +821,6 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
469
821
|
end
|
470
822
|
end
|
471
823
|
|
472
|
-
context '#create_credential' do
|
473
|
-
|
474
|
-
it 'associates the new Metasploit::Credential::Core with a task if passed' do
|
475
|
-
opts = {
|
476
|
-
origin_type: :manual,
|
477
|
-
user_id: user.id,
|
478
|
-
username: 'username',
|
479
|
-
private_data: 'password',
|
480
|
-
workspace_id: workspace.id,
|
481
|
-
task_id: task.id
|
482
|
-
}
|
483
|
-
core = test_object.create_credential(opts)
|
484
|
-
expect(core.tasks).to include(task)
|
485
|
-
end
|
486
|
-
|
487
|
-
end
|
488
|
-
|
489
824
|
context '#create_credential_core' do
|
490
825
|
let(:origin) { FactoryGirl.create(:metasploit_credential_origin_service) }
|
491
826
|
let(:public) { FactoryGirl.create(:metasploit_credential_public)}
|
@@ -512,7 +847,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
512
847
|
realm: realm,
|
513
848
|
workspace_id: workspace.id
|
514
849
|
}
|
515
|
-
expect{test_object.create_credential_core(opts)}.to change{Metasploit::Credential::Core.count}.by(1)
|
850
|
+
expect{ test_object.create_credential_core(opts)}.to change{ Metasploit::Credential::Core.count }.by(1)
|
516
851
|
end
|
517
852
|
it 'associates the new Metasploit::Credential::Core with a task if passed' do
|
518
853
|
opts = {
|
@@ -546,7 +881,7 @@ RSpec.describe Metasploit::Credential::Creation do
|
|
546
881
|
last_attempted_at: DateTime.current,
|
547
882
|
status: Metasploit::Model::Login::Status::SUCCESSFUL,
|
548
883
|
}
|
549
|
-
expect{test_object.create_credential_login(login_data)}.to change{Metasploit::Credential::Login.count}.by(1)
|
884
|
+
expect{ test_object.create_credential_login(login_data) }.to change{ Metasploit::Credential::Login.count }.by(1)
|
550
885
|
end
|
551
886
|
it "associates the Metasploit::Credential::Core with a task if passed" do
|
552
887
|
login_data = {
|
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: 2.0.
|
4
|
+
version: 2.0.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luke Imhoff
|
@@ -86,7 +86,7 @@ cert_chain:
|
|
86
86
|
2SpuQH+SWteq3NXkAmFEEqvLJQ4sbptZt8OP8ghL3pVAvZNFmww/YVszSkShSzcg
|
87
87
|
QdihYCSEL2drS2cFd50jBeq71sxUtxbv82DUa2b+
|
88
88
|
-----END CERTIFICATE-----
|
89
|
-
date: 2016-
|
89
|
+
date: 2016-10-03 00:00:00.000000000 Z
|
90
90
|
dependencies:
|
91
91
|
- !ruby/object:Gem::Dependency
|
92
92
|
name: metasploit-concern
|
metadata.gz.sig
CHANGED
Binary file
|