Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add certs command & use pkinit if kerberos tickets are not available in cache #19760

Open
wants to merge 6 commits into
base: master
Choose a base branch
from

Conversation

cdelafuente-r7
Copy link
Contributor

@cdelafuente-r7 cdelafuente-r7 commented Dec 20, 2024

This PR does two things:

  1. Add a certs command, similar to klist, that displays and manages Pkcs12 certificates stored in the database.
  2. Wire up Pkcs12 authentication through pkinit automatically when <protocol>::Auth option is set to kerberos and no related kerberos tickets is found in the cache. If a matching certificate is found, it will be used to get a TGT from the KDC using the pkinit protocol.

This PR is based on top of this PR. So, it includes extra commits present in this branch. To review the changes related to this PR only, you can compare branches here.

certs command

This command list the available certificates stored in the creds database (use certs -v to display verbose output). It can also search a pkcs12 by ID or by username. Note that username can include the domain using the UPN format (e.g. [email protected]). The command can also be used to delete and export certificates.

Here is the help output:

msf6 auxiliary(scanner/smb/smb_login) > certs --help
List Pkcs12 certificate bundles in the database
Usage: certs [options] [username[@domain_upn_format]]


OPTIONS:

    -a, --activate    Activates *all* matching pkcs12 entries
    -A, --deactivate  Deactivates *all* matching pkcs12 entries
    -d, --delete      Delete *all* matching pkcs12 entries
    -e, --export      The file path where to export the matching pkcs12 entry
    -h, --help        Help banner
    -i, --index       Pkcs12 entry ID(s) to search for, e.g. `-i 1` or `-i 1,2,3` or `-i 1 -i 2 -i 3`
    -v, --verbose     Verbose output

Automated Pkcs12 authentication

When the user sets <protocol>::Auth to kerberos, the original process will look into the cached tickets and try to find a suitable ticket to authenticate. If no ticket is found, it will use the credentials provided by the user to query fresh new tickets (TGT and TGS). Now, before requesting new tickets using these credentials, the module will look into the database if a pkcs12 certificate can be re-used to request these tickets. The process is transparent to the user. The look up is done based on the provided username and domain.

This automation also also works with schannel authentication. When using a module that supports schannel (only scanner/ldap/ldap_login for now), you can set <protocol>::Auth to schannel. If no Pkcs12 file is provided as an argument, the same look up will occurs in the database to find a matching Pkcs12.

Note that automated Pkcs12 authentication will work with Pkcs12 with the status set to active or when the status is not set at all. You can disable this feature for specific Pkcs12's by using the certs -A command.

Verification

Request a certificate with the admin/dcerpc/icpr_cert module.

For example, exploiting the ESC1 vulnerability:

msf6 auxiliary(admin/dcerpc/icpr_cert) > run verbose=true CA=myca-name RHOSTS=10.100.32.94 username=msfuser password=vagrant CERT_TEMPLATE=ESC1 [email protected]
[*] Running module against 10.100.32.94
[*] 10.100.32.94:445 - Connecting to ICertPassage (ICPR) Remote Protocol
[*] 10.100.32.94:445 - Binding to \cert...
[+] 10.100.32.94:445 - Bound to \cert
[*] 10.100.32.94:445 - Requesting a certificate for user msfuser - alternate UPN: [email protected] - digest algorithm: SHA256 - template: ESC1
[+] 10.100.32.94:445 - The requested certificate was issued.
[*] 10.100.32.94:445 - Certificate UPN: [email protected]
[*] 10.100.32.94:445 - Certificate Policies:
[*] 10.100.32.94:445 -   * 1.3.6.1.5.5.7.3.2 (Client Authentication)
[*] 10.100.32.94:445 - Certificate stored at: /home/n00tmeg/.msf4/loot/20241218141515_default_10.100.32.94_windows.ad.cs_544294.pfx
[*] Auxiliary module execution completed

Check the certs command

msf6 auxiliary(admin/dcerpc/icpr_cert) > certs
Pkcs12
======
id  username       realm         subject    issuer                                              ADCS CA                   ADCS Template  status
--  --------       -----         -------    ------                                              -------                   -------------  ------
1   administrator  mydomi.local  /CN=muser  /DC=local/DC=pro/DC=ad/CN=mssrv-dc-mydomi.local-CA  mssrv-dc-mydomi.local-CA  ESC1           active

Try to search certificate:

msf6 auxiliary(admin/dcerpc/icpr_cert) > certs [email protected]
Pkcs12
======
id  username       realm         subject    issuer                                              ADCS CA                   ADCS Template  status
--  --------       -----         -------    ------                                              -------                   -------------  ------
1   administrator  mydomi.local  /CN=muser  /DC=local/DC=pro/DC=ad/CN=mssrv-dc-mydomi.local-CA  mssrv-dc-mydomi.local-CA  ESC1           active

Select a certificate with an ID:

msf6 auxiliary(admin/dcerpc/icpr_cert) > certs -i 1
Pkcs12
======
id  username       realm         subject    issuer                                              ADCS CA                   ADCS Template  status
--  --------       -----         -------    ------                                              -------                   -------------  ------
1   administrator  mydomi.local  /CN=muser  /DC=local/DC=pro/DC=ad/CN=mssrv-dc-mydomi.local-CA  mssrv-dc-mydomi.local-CA  ESC1           active

Deactivate a certificate:

msf6 auxiliary(scanner/ldap/ldap_login) > certs -A -i 1
Pkcs12
======
id  username       realm         subject    issuer                                              ADCS CA                   ADCS Template  status
--  --------       -----         -------    ------                                              -------                   -------------  ------
1   administrator  mydomi.local  /CN=muser  /DC=local/DC=pro/DC=ad/CN=mssrv-dc-mydomi.local-CA  mssrv-dc-mydomi.local-CA  ESC1           inactive

[*] Deactivated 1 entry

Delete a certificate:

msf6 auxiliary(admin/dcerpc/icpr_cert) > certs -i 1 -d
Pkcs12
======
id  username       realm         subject    issuer                                              ADCS CA                   ADCS Template  status
--  --------       -----         -------    ------                                              -------                   -------------  ------
1   administrator  mydomi.local  /CN=muser  /DC=local/DC=pro/DC=ad/CN=mssrv-dc-mydomi.local-CA  mssrv-dc-mydomi.local-CA  ESC1           active

[*] Deleted 1 entry

Check the automated Pkcs12 authentication

Make sure you don't have any Kerberos ticket in cache:

msf6 auxiliary(admin/dcerpc/icpr_cert) > klist
Kerberos Cache
==============
No tickets

Use the scanner/winrm/winrm_cmd module to execute the whoami command on the target:

msf6 auxiliary(scanner/winrm/winrm_cmd) > run verbose=true RHOSTS=10.100.32.94 Winrm::Auth=kerberos Winrm::Rhostname=mspro-dc username=administrator domain=mydomain.local DomainControllerRhost=10.100.32.94 cmd=whoami
[*] Using stored certificate for [email protected]
[+] 10.100.32.94:88 - Received a valid TGT-Response
[*] 10.100.32.94:5985     - TGT MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20241218141549_default_10.100.32.94_mit.kerberos.cca_125955.bin
[+] 10.100.32.94:88 - Received a valid TGS-Response
[*] 10.100.32.94:5985     - TGS MIT Credential Cache ticket saved to /home/n00tmeg/.msf4/loot/20241218141549_default_10.100.32.94_mit.kerberos.cca_751667.bin
[+] 10.100.32.94:88 - Received a valid delegation TGS-Response
[+] 10.100.32.94:88 - Received AP-REQ. Extracting session key...
ad\administrator
[+] Results saved to /home/n00tmeg/.msf4/loot/20241218141553_default_10.100.32.94_winrm.cmd_result_401191.txt
[*] Scanned 1 of 1 hosts (100% complete)
[*] Auxiliary module execution completed

You should see Using stored certificate for ... message.

Now, verify the ticket were stored in cache:

msf6 auxiliary(scanner/winrm/winrm_cmd) > klist
Kerberos Cache
==============
id  host          principal                   sname                             enctype  issued                     status  path
--  ----          ---------                   -----                             -------  ------                     ------  ----
44  10.100.32.94  [email protected]  krbtgt/[email protected]  AES256   2024-12-18 14:15:49 +0100  active  /home/n00tmeg/.msf4/loot/20241218141549_default_10.100.32.94_mit.kerberos.cca_125955.bin
45  10.100.32.94  [email protected]  http/[email protected]        AES256   2024-12-18 14:15:49 +0100  active  /home/n00tmeg/.msf4/loot/20241218141549_default_10.100.32.94_mit.kerberos.cca_751667.bin

If you re-run the module with the same options, it should now use the cached ticket instead of the certificate.

You can repeat the operation with the following modules:

run verbose=true RHOSTS=10.140.10.78 LDAP::Auth=kerberos username=administrator domain=ad.pro.local LDAP::Rhostname=mspro-dc DomainControllerRhost=10.140.10.78 CreateSession=true

Schannel can also be used the same way:

run verbose=true RHOSTS=10.140.10.78 LDAP::Auth=schannel username=administrator domain=ad.pro.local ssl=true
  • scanner/smb/smb_login
run verbose=true RHOSTS=10.140.10.78 SMB::Auth=kerberos username=administrator domain=ad.pro.local Smb::Rhostname=mspro-dc DomainControllerRhost=10.140.10.78 CreateSession=true

TODO

I noticed the credentials are being saved in the database when using kerberos authentication with the scanner/ldap/ldap_login and scanner/smb/smb_login. This will need to be fixed. This has been fixed.

@cdelafuente-r7 cdelafuente-r7 added enhancement usability Usability improvements labels Dec 20, 2024
@cdelafuente-r7 cdelafuente-r7 force-pushed the feat/pkcs12/certs_command/pkinit branch from c4d21eb to 5e8e292 Compare January 10, 2025 13:34
…base

- Update the `creds` command to add Pkcs12 private credentials with
  metadata.
- Update `ms_icpr` module to store metadata.
@cdelafuente-r7 cdelafuente-r7 force-pushed the feat/pkcs12/certs_command/pkinit branch from 5e8e292 to f9ed213 Compare February 11, 2025 10:03
@cdelafuente-r7 cdelafuente-r7 marked this pull request as ready for review February 11, 2025 10:23
@cdelafuente-r7 cdelafuente-r7 changed the title WIP: Add certs command & use pkinit if kerberos tickets are not available in cache Add certs command & use pkinit if kerberos tickets are not available in cache Feb 11, 2025
@cdelafuente-r7 cdelafuente-r7 force-pushed the feat/pkcs12/certs_command/pkinit branch 2 times, most recently from 2cad3ff to 5dc0d65 Compare February 12, 2025 19:10
…a 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
- use the `status`, certificate's `not_before`/`not_after` and check if the TLS
  OID is present to filter pkcs12 before using them with PKInit
- add the `activate`, `deactivate` and `export` capabilities to the
  certs command
- add specs
@cdelafuente-r7 cdelafuente-r7 force-pushed the feat/pkcs12/certs_command/pkinit branch from 5dc0d65 to e353684 Compare February 12, 2025 20:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement usability Usability improvements
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant