metasploit-credential 6.0.2 → 6.0.4

Sign up to get free protection for your applications and to get access to all the features.
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