Anyways onto the topic at hand: PAC validation and the various excuses not to check it
What is PAC Validation and Why Do I Care?The PAC (Privilaged Attribute Certificate) is a structure contained in a Kerberos ticket that contains a list of privileges that the ticket is representing, along with some other stuff. If we can forge the PAC we can do things to break the privilege model of Kerberos in some very interesting ways ;-)
"PAC validation" is pretty much what it sounds like, the service receiving the ticket double checks the information contained in the PAC as being valid before either issuing service tickets (in the event of a Ticket Granting Ticket / TGT) or running the command/request/whatever (in the event of a service ticket being used).
The 20 Minute Rule
What we're calling "The 20 Minute Rule" is taken straight out of the Microsoft's MS-KILE specification, specifically section 5.1.3 which states:
"Kerberos V5 does not provide account revocation checking for TGS requests, which allows TGT renewals and service tickets to be issued as long as the TGT is valid even if the account has been revoked. KILE provides a check account policy (section 18.104.22.168.1) that limits the exposure to a shorter time. KILE KDCs in the account domain are required to check accounts when the TGT is older than 20 minutes. This limits the period that a client can get a ticket with a revoked account while limiting the performance cost for AD queries."
So to translate, in the event that the TGT is more than 20 minutes old, the PAC contents are validated to ensure that the account is still valid. However to flip this around, this means that there's a 20 minute window where the contents ARE NOT validated. This is one of the primary things we brought up in our Black Hat talk. As long as you have the KRBTGT hash you can put whatever information you want into the PAC inside the TGT, and service tickets will be issued, as long as the age of the TGT is less that 20 minutes old. This includes bogus account / SID information, such as a non-existent user being a member of the domain admins group. Because the information isn't validated during this first 20 minute window, service tickets will be generated that are good for several hours by default. Additionally, since we can create our own TGTs, the 20 minute rule is never really a problem since we can simply create a new TGT every 20 minutes to get around this limitation.
Other PAC Validation Issues
So obviously, this can lead to some problems, but are there any other examples lurking out there? I'm glad you asked!
Recently @gentilkiwi and I have been investigating another issue related to a failure of PAC validation that Ben has dubbed a 'Silver Ticket'. Here's the section of relevant protocol specification from the holy Microsoft MS-APDS scripture Appendix A, Section 1.6.2:
- Windows 2000 Server and Windows XP do not validate the PAC when the application server is running under the local system context or has SeTcbPrivilege, as specified in [MS-LSAD] section 22.214.171.124.1. Otherwise, Windows 2000 Server and Windows XP use Kerberos PAC validation.
- Windows Server 2003 does not validate the PAC when the application server is running under the local system context, the network service context, or has SeTcbPrivilege. Otherwise, Windows Server 2003 uses Kerberos PAC validation.
- Windows Server 2003 with SP1 does not validate the PAC when the application server is under the local system context, the network service context, the local service context, or has SeTcbPrivilege privilege. Otherwise, Windows Server 2003 with SP1 and future service packs use Kerberos PAC validation.
- Windows Vista, Windows Server 2008, Windows 7, Windows Server 2008 R2, Windows 8, Windows Server 2012, Windows 8.1, and Windows Server 2012 R2 do not validate the PAC by default for services. Windows still validates the PAC for processes that are not running as services. PAC validation can be enabled when the application server is not running in the context of local system, network service, or local service; or it does not have SeTcbPrivilege, as specified in [MS-LSAD] section 126.96.36.199.1.
So, in general older versions of Windows don't validate the PAC when the process is running as SYSTEM or has the "SeTcbPrivilege" (Act as part of the operating system) privilege set. Newer versions (Vista+) don't check the PAC for services.
So, how is this useful? Well, pretty much anything that you could want to do to a computer remotely is a service, such as access a file share, schedule a task, execute code, etc...
So, for Kerberos, services by default don't validate PAC settings... What could possibly go wrong here? But wait! There's more!
Service Tickets and Kerberos
The obvious question now arises, what do we need to issue a service ticket for a particular service? How can we take advantage of this?
Service tickets SHOULD be issued by a TGS after getting a TGT and should be between 2 Kerberos principals. So for example, if Bob wants to access a file share (CIFS) on ServerA, Bob would ask the TGS to give him a ticket for user CIFS@ServerA. The TGS would then give Bob a ticket that he could present to ServerA that would give him access to the CIFS service.
With TGTs, the piece destined for the TGS would need to be signed by the KRBTGT account, the central account for trust to validate that the ticket is legit. However, for service tickets, the target account is on the computer itself. What is the long term secret key?
In short, it depends. For all services that run as System on the computer, it will be the computer account from AD. If the service is operating as a particular user (typically like Sharepoint, Exchange, MSSQL, etc...) it will be that account.
Recovering the computer account is relatively trivial with physical access (think boot disk, grab the registry, decode at whim) and if you can run as admin, it's trivial as well... If you can guess the service account password for a service that runs as a different user, that will work too...
Now, all you have to do is use Mimikatz to generate a Silver Ticket for the service and away you go... an example that Ben posted to twitter can be seen here:
Since service tickets are identical in format to TGTs albeit with a different service name, all you need to do is specify a different service name and use the RC4 (NTLM hash) of the account password (either the computer account for default services or the actual account) and you can now issue service tickets for the requested service. Note: You can also use the AES keys if you happen to have them instead of the NTLM key and it will still work ;-)
It is worth noting, that services like MSSQL, Sharepoint, etc will only allow you to play with those services. The computer account will allow access to CIFS, service creation, and a whole host of other activities on the targeted computer. You can leverage the computer account into a shell with PSEXEC and you will be running as system on that particular computer. Lateral movement is then a matter of doing whatever you need to do from there :-)
My next post I will perform some demos with screenshots, etc... Stay tuned!