Abusing Unsafe Defaults in Active Directory Domain Services: A Real-World Case Study

Posted by Louis Dion-Marcil   |   February 20, 2019

Water violently leaking from a large pipe

This past July, Kevin Robertson from NetSPI released a blog post entitled, "Beyond LLMNR/NBNS Spoofing – Exploiting Active Directory-Integrated DNS," which introduced a new technique (to us at least) targeting weak default access control in Active Directory Domain Services. At GoSecure, since most of our engagements require some level of Active Directory security assessment, we followed our interest and decided to find a way to reliably exploit it.

Our blog post details a software bug in the Antidote suite, which causes the software to continuously try to reach a network file share on the local domain using a known subdomain name. This software, used as a self-learning spellchecker, is popular and commonly used in most companies conducting business in French, meaning we often assess environments where this software is heavily deployed. Attackers are able to abuse the weak default access control on the Active Directory Domain Services to register this known subdomain, and making the record point to their machine. By doing so, every time Antidote is fired up, the process attempts to reach the network file share on that subdomain, thereby forcing the operating system to authenticate against that machine, which then points to the attacker's machine. A constant stream of authentication attempts coming from all users with Antidote installed are then received by the malicious actor, who would then be allowed to perform NTLM relaying attacks or crack the received hashes.Using the details in this research meant the intrusion testers could reliably obtain and relay authentication hashes for most employees of an organization in a passive, non-intrusive, and timely manner.

Technical Details

The NetSPI post explained how, by default, all members of the "Domain User" group are able to create arbitrary DNS records under the main zone of the Domain Services. Since we had been recommending that our clients disable LLMNR and NetBIOS name resolution in their environments for years, we took particular interest in this blog post, given that its content could potentially allow us to go beyond Local Area Network name spoofing. 

For the rest of this blog post, we will use the fictive Active Directory Domain company.int.

The Antidote Bug

The bug is related to the naive way Antidote handles the version checking for its plugins. It creates an unintended side effect that forces Windows to access the \\PLUG-INS.company.int\Antidote network share. Later we detail how this bug was introduced in the software, but first, look at how the bug can be misused for nefarious purposes. The bug, present in default configuration installations, is caused by a faulty string concatenation where a null string is appended to a subfolder. This ends up forcing the software to query a file path with a null prefix, resulting in a path with a leading backslash (\). Because of this, Windows presumes that the process is looking to load a UNC path (which follows the \\server\folder\file URI scheme). This has the direct effect of looking up the PLUG-INS name and browsing it as if it were a network file share. Under Windows, the default process of name resolution can be resumed to the following steps:

  1. Perform DNS Query
    In the case of a machine that is joined to a Domain, a single-item query (meaning without a TLD) will be queried under the main domain zone. In this case, since the operating system queries for PLUG-INS, the DNS query will be for PLUG-INS.company.int. Most likely, this record does not exist in the Active Directory environment, so we move on to the next step;
  2. Perform NetBIOS Query
    Local Area Network query targeting the neighboring hosts. If an attacker is in the same broadcast domain, they will see this request and be able to reply for it -- aka spoofing the response;
  3. Perform LLMNR Query
    Another protocol which will ask neighboring hosts on the Local Area Network for an answer. This type of response can also be spoofed by hosts in the same broadcast domain.

Why is this information pertinent in any way? When trying to read from a UNC path, Windows will perform an NTLM handshake with the target, meaning a challenge-response will be performed between the requesting machine and its target. As an attacker, if we are able to have machines in the domain perform authentication attempts against our machine, it allows us to intercept the authentication attempt, and potentially abuse it in order to either obtain their cleartext credentials or to relay the authentication to a 3rd machine.

Abusing the authentication process is not difficult, and is outside the scope of this blog post. Once a remote machine tries to authenticate against our machine, we are able to use tools like Hashcat or John The Ripper in order to obtain the cleartext representation of the victim's password. Should that technique fail, either because the password complexity is too strong, or because you don't have a fancy cracking rig, attackers can still perform NTLM relaying. With NTLM relay, we use the hash we capture from the NTLM challenge-response and relay it instantly to a 3rd machine under the same domain (or forest with appropriate trusts). Relaying allows the attacker to authenticate against any service in that domain, under the context of the victim. This can be used to access sensitive information, like the victim's emails, file servers, and sometimes even remote code execution if the victim has Local Administrator rights on the machine an attacker is relaying against.

Now that we detailed how name resolution works and why it would be interesting from an attacker's perspective to have machines authenticate against ours, we show that when put together these can be leveraged to exploit the Domain Services access control weakness. We know that most user machines in the domain will be querying for the PLUG-INS.company.int record, therefore we need to register this record and make it point to our machine. This can be done using Kevin Robertson's technique, allowing all domain users to create DNS records under the main zone. Since Microsoft's Domain Services' default configuration for "Create all child objects" is set to "Allow" for the group "Authenticated Users", all authenticated users can create new records freely. Using the Powermad project4, it is then possible to create a record called PLUG-INS that would point to our attacker machine. This would mean that all machines with Antidote installed would constantly try to authenticate against our machine, as such:

Before creating the record, let's confirm that PLUG-INS.company.int does not exist. We can check this with the nslookup utility:

Next, we're going to create the PLUG-INS record:

To confirm the record was created properly, we can use nslookup again:

From this point on, all machines running Antidote will constantly try to authenticate against our attacker machine on 172.24.0.5, allowing us to crack the hash or relay the authentication.

To demonstrate the reliability of this scenario, we used this technique on one of our clients, where approximately 90 provisioned endpoints were running Antidote. We registered the PLUG-INS record and made it point to one of our machines where Responder was running in analyze mode. In analyze mode Responder does not perform any spoofing, it simply listens for inbound connections and saves the hash. We plotted the results, showing how easy it is for an attacker to passively collect hashes from all domain users over time.

After creating the record, at around noon, we can see a steady and linear amount of collected password hashes. The multiple black X marks represent the time of day we obtained hashes for high-profile accounts (1 account member of the Domain Admins group, 2 members of an OU with access to sensitive information).

Underlying Issue in Antidote

Software missing on machines is the root cause of Antidote attempting to read from the \\PLUG-INS\ network share. This results in plugins not properly operating in that state. The module attempts to read the content of the {SOFTWARE_INSTALL_PATH}\PLUG-INS\Antidote directory. When the software the plugin should handle is not installed, the value of {SOFTWARE_INSTALL_PATH} is obviously null, meaning that the final path is transformed to \PLUG-INS\Antidote. When Windows sees a path with a leading backslash (\), it assumes the path is in fact, a UNC path. Antidote ships with plugin handlers, which are tasked with handling version checking. Every time Antidote is fired up, all the plugin handlers are launched in order to check if an update is available for the installed version. Since Druide provides individual plugin files for every single version of the software they handle, the faulty plugin handlers will attempt to read from the network share for every handled version. For example, the Illustrator plugin handler looks for all of the following files:

PS C:\Program Files (x86)\Druide\Antidote 9\Connect\Illustrator\Bin> dir
Directory: C:\Program Files (x86)\Druide\Antidote 9\Connect\Illustrator\Bin
Mode LastWriteTime Length Name
---- ------------- ------ ----
 -a---- 9/12/2017 4:24 PM 14690304 Antidote.Illustrator.P100.aip
 -a---- 9/12/2017 4:24 PM 14674432 Antidote.Illustrator.P106.aip
 -a---- 9/12/2017 4:22 PM 25029632 Antidote.Illustrator.P106_64.aip
 -a---- 9/12/2017 4:25 PM 14674432 Antidote.Illustrator.P107.aip
 -a---- 9/12/2017 4:23 PM 25029632 Antidote.Illustrator.P107_64.aip
 -a---- 12/5/2017 3:07 PM 14674944 Antidote.Illustrator.P108.aip
 -a---- 12/5/2017 3:05 PM 25030656 Antidote.Illustrator.P108_64.aip

This means that every time the plugin update routine is fired up, the Illustrator handler alone will attempt to reach the PLUG-INS network share over 7 times. The vulnerable Antidote plugins are the following:

  • Adobe Illustrator
  • Adobe InCopy
  • Adobe InDesign

The three plugin handlers have this bug, which is triggered for all of their individual plugin versions…meaning we get a lot of hashes when Antidote is fired up:

Using NTLM relaying is a big advantage when trying to find machines that a potential victim has privileged access to. Antidote plugins for other software are able to work properly when the install path is not found. Here is a rough flowchart of the process handling the plugins in Antidote, and why some of them end up requesting UNC paths:

Note that with Antidote 10 MoteurIntegration.exe is under the Connectix 10 folder 

Vendor Response

We reported the software bug to Antidote in December 2017, more specifically, the fact that the PLUG-INS LLMNR/NBNS broadcast could be spoofed in order to capture hashes. We also theorized that it might be possible to force Antidote to load our malicious plugins, which would allow remote code execution. They promptly replied with the details of their investigation, which confirmed the plug-ins broadcast bug. Druide was also able to prove that it is not possible to force remote Antidote instances to load malicious plugins. Indeed, the plugin update process will only call GetFileVersionInfoA() on the DLLs, which does not lead to remote code execution. Druide also wrote that they would eventually fix this bug, in due time, but that it is not a critical issue to them. We waited for a fix.

Late last year Druide released Antidote version 10. Earlier this month, we confirmed that the security issue is still present. We sent Druide a draft version of this blog post and the impact was clearer to them. They quickly published updated versions of Antidote 8, 9 and 10 fixing the issue. We advise users of Antidote to update right away using the built-in self-update capability of Antidote.

Defenses

This is obviously a two-fold issue. First, we have faulty software on endpoints which tries to connect to a network share, which, in turn, broadcasts user credential hashes. Second, we also allow users to create DNS records which increases the exploitability and impact of the faulty software. We will look at how to mitigate both vectors: the endpoint and the Domain Services.

Active Directory Defense

The Domain Services ACL can be hardened to prevent domain users from creating arbitrary records. This can be done by changing the security configuration for your DNS zones. On the server on which the service Domain Service is running, open the DNS Manager, and for each domain zone under which users are joined, remove the "Create all child objects" permission from the "Authenticated Users" group.

Once this is done, users will not be able to create any records. Note that this may have unintended side effects on your users' ability to join computers to the Active Directory environment. If your onboarding process requires users to join their own machines, this will most definitely break this process. To test that users do not have access to create arbitrary records anymore, we use Powermad again:

An alternative mitigation technique would be Kevin Robertson's method of sinkholing the record by making it point to a dummy record5. If your environment is not already rid of LLMNR and NBNS broadcasting, you should definitely create a plug-ins record and make it point to an A record that does not point to a machine, such as 0.0.0.0. This is important because if your users still perform LLMNR and NBNS requests, should the DNS query not return a record, the operating system will fallback to these legacy protocols which attackers will be able to spoof.

If LLMNR and NBNS broadcasting are mitigated in your environment, there is no real value in creating a DNS record for the entry. A more straight forward way of making sure no machine resolves PLUG-INS.company.int is to use the Global Query Block List, a lesser-known feature of the Domain Services. This feature was added with Windows Server 2008 and acts as a blacklist of records that should never be resolved. The Global Query Block List is enabled by default and contains two blacklisted records, ISATAP and WPAD. To check whether you are using the Global Query Block List, run the command dnscmd /info /enableglobalqueryblocklist on your DNS server. Should the command return Dword: 1 (00000001), then your Domain Services uses the Block List.

To list the records, run dnscmd /info /globalqueryblocklist.

For the Antidote use case, we'll want to add plug-ins to the blacklist, so that all queries for that record will not be responded for, even if such a record is created in any zone. This can be done with the command dnscmd /config /globalqueryblocklist wpad isatap plug-ins

Once the entry was added to the Block List, the plug-ins.company.int will never resolve it again, even if a record is created.

Endpoint Defense

Update your Antidote using the built-in update manager (under Help) and make sure it has been updated to the following versions:

  • Antidote 10: 10.1.2147 or later (verify under Add/Remove programs for Antidote - Connectix 10, this patch level isn't visible from Antidote's about dialog)
  • Antidote 9: 9.5.3937 or later (verify under Add/Remove programs for Antidote, this patch level isn't visible from Antidote's about dialog)
  • Antidote 8: 8.05.2287 or later (verify under Add/Remove programs Antidote, this patch level isn't visible from Antidote's about dialog)

Site-wide deployment may mean the end user will not have the ability to perform updates. If you see that you are using a vulnerable version, contact your IT department.

If, for any reason, you are unable to update, the vulnerability can be mitigated by removing the faulty plugin handlers. They are found at the following paths:

Antidote 9
C:\Program Files (x86)\Druide\Antidote 9\Application\Bin{32,64}\Extensions\Illustrator.dll
C:\Program Files (x86)\Druide\Antidote 9\Application\Bin{32,64}\Extensions\InCopy.dll
C:\Program Files (x86)\Druide\Antidote 9\Application\Bin{32,64}\Extensions\InDesign.dll

Antidote 10
C:\Program Files (x86)\Druide\Connectix 10\Application\Bin{32,64}\Extensions\Antidote.Illustrator.MA.P100.dll
C:\Program Files (x86)\Druide\Connectix 10\Application\Bin{32,64}\Extensions\Antidote.InCopy.MA.P100.dll
C:\Program Files (x86)\Druide\Connectix 10\Application\Bin{32,64}\Extensions\Antidote.InDesign.MA.P100.dll

Since the bug is only triggered when the Illustrator, InCopy, or InDesign software isn't installed on endpoints, the plugin can be safely used if they are installed.

Conclusion

The problem discussed in this blog post is a two-sided problem. We visited a weakness in the default access control configuration for Active Directory Domain Services that allows all authenticated domain users to create DNS records under their respective zones. To illustrate the impact of such poor access control, we needed a concrete, widely abusable use case. We presented the case of Druide's Antidote software, for which some plugin handlers continuously attempt to reach unexistent network shares at a prefixed subdomain. By registering this subdomain with an unprivileged domain account, we were able to demonstrate that we could reliably obtain NTLM hashes for all employees using the Antidote software, and relay them.

Since we drafted this blog post, NetSPI released another blog post about different abuses and mitigation around Active-Directory' DNS. We advise defenders to take a look.

The Antidote bug was discovered and disclosed to the vendor by Martin Lemay. Further analysis performed by Ian Bouchard, Philippe Arteau, Louis-Dion Marcil and Olivier Bilodeau.

Topics: pentest, Featured, Active Directory, NTLM