|
212 | 212 | realm: nil, |
213 | 213 | workspace: framework.db.workspace) |
214 | 214 | end |
| 215 | + let!(:pkcs12_subject) { '/C=FR/O=MyOrg/OU=MyUnit/CN=SubjectTestName' } |
| 216 | + let!(:pkcs12_issuer) { '/C=US/O=MyIssuer/OU=MyIssuerUnit/CN=IssuerTestName' } |
| 217 | + let!(:pkcs12_ca) { 'testCA' } |
| 218 | + let!(:pkcs12_adcs_template) { 'TestTemplate' } |
| 219 | + let!(:pkcs12_core) do |
| 220 | + priv = FactoryBot.create(:metasploit_credential_pkcs12_with_ca_and_adcs_template, |
| 221 | + subject: pkcs12_subject, |
| 222 | + issuer: pkcs12_issuer, |
| 223 | + adcs_ca: pkcs12_ca, |
| 224 | + adcs_template: pkcs12_adcs_template) |
| 225 | + FactoryBot.create(:metasploit_credential_core, |
| 226 | + origin: FactoryBot.create(:metasploit_credential_origin_import), |
| 227 | + private: priv, |
| 228 | + public: nil, |
| 229 | + realm: nil, |
| 230 | + workspace: framework.db.workspace) |
| 231 | + end |
215 | 232 |
|
216 | | - # # Somehow this is hitting a unique constraint on Cores with the same |
217 | | - # # Public, even though it has a different Private. Skip for now |
218 | | - # let!(:ntlm_core) do |
219 | | - # priv = FactoryBot.create(:metasploit_credential_ntlm_hash, data: ntlm_hash) |
220 | | - # FactoryBot.create(:metasploit_credential_core, |
221 | | - # origin: FactoryBot.create(:metasploit_credential_origin_import), |
222 | | - # private: priv, |
223 | | - # public: pub, |
224 | | - # realm: nil, |
225 | | - # workspace: framework.db.workspace) |
226 | | - # end |
227 | | - # let!(:nonreplayable_core) do |
228 | | - # priv = FactoryBot.create(:metasploit_credential_nonreplayable_hash, data: 'asdf') |
229 | | - # FactoryBot.create(:metasploit_credential_core, |
230 | | - # origin: FactoryBot.create(:metasploit_credential_origin_import), |
231 | | - # private: priv, |
232 | | - # public: pub, |
233 | | - # realm: nil, |
234 | | - # workspace: framework.db.workspace) |
235 | | - # end |
| 233 | + let!(:ntlm_core) do |
| 234 | + priv = FactoryBot.create(:metasploit_credential_ntlm_hash, data: ntlm_hash) |
| 235 | + FactoryBot.create(:metasploit_credential_core, |
| 236 | + origin: FactoryBot.create(:metasploit_credential_origin_import), |
| 237 | + private: priv, |
| 238 | + public: pub, |
| 239 | + realm: nil, |
| 240 | + workspace: framework.db.workspace) |
| 241 | + end |
| 242 | + let!(:nonreplayable_core) do |
| 243 | + priv = FactoryBot.create(:metasploit_credential_nonreplayable_hash, data: 'asdf') |
| 244 | + FactoryBot.create(:metasploit_credential_core, |
| 245 | + origin: FactoryBot.create(:metasploit_credential_origin_import), |
| 246 | + private: priv, |
| 247 | + public: pub, |
| 248 | + realm: nil, |
| 249 | + workspace: framework.db.workspace) |
| 250 | + end |
236 | 251 |
|
237 | 252 | after(:example) do |
238 | | - # ntlm_core.destroy |
| 253 | + ntlm_core.destroy |
239 | 254 | password_core.destroy |
240 | | - # nonreplayable_core.destroy |
| 255 | + nonreplayable_core.destroy |
| 256 | + pkcs12_core.destroy |
241 | 257 | end |
242 | 258 |
|
243 | 259 | context 'password' do |
|
283 | 299 |
|
284 | 300 | context 'ntlm' do |
285 | 301 | it 'should show just the ntlm' do |
286 | | - skip 'Weird uniqueness constraint on Core (workspace_id, public_id)' |
287 | 302 |
|
288 | 303 | creds.cmd_creds('-t', 'ntlm') |
289 | 304 | expect(@output.join("\n")).to match_table <<~TABLE |
290 | 305 | Credentials |
291 | 306 | =========== |
292 | 307 |
|
293 | | - host origin service public private realm private_type JtR Format cracked_password |
294 | | - ---- ------ ------- ------ ------- ----- ------------ ---------- ---------------- |
295 | | - thisuser 1443d06412d8c0e6e72c57ef50f76a05:27c433245e4763d074d30a05aae0af2c NTLM hash |
| 308 | + host origin service public private realm private_type JtR Format cracked_password |
| 309 | + ---- ------ ------- ------ ------- ----- ------------ ---------- ---------------- |
| 310 | + thisuser 1443d06412d8c0e6e72c57ef50f76a05:27c433245e4763d074d30a05aae0af2c NTLM hash |
| 311 | +
|
| 312 | + TABLE |
| 313 | + end |
| 314 | + end |
| 315 | + |
| 316 | + context 'nonreplayable' do |
| 317 | + it 'should show just the ntlm' do |
| 318 | + |
| 319 | + creds.cmd_creds('-t', 'hash') |
| 320 | + expect(@output.join("\n")).to match_table <<~TABLE |
| 321 | + Credentials |
| 322 | + =========== |
| 323 | +
|
| 324 | + host origin service public private realm private_type JtR Format cracked_password |
| 325 | + ---- ------ ------- ------ ------- ----- ------------ ---------- ---------------- |
| 326 | + thisuser asdf Nonreplayable hash |
| 327 | +
|
| 328 | + TABLE |
| 329 | + end |
| 330 | + end |
| 331 | + |
| 332 | + context 'pkcs12' do |
| 333 | + it 'should show just the pkcs12' do |
| 334 | + private_str = "subject:#{pkcs12_subject},issuer:#{pkcs12_issuer},ADCS CA:#{pkcs12_ca},ADCS template:#{pkcs12_adcs_template}" |
| 335 | + private_str = "#{private_str[0,76]} (TRUNCATED)" |
| 336 | + creds.cmd_creds('-t', 'pkcs12') |
| 337 | + expect(@output.join("\n")).to match_table <<~TABLE |
| 338 | + Credentials |
| 339 | + =========== |
| 340 | +
|
| 341 | + host origin service public private realm private_type JtR Format cracked_password |
| 342 | + ---- ------ ------- ------ ------- ----- ------------ ---------- ---------------- |
| 343 | + #{private_str} Pkcs12 (pfx) |
296 | 344 |
|
297 | 345 | TABLE |
298 | 346 | end |
|
479 | 527 | }.to_not change { Metasploit::Credential::Core.count } |
480 | 528 | end |
481 | 529 | end |
| 530 | + context 'pkcs12' do |
| 531 | + let(:priv) { FactoryBot.build(:metasploit_credential_pkcs12) } |
| 532 | + before(:each) do |
| 533 | + @file = Tempfile.new('mypkcs12.pfx') |
| 534 | + @file.write(Base64.strict_decode64(priv.data)) |
| 535 | + @file.close |
| 536 | + end |
| 537 | + it 'creates a core if one does not exist' do |
| 538 | + expect { |
| 539 | + creds.cmd_creds('add', "pkcs12:#{@file.path}") |
| 540 | + }.to change { Metasploit::Credential::Core.count }.by 1 |
| 541 | + end |
| 542 | + it 'does not create a core if it already exists' do |
| 543 | + FactoryBot.create(:metasploit_credential_core, |
| 544 | + origin: FactoryBot.create(:metasploit_credential_origin_import), |
| 545 | + private: priv, |
| 546 | + public: nil, |
| 547 | + realm: nil, |
| 548 | + workspace: framework.db.workspace) |
| 549 | + expect { |
| 550 | + creds.cmd_creds('add', "pkcs12:#{@file.path}") |
| 551 | + }.to_not change { Metasploit::Credential::Core.count } |
| 552 | + 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 |
| 588 | + end |
482 | 589 | end |
483 | 590 | context 'realm-types' do |
484 | 591 | Metasploit::Model::Realm::Key::SHORT_NAMES.each do |short_name, long_name| |
|
0 commit comments