The CyberArk Labs team has discovered a way to harvest encrypted service credentials from the Local Security Authority (LSA) Secrets registry hive and inject them into a new malicious service to achieve lateral movement and full domain compromise. This exploit requires that an attacker first gain local administrator privileges on an infected machine, but once those local administrator privileges are gained, the attacker can leverage a single domain-joined workstation to laterally move throughout the domain and ultimately gain access to a domain controller. This exploit can be carried out on Windows endpoints, including on the most up-to-date Windows 10 workstations that have Credential Guard (VSM) enabled.
This blog will explain how service credentials are protected today, how they can be compromised, and how the CyberArk Labs team proved that this exploit can enable lateral movement and domain compromise.
Background: How are service credentials protected today?
Beginning in Windows 7, Microsoft began protecting service credentials by securely storing them in the LSA Secrets registry hive (HKEY_LOCAL_MACHINE/Security/Policy), which is part of the Security registry hive. Here, the credentials are encrypted with the System Key using the Data Protection API (DPAPI). By default, access to the Security registry hive – and thus the Secrets within it – is restricted to the SYSTEM account only, meaning not even the Administrator can access them. However, despite this default setting, the Administrator maintains the permissions necessary to not only remove this restriction but also open a new session as the SYSTEM user and effectively operate with SYSTEM privileges. By taking advantage of these permissions, an Administrator can gain access to the LSA Secrets, dump the credentials from the registry hive and extract them using the DPAPI.
In Windows 10, Microsoft introduced Credential Guard, which was designed to mitigate the risk of lateral movement using compromised credentials (and credential hashes) by proactively securing domain user credentials in memory in an isolated, highly secure location. However, because Credential Guard only secures credentials in memory, it cannot protect service credentials that are required to properly boot the system. As a result, these service credentials, which may have domain access, remain in the LSA Secrets registry hive.
Newly Discovered Risk
The CyberArk Labs team recently discovered that service credentials stored in the LSA Secrets registry hive can be compromised in encrypted form and used to achieve lateral movement, even when Credential Guard in Windows 10 is enabled. Similar in concept to Pass-the-Hash exploits in previous versions of Windows, an attacker can use compromised encrypted secrets to laterally move through the domain without ever needing to know the underlying credential.
The Proof of Concept
Because this specific risk involves the compromise of service credentials, we hypothesized that these service credentials – which are used for legitimate services – could potentially be captured and injected into a malicious service, thus granting an attacker access to all systems and resources to which the original service had access. If this proved true, then any malicious user with local Administrator access on a Windows machine could reuse stored domain-level service credentials to laterally move through the network and potentially gain access to a domain controller.
To test this hypothesis, we started with the following baseline environment:
- Local Administrator access on a Windows 10 laptop
- Credential Guard enabled on the Windows 10 laptop
- One service with non-administrative domain credentials
To test against this scenario, we created a new, blank service into which we would attempt to inject captured service credentials. This blank service was designed to imitate a malicious service that an attacker could create and use in the wild.
Step 1: Gaining Access to LSA Secrets
The first step in gaining access to LSA Secrets is to grant the local administrator access to the Security registry hive. As mentioned above, by default, this access is reserved for the SYSTEM user only. However, the local Administrator has the permissions needed to change this default setting.
Figure 1: Security registry hive default Administrator permissions
Using local Administrator permissions, an attacker can edit the Security permissions to grant the Administrator access to the Security registry hive (HKEY_LOCAL_MACHINE/Security). Once the attacker (the “Administrator”) has read and write permissions to the Security registry hive, he or she is able to access the registry and begin searching for service secrets.
Step 2: Searching for Service Secrets
With access to LSA Secrets, we next queried the machine to search for services with domain-level access. Note, these services did not have administrative permissions; they simply had non-administrative access to other systems on the same domain.
Figure 2: Service enumeration
This query identified two services that had domain-level access: AppVClient and tzautoupdate. These services are both standard on all Windows 10 machines, and we were able to locate their secrets in the registry under:
- HKEY_LOCAL_MACHINE/Security/Policy/Secrets/SC AppVClient
- HKEY_LOCAL_MACHINE/Security/Policy/Secrets/SC tzautoupdate
We exported these secrets from the LSA Secrets registry hive in encrypted form and did not attempt to decrypt them with the DPAPI. At this point, the secrets were still configured to enable authentication for these specific services only. Before we could change the configurations to execute the test using our new service, we also needed access to services’ properties.
Again, using our local Administrator access, we went to the registry and exported the properties associated with these services from: HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services.
Step 3: Modifying the Secrets and Properties for Reuse
As mentioned above, the legitimate services’ secrets and properties were both configured to work for their specific services only – meaning we could not reuse them as is. However, we hypothesized that we could potentially modify the configurations of the secrets and properties to enable them to work with a different service. To test this, we used the blank service mentioned above.
Using the exported versions of the services’ secrets and properties, we modified the configurations so that both would point back to our new, blank service.
Figure 3: Service modifications
We then imported the modified secrets into the blank service’s secrets and the modified properties into the blank service’s properties, as show in Figures 4 and 5.
Figure 4: Import modified service secrets into blank service secrets
Figure 5: Import modified service properties into blank service properties
Next, we started the blank service on the machine and put it to the test.
We performed domain controller enumeration to quickly locate domain controllers, and we searched for services that had high privileged access to all enumerated domain controllers. We also looked for all systems connected to the original victim system. If the victim machine did not contain any services with domain controller access, we wanted to be able to laterally move to other machines, which may contain services with higher privileges.
Step 4: Achieving Lateral Movement and Full Domain Compromise
Using the compromised service information combined with information about connected systems on the network, we tested our blank service to see if we could successfully achieve lateral movement. The results were a very clear “yes.” Using these compromised and reused service credentials, we proved that compromised service credentials could, in fact, be used to achieve lateral movement. And, with each new machine accessed, we had the potential to find service accounts with higher and higher privileges on the domain. With each new machine compromised, we were able to repeat the process of service credential compromise, modification and reuse until we eventually located a service account that had access to the domain controller and achieved full domain compromise.
Real world implications
Testing in the CyberArk Lab clearly demonstrated that an attacker with local Administrator access on a single user’s machine can compromise service credentials and reuse them to achieve lateral movement and full domain compromise – even when Credential Guard is enabled.
In a real-world scenario, an attacker could use this same process of service credential theft, modification and reuse in a malicious service, and the attacker could configure the malicious service to automate each iterative step of this attack. In such a scenario, an attacker with local Administrator access on one machine could gain full ownership of the entire domain in just minutes.
Despite common assumptions, Microsoft Credential Guard does not protect domain-level service credentials in the same way that it protects domain-level user credentials. As such, organizations must take extra steps to secure and monitor the use of service credentials.
To reduce the risk of service credential theft – and the resulting ability for an attacker to laterally move through the network until they gain domain administrator privileges – organizations should take the following steps:
- Remove local administrator privileges from standard users
- Minimize the use of domain accounts in local services to only those that are required
- When needed, create dedicated domain accounts for services
- Remove all unnecessary privileges from service accounts
- Monitor all permissions changes to sensitive registry values via the Windows Event Log
- Use credential theft detection tools to detect and block the theft of LSA Secrets
- October 25, 2016: Risk reported to Microsoft Security Response Center
- October 26, 2016: Microsoft responded that they did not consider the submission a valid vulnerability as it requires an attacker to have already compromised the machine.*
- November 16, 2016: Public disclosure
*According to Microsoft’s “Ten Immutable Laws of Security”