metasploit-credential 6.0.2 → 6.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 416819532338ddf04c5f8305550aa8c3b728223a6ddfe0e8aff141c4690f84bb
4
- data.tar.gz: 1a1f815cde01159da2d994b3bc87a90c98a055957c317841d4c5f64381f5a4cc
3
+ metadata.gz: 97884e997f5fe9428e4fc79f0b4a9e4a4e51a06363b372a2fa1affa0dffba6d5
4
+ data.tar.gz: 37e4b1a543e249e7facb0c6570efd104d4bf347922636b561aecb78bab0602a8
5
5
  SHA512:
6
- metadata.gz: bf49d45cfb1f1e5b80795d117947ae7bfe15c507d62d37e7e70b80e6b47e03bfdee5ed5e21f071f5746cb7d20e7ba878049cb4c4f44106f98c831fcd13624b88
7
- data.tar.gz: 056fd6587af57c9078459859e43284fb809fb394132919ed70ed237693e2edc1e3eea66ba70b6a1cad1d532959b1aab8d4515cbfbffd3be923c837cd7034fc9a
6
+ metadata.gz: 23da300c2d52cd12a8aeb398010b21d2542ab4f88f59946fabde21efbb3554c30f36b32839961abef13c43528324ddacc807d68872cc9df3bbf2e47d31c66905
7
+ data.tar.gz: 90f93c7bd036e2f6b328dca97707d5e85bd40a257cb6f7dba928d0d6fd983cd295e38b3052cb6aae271c37bd730e4b5c36e71feed1e1dc561bb0b163c207d098
checksums.yaml.gz.sig CHANGED
Binary file
@@ -0,0 +1,84 @@
1
+ require 'openssl'
2
+ require 'base64'
3
+
4
+ # A private Pkcs12 file.
5
+ class Metasploit::Credential::Pkcs12 < Metasploit::Credential::Private
6
+ #
7
+ # Attributes
8
+ #
9
+
10
+ # @!attribute data
11
+ # A private pkcs12 file, base64 encoded - i.e. starting with 'MIIMhgIBAzCCDFAGCSqGSIb3DQEHAaCC....'
12
+ #
13
+ # @return [String]
14
+
15
+ #
16
+ #
17
+ # Validations
18
+ #
19
+ #
20
+
21
+ #
22
+ # Attribute Validations
23
+ #
24
+
25
+ validates :data,
26
+ presence: true
27
+ #
28
+ # Method Validations
29
+ #
30
+
31
+ validate :readable
32
+
33
+ #
34
+ # Instance Methods
35
+ #
36
+
37
+ # Converts the private pkcs12 data in {#data} to an `OpenSSL::PKCS12` instance.
38
+ #
39
+ # @return [OpenSSL::PKCS12]
40
+ # @raise [ArgumentError] if {#data} cannot be loaded
41
+ def openssl_pkcs12
42
+ if data
43
+ begin
44
+ password = ''
45
+ OpenSSL::PKCS12.new(Base64.strict_decode64(data), password)
46
+ rescue OpenSSL::PKCS12::PKCS12Error => error
47
+ raise ArgumentError.new(error)
48
+ end
49
+ end
50
+ end
51
+
52
+ # The {#data key data}'s fingerprint, suitable for displaying to the
53
+ # user.
54
+ #
55
+ # @return [String]
56
+ def to_s
57
+ return '' unless data
58
+
59
+ cert = openssl_pkcs12.certificate
60
+ result = []
61
+ result << "subject:#{cert.subject.to_s}"
62
+ result << "issuer:#{cert.issuer.to_s}"
63
+ result.join(',')
64
+ end
65
+
66
+ private
67
+
68
+ #
69
+ # Validates that {#data} can be read by OpenSSL and a `OpenSSL::PKCS12` can be created from {#data}. Any exception
70
+ # raised will be reported as a validation error.
71
+ #
72
+ # @return [void]
73
+ def readable
74
+ if data
75
+ begin
76
+ openssl_pkcs12
77
+ rescue => error
78
+ errors.add(:data, "#{error.class} #{error}")
79
+ end
80
+ end
81
+ end
82
+
83
+ Metasploit::Concern.run(self)
84
+ end
@@ -74,6 +74,7 @@ class Metasploit::Credential::Private < ApplicationRecord
74
74
  Metasploit::Credential::Password
75
75
  Metasploit::Credential::SSHKey
76
76
  Metasploit::Credential::KrbEncKey
77
+ Metasploit::Credential::Pkcs12
77
78
  }
78
79
 
79
80
  #
@@ -57,6 +57,7 @@ en:
57
57
  metasploit/credential/ntlm_hash: "NTLM hash"
58
58
  metasploit/credential/ssh_key: "SSH key"
59
59
  metasploit/credential/krb_enc_key: 'Krb enc key'
60
+ metasploit/credential/pkcs12: 'Pkcs12 (pfx)'
60
61
  errors:
61
62
  models:
62
63
  metasploit/credential/core:
@@ -83,10 +84,14 @@ en:
83
84
  attributes:
84
85
  data:
85
86
  format: "is not in the KrbEncKey data format of 'msf_krbenckey:<ENCTYPE>:<KEY>:<SALT>', where the key and salt are in hexadecimal characters"
87
+ metasploit/credential/pkcs12:
88
+ attributes:
89
+ data:
90
+ format: "is not a Base64 encoded pkcs12 file without a password"
86
91
  metasploit/credential/ssh_key:
87
92
  attributes:
88
93
  data:
89
- encrypted: "is encrypted, but Metasploit::Credential::SSHKey only supports unencrypred private keys."
94
+ encrypted: "is encrypted, but Metasploit::Credential::SSHKey only supports unencrypted private keys."
90
95
  not_private: "is not a private key."
91
96
  errors:
92
97
  messages:
@@ -0,0 +1,32 @@
1
+ class CreateIndexOnPrivateDataAndTypeForPkcs12 < ActiveRecord::Migration[6.1]
2
+ def up
3
+ # Drop the existing index created by 20161107153145_recreate_index_on_private_data_and_type.rb, and recreate it
4
+ # with Metasploit::Credential::Pkcs12 ignored
5
+ remove_index :metasploit_credential_privates, [:type, :data], if_exists: true
6
+ change_table :metasploit_credential_privates do |t|
7
+ t.index [:type, :data],
8
+ unique: true,
9
+ where: "NOT (type = 'Metasploit::Credential::SSHKey' or type = 'Metasploit::Credential::Pkcs12')"
10
+ end
11
+
12
+ # Create a new index similar to 20161107203710_create_index_on_private_data_and_type_for_ssh_key.rb
13
+ sql = <<~EOF
14
+ CREATE UNIQUE INDEX IF NOT EXISTS "index_metasploit_credential_privates_on_type_and_data_pkcs12" ON
15
+ "metasploit_credential_privates" ("type", decode(md5(data), 'hex'))
16
+ WHERE type in ('Metasploit::Credential::Pkcs12')
17
+ EOF
18
+ execute(sql)
19
+ end
20
+
21
+ def down
22
+ # Restore the original metasploit_credential_privates index from /Users/adfoster/Documents/code/metasploit-credential/db/migrate/20161107153145_recreate_index_on_private_data_and_type.rb
23
+ # XXX: this would crash if there are any Pkcs12 entries present, so for the simplicity of avoiding a data migration we keep the pkcs12 type ommitted from the index
24
+ remove_index :metasploit_credential_privates, [:type, :data], if_exists: true
25
+ change_table :metasploit_credential_privates do |t|
26
+ t.index [:type, :data],
27
+ unique: true,
28
+ where: "NOT (type = 'Metasploit::Credential::SSHKey' or type = 'Metasploit::Credential::Pkcs12')"
29
+ end
30
+ remove_index :metasploit_credential_privates, name: :index_metasploit_credential_privates_on_type_and_data_pkcs12, if_exists: true
31
+ end
32
+ end
@@ -479,6 +479,8 @@ module Metasploit::Credential::Creation
479
479
  private_object = Metasploit::Credential::Password.where(data: private_data).first_or_create
480
480
  when :ssh_key
481
481
  private_object = Metasploit::Credential::SSHKey.where(data: private_data).first_or_create
482
+ when :pkcs12
483
+ private_object = Metasploit::Credential::Pkcs12.where(data: private_data).first_or_create
482
484
  when :krb_enc_key
483
485
  private_object = Metasploit::Credential::KrbEncKey.where(data: private_data).first_or_create
484
486
  when :ntlm_hash
@@ -3,7 +3,7 @@
3
3
  module Metasploit
4
4
  module Credential
5
5
  # VERSION is managed by GemRelease
6
- VERSION = '6.0.2'
6
+ VERSION = '6.0.4'
7
7
 
8
8
  # @return [String]
9
9
  #
@@ -43,6 +43,7 @@ module Metasploit
43
43
  autoload :Origin
44
44
  autoload :Password
45
45
  autoload :PasswordHash
46
+ autoload :Pkcs12
46
47
  autoload :PostgresMD5
47
48
  autoload :Private
48
49
  autoload :Public
@@ -1,6 +1,6 @@
1
1
  development: &pgsql
2
2
  adapter: postgresql
3
- database: metasploit-credential_development2
3
+ database: metasploit-credential_development3
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-credential_test2
13
+ database: metasploit-credential_test3
@@ -0,0 +1,37 @@
1
+ FactoryBot.define do
2
+ factory :metasploit_credential_pkcs12,
3
+ class: Metasploit::Credential::Pkcs12 do
4
+ transient do
5
+ # key size tuned for speed. DO NOT use for production, it is below current recommended key size of 2048
6
+ key_size { 1024 }
7
+ # signing algorithm for the pkcs12 cert
8
+ signing_algorithm { 'SHA256' }
9
+ # the cert subject
10
+ subject { '/C=BE/O=Test/OU=Test/CN=Test' }
11
+ # the cert issuer
12
+ issuer { '/C=BE/O=Test/OU=Test/CN=Test' }
13
+ end
14
+
15
+ data {
16
+ password = ''
17
+ pkcs12_name = ''
18
+
19
+ private_key = OpenSSL::PKey::RSA.new(key_size)
20
+ public_key = private_key.public_key
21
+
22
+ cert = OpenSSL::X509::Certificate.new
23
+ cert.subject = OpenSSL::X509::Name.parse(subject)
24
+ cert.issuer = OpenSSL::X509::Name.parse(issuer)
25
+ cert.not_before = Time.now
26
+ cert.not_after = Time.now + 365 * 24 * 60 * 60
27
+ cert.public_key = public_key
28
+ cert.serial = 0x0
29
+ cert.version = 2
30
+ cert.sign(private_key, OpenSSL::Digest.new(signing_algorithm))
31
+
32
+ pkcs12 = OpenSSL::PKCS12.create(password, pkcs12_name, private_key, cert)
33
+ pkcs12_base64 = Base64.strict_encode64(pkcs12.to_der)
34
+ pkcs12_base64
35
+ }
36
+ end
37
+ end
@@ -134,20 +134,30 @@ RSpec.describe Metasploit::Credential::Creation do
134
134
  nonreplayable_hash: "Metasploit::Credential::NonreplayableHash",
135
135
  ntlm_hash: "Metasploit::Credential::NTLMHash",
136
136
  postgres_md5: "Metasploit::Credential::PostgresMD5",
137
- ssh_key: "Metasploit::Credential::SSHKey"
137
+ ssh_key: "Metasploit::Credential::SSHKey",
138
+ krb_enc_key: "Metasploit::Credential::KrbEncKey",
139
+ pkcs12: "Metasploit::Credential::Pkcs12"
138
140
  }.each_pair do |private_type, public_class|
139
141
  context "Origin[manual], Public[Username], Private[#{private_type}]" do
140
142
  let(:ssh_key) {
141
143
  key_class = OpenSSL::PKey.const_get(:RSA)
142
144
  key_class.generate(512).to_s
143
145
  }
146
+ let(:krb_enc_key) {
147
+ FactoryBot.build(:metasploit_credential_krb_enc_key).data
148
+ }
149
+ let(:pkcs12) {
150
+ FactoryBot.build(:metasploit_credential_pkcs12).data
151
+ }
144
152
  let(:private_data) { {
145
153
  password: 'password',
146
154
  blank_password: '',
147
155
  nonreplayable_hash: '435ba65d2e46d35bc656086694868d1ab2c0f9fd',
148
156
  ntlm_hash: 'aad3b435b51404eeaad3b435b51404ee:31d6cfe0d16ae931b73c59d7e0c089c0',
149
157
  postgres_md5: 'md5ac4bbe016b808c3c0b816981f240dcae',
150
- ssh_key: ssh_key
158
+ ssh_key: ssh_key,
159
+ krb_enc_key: krb_enc_key,
160
+ pkcs12: pkcs12
151
161
  }}
152
162
  let(:credential_data) {{
153
163
  workspace_id: workspace.id,
@@ -821,6 +831,16 @@ RSpec.describe Metasploit::Credential::Creation do
821
831
  expect{ test_object.create_credential_private(opts) }.to change{ Metasploit::Credential::KrbEncKey.count }.by(1)
822
832
  end
823
833
  end
834
+
835
+ context 'when :private_type is pkcs12' do
836
+ it 'creates a Metasploit::Credential::Pkcs12' do
837
+ opts = {
838
+ private_data: FactoryBot.build(:metasploit_credential_pkcs12).data,
839
+ private_type: :pkcs12
840
+ }
841
+ expect{ test_object.create_credential_private(opts) }.to change{ Metasploit::Credential::Pkcs12.count }.by(1)
842
+ end
843
+ end
824
844
  end
825
845
 
826
846
  context '#create_credential_core' do
@@ -0,0 +1,116 @@
1
+ RSpec.describe Metasploit::Credential::Pkcs12, type: :model do
2
+ it_should_behave_like 'Metasploit::Concern.run'
3
+
4
+ context 'factories' do
5
+ context 'metasploit_credential_pkcs12' do
6
+ subject(:metasploit_credential_pkcs12) do
7
+ FactoryBot.build(:metasploit_credential_pkcs12)
8
+ end
9
+
10
+ it { is_expected.to be_valid }
11
+ end
12
+ end
13
+
14
+ context 'validations' do
15
+ it { is_expected.to validate_presence_of :data }
16
+
17
+ context 'on #data' do
18
+ subject(:data_errors) do
19
+ pkcs12.errors[:data]
20
+ end
21
+
22
+ let(:pkcs12) do
23
+ FactoryBot.build(:metasploit_credential_pkcs12)
24
+ end
25
+
26
+ context '#readable' do
27
+ context 'with #data' do
28
+ context 'with error' do
29
+ #
30
+ # Shared Examples
31
+ #
32
+
33
+ shared_examples_for 'exception' do
34
+ it 'includes error class' do
35
+ exception_class_name = exception.class.to_s
36
+ expect(
37
+ data_errors.any? { |error|
38
+ error.include? exception_class_name
39
+ }
40
+ ).to be true
41
+ end
42
+
43
+ it 'includes error message' do
44
+ exception_message = exception.to_s
45
+
46
+ expect(
47
+ data_errors.any? { |error|
48
+ error.include? exception_message
49
+ }
50
+ ).to be true
51
+ end
52
+ end
53
+
54
+ #
55
+ # Callbacks
56
+ #
57
+
58
+ before(:example) do
59
+ expect(pkcs12).to receive(:openssl_pkcs12).and_raise(exception)
60
+
61
+ pkcs12.valid?
62
+ end
63
+
64
+ context 'with ArgumentError' do
65
+ let(:exception) do
66
+ ArgumentError.new("Bad Argument")
67
+ end
68
+
69
+ it_should_behave_like 'exception'
70
+ end
71
+
72
+ context 'with OpenSSL::PKCS12::PKCS12Error' do
73
+ let(:exception) do
74
+ OpenSSL::PKCS12::PKCS12Error.new('mac verify failure')
75
+ end
76
+
77
+ it_should_behave_like 'exception'
78
+ end
79
+ end
80
+
81
+ context 'without error' do
82
+ before(:example) do
83
+ pkcs12.valid?
84
+ end
85
+
86
+ it { is_expected.to be_empty }
87
+ end
88
+ end
89
+
90
+ context 'without #data' do
91
+ let(:error) do
92
+ I18n.translate!('errors.messages.blank')
93
+ end
94
+
95
+ #
96
+ # Callbacks
97
+ #
98
+
99
+ before(:example) do
100
+ pkcs12.data = nil
101
+
102
+ pkcs12.valid?
103
+ end
104
+
105
+ it { is_expected.to include(error) }
106
+ end
107
+ end
108
+ end
109
+ end
110
+
111
+ describe 'human name' do
112
+ it 'properly determines the model\'s human name' do
113
+ expect(described_class.model_name.human).to eq('Pkcs12 (pfx)')
114
+ end
115
+ end
116
+ end
@@ -135,6 +135,7 @@ RSpec.describe Metasploit::Credential::Private, type: :model do
135
135
  Metasploit::Credential::Password
136
136
  Metasploit::Credential::SSHKey
137
137
  Metasploit::Credential::KrbEncKey
138
+ Metasploit::Credential::Pkcs12
138
139
  }
139
140
  end
140
141
  end
data.tar.gz.sig CHANGED
Binary file
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: 6.0.2
4
+ version: 6.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Metasploit Hackers
@@ -93,7 +93,7 @@ cert_chain:
93
93
  EknWpNgVhohbot1lfVAMmIhdtOVaRVcQQixWPwprDj/ydB8ryDMDosIMcw+fkoXU
94
94
  9GJsSaSRRYQ9UUkVL27b64okU8D48m8=
95
95
  -----END CERTIFICATE-----
96
- date: 2023-01-31 00:00:00.000000000 Z
96
+ date: 2023-04-11 00:00:00.000000000 Z
97
97
  dependencies:
98
98
  - !ruby/object:Gem::Dependency
99
99
  name: metasploit-concern
@@ -255,6 +255,7 @@ files:
255
255
  - app/models/metasploit/credential/origin/session.rb
256
256
  - app/models/metasploit/credential/password.rb
257
257
  - app/models/metasploit/credential/password_hash.rb
258
+ - app/models/metasploit/credential/pkcs12.rb
258
259
  - app/models/metasploit/credential/postgres_md5.rb
259
260
  - app/models/metasploit/credential/private.rb
260
261
  - app/models/metasploit/credential/public.rb
@@ -288,6 +289,7 @@ files:
288
289
  - db/migrate/20150106201450_old_creds_to_new_creds2.rb
289
290
  - db/migrate/20161107153145_recreate_index_on_private_data_and_type.rb
290
291
  - db/migrate/20161107203710_create_index_on_private_data_and_type_for_ssh_key.rb
292
+ - db/migrate/20221209005658_create_index_on_private_data_and_type_for_pkcs12.rb
291
293
  - lib/metasploit/credential.rb
292
294
  - lib/metasploit/credential/core_validations.rb
293
295
  - lib/metasploit/credential/creation.rb
@@ -366,6 +368,7 @@ files:
366
368
  - spec/factories/metasploit/credential/origin/sessions.rb
367
369
  - spec/factories/metasploit/credential/password_hashes.rb
368
370
  - spec/factories/metasploit/credential/passwords.rb
371
+ - spec/factories/metasploit/credential/pkcs12.rb
369
372
  - spec/factories/metasploit/credential/postgres_md5.rb
370
373
  - spec/factories/metasploit/credential/privates.rb
371
374
  - spec/factories/metasploit/credential/publics.rb
@@ -401,6 +404,7 @@ files:
401
404
  - spec/models/metasploit/credential/origin/session_spec.rb
402
405
  - spec/models/metasploit/credential/password_hash_spec.rb
403
406
  - spec/models/metasploit/credential/password_spec.rb
407
+ - spec/models/metasploit/credential/pkcs12_spec.rb
404
408
  - spec/models/metasploit/credential/postgres_md5_spec.rb
405
409
  - spec/models/metasploit/credential/private_spec.rb
406
410
  - spec/models/metasploit/credential/public_spec.rb
@@ -497,6 +501,7 @@ test_files:
497
501
  - spec/factories/metasploit/credential/origin/sessions.rb
498
502
  - spec/factories/metasploit/credential/password_hashes.rb
499
503
  - spec/factories/metasploit/credential/passwords.rb
504
+ - spec/factories/metasploit/credential/pkcs12.rb
500
505
  - spec/factories/metasploit/credential/postgres_md5.rb
501
506
  - spec/factories/metasploit/credential/privates.rb
502
507
  - spec/factories/metasploit/credential/publics.rb
@@ -532,6 +537,7 @@ test_files:
532
537
  - spec/models/metasploit/credential/origin/session_spec.rb
533
538
  - spec/models/metasploit/credential/password_hash_spec.rb
534
539
  - spec/models/metasploit/credential/password_spec.rb
540
+ - spec/models/metasploit/credential/pkcs12_spec.rb
535
541
  - spec/models/metasploit/credential/postgres_md5_spec.rb
536
542
  - spec/models/metasploit/credential/private_spec.rb
537
543
  - spec/models/metasploit/credential/public_spec.rb
metadata.gz.sig CHANGED
Binary file