fortra / impacket

Impacket is a collection of Python classes for working with network protocols.
https://www.coresecurity.com
Other
12.99k stars 3.5k forks source link

Implement Kerberos encryption types from RFC8009 (AES HMAC-SHA2 familly) #1684

Open jrisc opened 5 months ago

jrisc commented 5 months ago

This pull request implements the following features in the Impacket library:

It also modifies the getST.py script:

The motivation for these changes is to test the Bronze-Bit exploit (CVE-2020-17049) against FreeIPA. It cannot be done with the current implementation because getST.py is designed to work against Active Directory only. FreeIPA differs on the following points:

The PA_S4U_X509_USER sequence basically serves the same purpose as PA-FOR-USER, but it uses the checksum type associated with the encryption type of the session key. Hence it can be any of the HMAC-MD5, HMAC-SHA1 or HMAC-SHA2 ones.

To be mentioned that FreeIPA does not have the same approach as Active Directory when it comes to service principals. For Active Directory, an SPN has to be owned by a user account, and S4U requests can use this account name rather than the actual proxy service principal. This is why getST.py expects an identity with the domain/username format as final argument (the actual Active Directory format is domain\username format though, with \). This is all AD-specific. The standard Kerberos format is username@realm for users and primary/hostname@realm for services. In addition, FreeIPA service principals are meant to be used directly in S4U requests, since they don't have an "owner" in the AD sense.

As a consequence, the identify to pass to getST.py in order for it to work with a FreeIPA-managed service principal was something like EXAMPLE.COM/HTTP/web.example.com (EXAMPLE.COM as realm, and HTTP/web.example.com as service principal). This was quite confusing, so I included a commit to add support for standard Kerberos principals in addition to AD usernames.

IMPORTANT: This pull request requires Legrandin/pycryptodome#781 to work. The SP800_108_Counter() function in its current form does not allow passing null bytes in label, while this is required by RFC8009.

anadrianmanrique commented 4 months ago

@jrisc First, apologies for the delayed response. Second, what an amazing work that you've done. We discussed about this PR with the team and this is what we decided: ### impacket's kerberos stack it's not going to support (in the short/mid term) platforms other than Micosoft/AD. Supporting other platforms involves for us to regression the code in these environments. This is not a priority at the moment. Being said that, if some of these features that this PR it's adding support to, it is present in the Micorosft's implementation, we can consider those specific changes ( as we will be able to test and regression it in the future ). So questions are: is there a way to exercise this whole code in a Microsoft environment? is there a way to exercise parts of this code in a Microsoft environment? if so, can be the PR changes be reduced/scoped to that code? Let us know your thoughts Thanks!

abbra commented 4 months ago

@anadrianmanrique thanks for the response.

Microsoft is working to add RFC8009 support too, as announced by Steve Syfuhs (Microsoft Kerberos developer) in https://syfuhs.net/improvements-in-windows-kerberos-architecture. They need that to make sure they are FIPS 140-3 compliant (they submitted a set of crypto modules for that already).

So you should be expecting this coming to Windows any time soon.

abbra commented 1 month ago

FYI, Microsoft has release public preview of Windows Server 2025 that includes support for RFC8009 enctypes. You might want to consider this work before Microsoft releases this version later this year to production.

See https://learn.microsoft.com/en-us/windows-server/get-started/whats-new-windows-server-2025 for more details.