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

Consolidate Kerberos Ticket Storage #17377

Conversation

zeroSteiner
Copy link
Contributor

@zeroSteiner zeroSteiner commented Dec 13, 2022

Since we're keeping the loot-based storage for the foreseeable future, we should consolidate how tickets are stored in loot. This creates a series of new TicketStorage::Base classes that expose a common interface. The classes include:

  • TicketStorage::None -- Storage is not used at all, nothing is read from it and nothing is saved.
  • TicketStorage::ReadOnly -- Previously stored tickets are used, but new tickets are not saved and no tickets can be deleted.
  • TicketStorage::WriteOnly -- Previously stored tickets are not used, but new tickets are saved and tickets can be deleted.
  • TicketStorage::ReadWrite -- Previously stored tickets are used, new tickets are saved and tickets can be deleted.

These classes replace the use_cached_credentials and store_credential_cache options as used by ServiceAuthenticator::Base. The original uses of these options have been replaced. More modules have also been updated with the new KrbCacheMode option allowing the user to switch between the 4 available modes (none, read-only, write-only and read-write).

The storage classes also return TicketStorage::StoredTicket instead of Mdm::Loot objects. The intention is to abstract away how they're stored so the Mdm object itself should not be leaked. In the future, the stored tickets should expose the same API.

Verification

List the steps needed to make sure this thing works

  • Test that tickets from kerberos/forge_ticket are stored in a way that they can be fetched from the cache
  • Test that tickets from kerberos/pkinit_login are stored in a way that they can be fetched from the cache
  • Test that the service authenticator base is storing and fetching tickets correctly

There should be no different in functionality.

@zeroSteiner zeroSteiner marked this pull request as draft December 13, 2022 18:34
@zeroSteiner zeroSteiner changed the title Consolidate Kerberos Ticket Loot ID [WIP] Consolidate Kerberos Ticket Storage Dec 13, 2022
@zeroSteiner zeroSteiner changed the title [WIP] Consolidate Kerberos Ticket Storage Consolidate Kerberos Ticket Storage Dec 15, 2022
@zeroSteiner zeroSteiner marked this pull request as ready for review December 15, 2022 14:31
@adfoster-r7
Copy link
Contributor

Placeholder comment to double check ldap_query, as I had to add in a dependency within a previous PR:

https://github.com/rapid7/metasploit-framework/pull/17236/files#r1020143352

@adfoster-r7
Copy link
Contributor

Not a blocker: Do we want to scope creep this PR and add support for invalidating tickets?

@zeroSteiner zeroSteiner force-pushed the feat/lib/kerberos/loot-info branch 2 times, most recently from 94f5513 to fe15bfb Compare December 15, 2022 17:08
@zeroSteiner
Copy link
Contributor Author

Placeholder comment to double check ldap_query, as I had to add in a dependency within a previous PR:

ldap_query appears to be working just fine, and I'm thinking it's because Ticket::Storage::Base includes Msf::Auxiliary::Report and forwards methods based on the framework_module it's passed just like ServiceAuthenticator::Base does.

Testing Output
msf6 auxiliary(gather/ldap_query) > loot

Loot
====

host  service  type  name  content  info  path
----  -------  ----  ----  -------  ----  ----

msf6 auxiliary(gather/ldap_query) > git rev-parse --abbrev-ref HEAD
[*] exec: git rev-parse --abbrev-ref HEAD

feat/lib/kerberos/loot-info
msf6 auxiliary(gather/ldap_query) > run KrbCacheMode=read-write
[*] Running module against 192.168.159.10

[+] 192.168.159.10:88 - Received a valid TGT-Response
[*] 192.168.159.10:389 - TGT MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20221215121112_default_192.168.159.10_mit.kerberos.cca_428808.bin
[+] 192.168.159.10:88 - Received a valid TGS-Response
[*] 192.168.159.10:389 - TGS MIT Credential Cache ticket saved to /home/smcintyre/.msf4/loot/20221215121112_default_192.168.159.10_mit.kerberos.cca_254238.bin
[+] 192.168.159.10:88 - Received a valid delegation TGS-Response
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[*] 192.168.159.10:389 Getting root DSE
dn: 
namingcontexts: DC=msflab,DC=local
namingcontexts: CN=Configuration,DC=msflab,DC=local
namingcontexts: CN=Schema,CN=Configuration,DC=msflab,DC=local
namingcontexts: DC=DomainDnsZones,DC=msflab,DC=local
namingcontexts: DC=ForestDnsZones,DC=msflab,DC=local
supportedcapabilities: 1.2.840.113556.1.4.800
supportedcapabilities: 1.2.840.113556.1.4.1670
supportedcapabilities: 1.2.840.113556.1.4.1791
supportedcapabilities: 1.2.840.113556.1.4.1935
supportedcapabilities: 1.2.840.113556.1.4.2080
supportedcapabilities: 1.2.840.113556.1.4.2237
supportedcontrol: 1.2.840.113556.1.4.319
supportedcontrol: 1.2.840.113556.1.4.801
supportedcontrol: 1.2.840.113556.1.4.473
supportedcontrol: 1.2.840.113556.1.4.528
supportedcontrol: 1.2.840.113556.1.4.417
supportedcontrol: 1.2.840.113556.1.4.619
supportedcontrol: 1.2.840.113556.1.4.841
supportedcontrol: 1.2.840.113556.1.4.529
supportedcontrol: 1.2.840.113556.1.4.805
supportedcontrol: 1.2.840.113556.1.4.521
supportedcontrol: 1.2.840.113556.1.4.970
supportedcontrol: 1.2.840.113556.1.4.1338
supportedcontrol: 1.2.840.113556.1.4.474
supportedcontrol: 1.2.840.113556.1.4.1339
supportedcontrol: 1.2.840.113556.1.4.1340
supportedcontrol: 1.2.840.113556.1.4.1413
supportedcontrol: 2.16.840.1.113730.3.4.9
supportedcontrol: 2.16.840.1.113730.3.4.10
supportedcontrol: 1.2.840.113556.1.4.1504
supportedcontrol: 1.2.840.113556.1.4.1852
supportedcontrol: 1.2.840.113556.1.4.802
supportedcontrol: 1.2.840.113556.1.4.1907
supportedcontrol: 1.2.840.113556.1.4.1948
supportedcontrol: 1.2.840.113556.1.4.1974
supportedcontrol: 1.2.840.113556.1.4.1341
supportedcontrol: 1.2.840.113556.1.4.2026
supportedcontrol: 1.2.840.113556.1.4.2064
supportedcontrol: 1.2.840.113556.1.4.2065
supportedcontrol: 1.2.840.113556.1.4.2066
supportedcontrol: 1.2.840.113556.1.4.2090
supportedcontrol: 1.2.840.113556.1.4.2205
supportedcontrol: 1.2.840.113556.1.4.2204
supportedcontrol: 1.2.840.113556.1.4.2206
supportedcontrol: 1.2.840.113556.1.4.2211
supportedcontrol: 1.2.840.113556.1.4.2239
supportedcontrol: 1.2.840.113556.1.4.2255
supportedcontrol: 1.2.840.113556.1.4.2256
supportedcontrol: 1.2.840.113556.1.4.2309
supportedcontrol: 1.2.840.113556.1.4.2330
supportedcontrol: 1.2.840.113556.1.4.2354
supportedextension: 1.3.6.1.4.1.1466.20037
supportedextension: 1.3.6.1.4.1.1466.101.119.1
supportedextension: 1.2.840.113556.1.4.1781
supportedextension: 1.3.6.1.4.1.4203.1.11.3
supportedextension: 1.2.840.113556.1.4.2212
supportedldapversion: 3
supportedldapversion: 2
supportedsaslmechanisms: GSSAPI
supportedsaslmechanisms: GSS-SPNEGO
supportedsaslmechanisms: EXTERNAL
supportedsaslmechanisms: DIGEST-MD5

[+] 192.168.159.10:389 Discovered base DN: DC=msflab,DC=local
[+] Successfully queried LDAP server!
[+] Successfully queried LDAP server!
DC=msflab DC=local
==================

 Name                       Attributes
 ----                       ----------
 ms-ds-machineaccountquota  10

[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) > loot

Loot
====

host            service  type                 name  content                   info                                                                  path
----            -------  ----                 ----  -------                   ----                                                                  ----
192.168.159.10           mit.kerberos.ccache        application/octet-stream  realm: MSFLAB.LOCAL, client: smcintyre, server: krbtgt/msflab.local   /home/smcintyre/.msf4/loot/20221215121112_default_192.168.159.10_mit.kerberos.cca_428808.bin
192.168.159.10           mit.kerberos.ccache        application/octet-stream  realm: MSFLAB.LOCAL, client: smcintyre, server: ldap/dc.msflab.local  /home/smcintyre/.msf4/loot/20221215121112_default_192.168.159.10_mit.kerberos.cca_254238.bin

msf6 auxiliary(gather/ldap_query) > run KrbCacheMode=read-write
[*] Running module against 192.168.159.10

[*] 192.168.159.10:88 - Using cached credential for ldap/DC.msflab.local@MSFLAB.LOCAL smcintyre@MSFLAB.LOCAL
[+] Successfully bound to the LDAP server!
[*] Discovering base DN automatically
[*] 192.168.159.10:389 Getting root DSE
dn: 
namingcontexts: DC=msflab,DC=local
namingcontexts: CN=Configuration,DC=msflab,DC=local
namingcontexts: CN=Schema,CN=Configuration,DC=msflab,DC=local
namingcontexts: DC=DomainDnsZones,DC=msflab,DC=local
namingcontexts: DC=ForestDnsZones,DC=msflab,DC=local
supportedcapabilities: 1.2.840.113556.1.4.800
supportedcapabilities: 1.2.840.113556.1.4.1670
supportedcapabilities: 1.2.840.113556.1.4.1791
supportedcapabilities: 1.2.840.113556.1.4.1935
supportedcapabilities: 1.2.840.113556.1.4.2080
supportedcapabilities: 1.2.840.113556.1.4.2237
supportedcontrol: 1.2.840.113556.1.4.319
supportedcontrol: 1.2.840.113556.1.4.801
supportedcontrol: 1.2.840.113556.1.4.473
supportedcontrol: 1.2.840.113556.1.4.528
supportedcontrol: 1.2.840.113556.1.4.417
supportedcontrol: 1.2.840.113556.1.4.619
supportedcontrol: 1.2.840.113556.1.4.841
supportedcontrol: 1.2.840.113556.1.4.529
supportedcontrol: 1.2.840.113556.1.4.805
supportedcontrol: 1.2.840.113556.1.4.521
supportedcontrol: 1.2.840.113556.1.4.970
supportedcontrol: 1.2.840.113556.1.4.1338
supportedcontrol: 1.2.840.113556.1.4.474
supportedcontrol: 1.2.840.113556.1.4.1339
supportedcontrol: 1.2.840.113556.1.4.1340
supportedcontrol: 1.2.840.113556.1.4.1413
supportedcontrol: 2.16.840.1.113730.3.4.9
supportedcontrol: 2.16.840.1.113730.3.4.10
supportedcontrol: 1.2.840.113556.1.4.1504
supportedcontrol: 1.2.840.113556.1.4.1852
supportedcontrol: 1.2.840.113556.1.4.802
supportedcontrol: 1.2.840.113556.1.4.1907
supportedcontrol: 1.2.840.113556.1.4.1948
supportedcontrol: 1.2.840.113556.1.4.1974
supportedcontrol: 1.2.840.113556.1.4.1341
supportedcontrol: 1.2.840.113556.1.4.2026
supportedcontrol: 1.2.840.113556.1.4.2064
supportedcontrol: 1.2.840.113556.1.4.2065
supportedcontrol: 1.2.840.113556.1.4.2066
supportedcontrol: 1.2.840.113556.1.4.2090
supportedcontrol: 1.2.840.113556.1.4.2205
supportedcontrol: 1.2.840.113556.1.4.2204
supportedcontrol: 1.2.840.113556.1.4.2206
supportedcontrol: 1.2.840.113556.1.4.2211
supportedcontrol: 1.2.840.113556.1.4.2239
supportedcontrol: 1.2.840.113556.1.4.2255
supportedcontrol: 1.2.840.113556.1.4.2256
supportedcontrol: 1.2.840.113556.1.4.2309
supportedcontrol: 1.2.840.113556.1.4.2330
supportedcontrol: 1.2.840.113556.1.4.2354
supportedextension: 1.3.6.1.4.1.1466.20037
supportedextension: 1.3.6.1.4.1.1466.101.119.1
supportedextension: 1.2.840.113556.1.4.1781
supportedextension: 1.3.6.1.4.1.4203.1.11.3
supportedextension: 1.2.840.113556.1.4.2212
supportedldapversion: 3
supportedldapversion: 2
supportedsaslmechanisms: GSSAPI
supportedsaslmechanisms: GSS-SPNEGO
supportedsaslmechanisms: EXTERNAL
supportedsaslmechanisms: DIGEST-MD5

[+] 192.168.159.10:389 Discovered base DN: DC=msflab,DC=local
[+] Successfully queried LDAP server!
[+] Successfully queried LDAP server!
DC=msflab DC=local
==================

 Name                       Attributes
 ----                       ----------
 ms-ds-machineaccountquota  10

[*] Auxiliary module execution completed
msf6 auxiliary(gather/ldap_query) > 

@zeroSteiner zeroSteiner force-pushed the feat/lib/kerberos/loot-info branch from fe15bfb to 0b10245 Compare December 15, 2022 20:14
@@ -130,8 +125,10 @@ def initialize(
@use_gss_checksum = use_gss_checksum
@mechanism = mechanism
@send_delegated_creds = send_delegated_creds
@use_cached_credentials = use_cached_credentials
@store_credential_cache = store_credential_cache
@ticket_storage = ticket_storage || Msf::Exploit::Remote::Kerberos::Ticket::Storage::ReadWrite.new(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are your thoughts on defaulting to Write behavior by default? 👀

I'm thinking in terms of element of least surprise for existing workflows with tools like impacket, users might not expect the ticket re-use behavior occurring out of the box

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a strong opinion about the default storage mode right here. If you're instantiating the authenticator yourself, as a module developer to do something specific, it might make sense to just be WriteOnly.

Changing it here wouldn't change the default mode for modules though.

@zeroSteiner zeroSteiner force-pushed the feat/lib/kerberos/loot-info branch from 0b10245 to 81d4b25 Compare December 15, 2022 23:03
@zeroSteiner zeroSteiner force-pushed the feat/lib/kerberos/loot-info branch from 81d4b25 to 60a76da Compare December 15, 2022 23:31
@adfoster-r7 adfoster-r7 merged commit 20496aa into rapid7:feature-kerberos-authentication Dec 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rn-no-release-notes no release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants