Skip to content

Commit 7f8a762

Browse files
Update ms_icpr and creds to reflect the changes in the Pkcs12 data model
- a separate field is now used for metadata (`private_metadata`) when creating a new Pkcs12 - the `creds` command now support adding an encrypted Pkcs12 with a password
1 parent 6802e83 commit 7f8a762

File tree

8 files changed

+96
-45
lines changed

8 files changed

+96
-45
lines changed

.github/workflows/command_shell_acceptance.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ jobs:
132132
run: git config --system core.longpaths true
133133

134134
- name: Setup Ruby
135+
run: git config --system core.longpaths true
135136
env:
136137
BUNDLE_FORCE_RUBY_PLATFORM: true
137138
uses: ruby/setup-ruby@v1

.github/workflows/shared_meterpreter_acceptance.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ jobs:
196196
run: git config --system core.longpaths true
197197

198198
- name: Setup Ruby
199+
run: git config --system core.longpaths true
199200
env:
200201
BUNDLE_FORCE_RUBY_PLATFORM: true
201202
# Required for macos13 pg gem compilation

Gemfile

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ source 'https://rubygems.org'
44
gemspec name: 'metasploit-framework'
55

66
gem 'metasploit-credential', git: 'https://github.com/cdelafuente-r7/metasploit-credential', branch: 'enh/MS-9710/add_pkcs12_metadata'
7+
gem 'metasploit-model', git: 'https://github.com/cdelafuente-r7/metasploit-model', branch: 'feat/model/search/operation/jsonb'
8+
gem 'metasploit_data_models', git: 'https://github.com/cdelafuente-r7/metasploit_data_models', branch: 'enh/visitor/jsonb'
79

810
# separate from test as simplecov is not run on travis-ci
911
group :coverage do

Gemfile.lock

Lines changed: 29 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
GIT
22
remote: https://github.com/cdelafuente-r7/metasploit-credential
3-
revision: acc5a012f4bc7e7774af059e778b947cd994da1e
3+
revision: 6c8554df2feab43489ca86eada790970e9749fb3
44
branch: enh/MS-9710/add_pkcs12_metadata
55
specs:
66
metasploit-credential (6.0.12)
@@ -14,6 +14,32 @@ GIT
1414
rubyntlm
1515
rubyzip
1616

17+
GIT
18+
remote: https://github.com/cdelafuente-r7/metasploit-model
19+
revision: 925a11f61f02123f29e32bb196b374390d36beb6
20+
branch: feat/model/search/operation/jsonb
21+
specs:
22+
metasploit-model (5.0.3)
23+
activemodel (~> 7.0)
24+
activesupport (~> 7.0)
25+
railties (~> 7.0)
26+
27+
GIT
28+
remote: https://github.com/cdelafuente-r7/metasploit_data_models
29+
revision: 34fc27d3059c919eac98cf2a8061c31146189a26
30+
branch: enh/visitor/jsonb
31+
specs:
32+
metasploit_data_models (6.0.6)
33+
activerecord (~> 7.0)
34+
activesupport (~> 7.0)
35+
arel-helpers
36+
metasploit-concern
37+
metasploit-model (>= 3.1)
38+
pg
39+
railties (~> 7.0)
40+
recog
41+
webrick
42+
1743
PATH
1844
remote: .
1945
specs:
@@ -309,21 +335,7 @@ GEM
309335
activesupport (~> 7.0)
310336
railties (~> 7.0)
311337
zeitwerk
312-
metasploit-model (5.0.2)
313-
activemodel (~> 7.0)
314-
activesupport (~> 7.0)
315-
railties (~> 7.0)
316338
metasploit-payloads (2.0.189)
317-
metasploit_data_models (6.0.6)
318-
activerecord (~> 7.0)
319-
activesupport (~> 7.0)
320-
arel-helpers
321-
metasploit-concern
322-
metasploit-model (>= 3.1)
323-
pg
324-
railties (~> 7.0)
325-
recog
326-
webrick
327339
metasploit_payloads-mettle (1.0.35)
328340
method_source (1.1.0)
329341
mime-types (3.6.0)
@@ -596,6 +608,8 @@ DEPENDENCIES
596608
memory_profiler
597609
metasploit-credential!
598610
metasploit-framework!
611+
metasploit-model!
612+
metasploit_data_models!
599613
octokit
600614
pry-byebug
601615
rake

db/schema.rb

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.0].define(version: 2022_12_09_005658) do
13+
ActiveRecord::Schema[7.0].define(version: 2025_02_04_172657) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "plpgsql"
1616

@@ -314,6 +314,7 @@
314314
t.datetime "created_at", precision: nil, null: false
315315
t.datetime "updated_at", precision: nil, null: false
316316
t.string "jtr_format"
317+
t.jsonb "metadata", default: {}, null: false
317318
t.index "type, decode(md5(data), 'hex'::text)", name: "index_metasploit_credential_privates_on_type_and_data_pkcs12", unique: true, where: "((type)::text = 'Metasploit::Credential::Pkcs12'::text)"
318319
t.index "type, decode(md5(data), 'hex'::text)", name: "index_metasploit_credential_privates_on_type_and_data_sshkey", unique: true, where: "((type)::text = 'Metasploit::Credential::SSHKey'::text)"
319320
t.index ["type", "data"], name: "index_metasploit_credential_privates_on_type_and_data", unique: true, where: "(NOT (((type)::text = 'Metasploit::Credential::SSHKey'::text) OR ((type)::text = 'Metasploit::Credential::Pkcs12'::text)))"

lib/msf/core/exploit/remote/ms_icpr.rb

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,8 @@ def do_request_cert(icpr, opts)
251251
workspace_id: myworkspace_id,
252252
username: upn || datastore['SMBUser'],
253253
private_type: :pkcs12,
254-
private_data: Metasploit::Credential::Pkcs12.build_data(
255-
# pkcs12 is a binary format, but for persisting we Base64 encode it
256-
pkcs12: Base64.strict_encode64(pkcs12.to_der),
257-
ca: datastore['CA'],
258-
adcs_template: cert_template
259-
),
254+
private_data: Base64.strict_encode64(pkcs12.to_der),
255+
private_metadata: { adcs_ca: datastore['CA'], adcs_template: cert_template },
260256
origin_type: :service,
261257
module_fullname: fullname
262258
}

lib/msf/ui/console/command_dispatcher/creds.rb

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,19 @@ def cmd_creds_help
100100
print_line "Usage - Adding credentials:"
101101
print_line " creds add uses the following named parameters."
102102
{
103-
user: 'Public, usually a username',
104-
password: 'Private, private_type Password.',
105-
ntlm: 'Private, private_type NTLM Hash.',
106-
postgres: 'Private, private_type postgres MD5',
107-
pkcs12: 'Private, private_type pkcs12 archive file, must be a file path.',
108-
'ssh-key' => 'Private, private_type SSH key, must be a file path.',
109-
hash: 'Private, private_type Nonreplayable hash',
110-
jtr: 'Private, private_type John the Ripper hash type.',
111-
realm: 'Realm, ',
112-
'realm-type' => "Realm, realm_type (#{Metasploit::Model::Realm::Key::SHORT_NAMES.keys.join(' ')}), defaults to domain.",
113-
ca: 'CA, Certificate Authority that issued the pkcs12 certificate',
114-
'adcs-template' => 'ADCS Template, template used to issue the pkcs12 certificate'
103+
user: 'Public, usually a username',
104+
password: 'Private, private_type Password.',
105+
ntlm: 'Private, private_type NTLM Hash.',
106+
postgres: 'Private, private_type postgres MD5',
107+
pkcs12: 'Private, private_type pkcs12 archive file, must be a file path.',
108+
'ssh-key' => 'Private, private_type SSH key, must be a file path.',
109+
hash: 'Private, private_type Nonreplayable hash',
110+
jtr: 'Private, private_type John the Ripper hash type.',
111+
realm: 'Realm, ',
112+
'realm-type' => "Realm, realm_type (#{Metasploit::Model::Realm::Key::SHORT_NAMES.keys.join(' ')}), defaults to domain.",
113+
'adcs-ca' => 'CA, Certificate Authority that issued the pkcs12 certificate',
114+
'adcs-template' => 'ADCS Template, template used to issue the pkcs12 certificate',
115+
'pkcs12-password' => 'The password to decrypt the Pkcs12, defaults to an empty password'
115116
}.each_pair do |keyword, description|
116117
print_line " #{keyword.to_s.ljust 10}: #{description}"
117118
end
@@ -208,7 +209,7 @@ def creds_add(*args)
208209
end
209210

210211
begin
211-
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','address','port','protocol', 'service-name', 'jtr', 'pkcs12', 'postgres', 'ca', 'adcs-template')
212+
params.assert_valid_keys('user','password','realm','realm-type','ntlm','ssh-key','hash','address','port','protocol', 'service-name', 'jtr', 'pkcs12', 'postgres', 'adcs-ca', 'adcs-template', 'pkcs12-password')
212213
rescue ArgumentError => e
213214
print_error(e.message)
214215
end
@@ -277,11 +278,11 @@ def creds_add(*args)
277278
print_error("Failed to add pkcs12 archive: #{e}")
278279
end
279280
data[:private_type] = :pkcs12
280-
data[:private_data] = Metasploit::Credential::Pkcs12.build_data(
281-
pkcs12: pkcs12_data,
282-
ca: params['ca'],
283-
adcs_template: params['adcs-template']
284-
)
281+
data[:private_data] = pkcs12_data
282+
data[:private_metadata] = {}
283+
data[:private_metadata][:adcs_ca] = params['adcs-ca'] if params['adcs-ca']
284+
data[:private_metadata][:adcs_template] = params['adcs-template'] if params['adcs-template']
285+
data[:private_metadata][:pkcs12_password] = params['pkcs12-password'] if params['pkcs12-password']
285286
end
286287

287288
if params.key? 'hash'
@@ -311,7 +312,7 @@ def creds_add(*args)
311312
framework.db.create_credential(data)
312313
end
313314
rescue ActiveRecord::RecordInvalid => e
314-
print_error("Failed to add #{data['private_type']}: #{e}")
315+
print_error("Failed to add #{data[:private_type]}: #{e}")
315316
end
316317
end
317318

spec/lib/msf/ui/console/command_dispatcher/creds_spec.rb

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@
220220
priv = FactoryBot.create(:metasploit_credential_pkcs12_with_ca_and_adcs_template,
221221
subject: pkcs12_subject,
222222
issuer: pkcs12_issuer,
223-
ca: pkcs12_ca,
223+
adcs_ca: pkcs12_ca,
224224
adcs_template: pkcs12_adcs_template)
225225
FactoryBot.create(:metasploit_credential_core,
226226
origin: FactoryBot.create(:metasploit_credential_origin_import),
@@ -331,7 +331,7 @@
331331

332332
context 'pkcs12' do
333333
it 'should show just the pkcs12' do
334-
private_str = "subject:#{pkcs12_subject},issuer:#{pkcs12_issuer},CA:#{pkcs12_ca},ADCS_template:#{pkcs12_adcs_template}"
334+
private_str = "subject:#{pkcs12_subject},issuer:#{pkcs12_issuer},ADCS CA:#{pkcs12_ca},ADCS template:#{pkcs12_adcs_template}"
335335
private_str = "#{private_str[0,76]} (TRUNCATED)"
336336
creds.cmd_creds('-t', 'pkcs12')
337337
expect(@output.join("\n")).to match_table <<~TABLE
@@ -528,10 +528,10 @@
528528
end
529529
end
530530
context 'pkcs12' do
531-
let(:priv) { FactoryBot.create(:metasploit_credential_pkcs12) }
531+
let(:priv) { FactoryBot.build(:metasploit_credential_pkcs12) }
532532
before(:each) do
533533
@file = Tempfile.new('mypkcs12.pfx')
534-
@file.write(Base64.strict_decode64(priv.pkcs12))
534+
@file.write(Base64.strict_decode64(priv.data))
535535
@file.close
536536
end
537537
it 'creates a core if one does not exist' do
@@ -550,6 +550,41 @@
550550
creds.cmd_creds('add', "pkcs12:#{@file.path}")
551551
}.to_not change { Metasploit::Credential::Core.count }
552552
end
553+
554+
context 'with a password' do
555+
let(:pkcs12_password) { 'mypass' }
556+
let(:priv) {
557+
FactoryBot.build(:metasploit_credential_pkcs12,
558+
pkcs12_password: pkcs12_password,
559+
metadata: { pkcs12_password: pkcs12_password }
560+
)
561+
}
562+
563+
it 'creates a core if the password is correct' do
564+
expect {
565+
creds.cmd_creds('add', "pkcs12:#{@file.path}", "pkcs12-password:#{pkcs12_password}")
566+
}.to change { Metasploit::Credential::Core.count }.by 1
567+
end
568+
569+
it 'does not creates a core if the password is incorrect' do
570+
expect {
571+
creds.cmd_creds('add', "pkcs12:#{@file.path}", "pkcs12-password:wrongpass")
572+
}.to_not change { Metasploit::Credential::Core.count }
573+
end
574+
end
575+
576+
context 'with metadata other than password' do
577+
let(:adcs_ca) { 'myca' }
578+
let(:adcs_template) { 'mytemplate' }
579+
580+
it 'creates a core if the password is correct' do
581+
expect {
582+
creds.cmd_creds('add', "pkcs12:#{@file.path}", "adcs-ca:#{adcs_ca}", "adcs-template:#{adcs_template}")
583+
}.to change { Metasploit::Credential::Core.count }.by 1
584+
expect(Metasploit::Credential::Pkcs12.first.adcs_ca).to eq(adcs_ca)
585+
expect(Metasploit::Credential::Pkcs12.first.adcs_template).to eq(adcs_template)
586+
end
587+
end
553588
end
554589
end
555590
context 'realm-types' do

0 commit comments

Comments
 (0)