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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZTI2NTNmNzJkMWE3MzRjMTYxZjk5NDE4YjFiOWVkM2I3YTZkYzE2OQ==
4
+ ODI2ZjA2Nzg2ODU2YmRlNDlmODA5N2UzYTcyNmVlM2FlMjQ1MjdkYQ==
5
5
  data.tar.gz: !binary |-
6
- N2IzZWIyZDk4NTUxMDJjMDY5NjFkZTBjM2I0YWY1OGZiZjE1ZGU5NA==
6
+ YmNjNWJkM2UyMDVkYzMwZTQxODU3YTRiMThhMjA1NGIwYjJjODNjMg==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- MzY4ZDdmYmVkYzM1NTAzNzU3OWU2NWQwYTA5ODQ5ODcyNzViNzUxNTQyOGM5
10
- Y2RjMjIwYjEwMDdkYTQwOTk2MzQ3ZWZmOWJhMTE5ODJlNDQxZDk3NTBiNjNm
11
- YWUwOGRmZjBlY2FhYWQ3OGJhMmFkMGVkNmYzOWQ3NmI3M2U2YzM=
9
+ Mjc3ODk2NTk3Mjg3NzZkODc0YzM4MmE1YTE5OTYxNzE1MDNiMjIxMGJjMmZl
10
+ Y2FhODdlOTllZThlOGMwZDhmNThhMDFlOWEzZTI4NDNmYjMzMTVjOWE5NjVk
11
+ YTk0YjcyZWNlZmUyZmEyNWViMTE1MGFmMzE1MjMzMmIzM2VjN2U=
12
12
  data.tar.gz: !binary |-
13
- OGQyMWQyOTNjMmI4ZGY1OWEwNGNjNWRmMGIyZGMwYmUxYjBkMmFjMGRiNzIw
14
- OWJmZjI4ODBhZWVkZmQ5NTI1YzQ4Yjg2ZjJjMjhjZThiYmQ4NzlmODczZmEz
15
- NDFiMTUxNzAyOGM3NjI1YjhkZWNiZDAxN2RkNWYwNzBmZDIwYTU=
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, :realm_key, :realm_value, :host_address, :service_port, :service_name, :service_protocol]
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 = row['host_address']
111
- service_port = row['service_port']
112
- service_protocol = row['service_protocol']
113
- service_name = row['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
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
- defaults: &defaults
2
+ development: &pgsql
3
3
  adapter: postgresql
4
- username: msf
5
- password: pass123
4
+ database: metasploit_credential_development
6
5
  host: localhost
7
6
  port: 5432
8
- pool: 50
7
+ pool: 5
9
8
  timeout: 5
10
9
 
11
- development:
12
- database: metasploit_cr
13
- <<: *defaults
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
- database: metasploit_cr_test
17
- min_messages: WARNING
18
- <<: *defaults
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
- origin {FactoryGirl.build :metasploit_credential_origin_import }
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
- username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol
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
- username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol
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
- username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol
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
- username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol
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
- username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol
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
- username,private_data
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
- username,private_type,private_data,realm_key,realm_value,host_address,service_port,service_name,service_protocol
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
- core_exporter.line_for_core(core).values.should == [core.public.username, core.private.type,
64
- core.private.data, core.realm.key, core.realm.value]
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
- core_exporter.line_for_login(login).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]
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 private type' do
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.10
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.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