ADIDNS Revisited – WPAD, GQBL, and More

A few months ago, I wrote a blog post on exploiting Active Directory-Integrated DNS (ADIDNS). This post will mainly cover some additional techniques on both the offensive and defensive fronts. I would suggest at least skimming the original post before continuing here.

With that out of the way, I’d like to start by adding in another well known and problematic default setting related to name resolution that I left out of the original post.

So What About WPAD?

Web Proxy Auto-Discovery (WPAD) is of course a common target during LLMNR and NBNS spoofing. At first glance, WPAD would seem like the most obvious record to add through ADIDNS. Authenticated users can usually add the record since it does not exist by default.

If you do add a record for WPAD, you will likely find that it just doesn’t do anything. This behavior is due to the global query block list (GQBL), which contains WPAD and ISATAP by default.

Modern Windows DNS servers will usually not answer name requests which match hosts listed in the GQBL. Why did I include the word ‘usually’? Well, it turns out that the GQBL doesn’t always work.

Bypassing the GQBL

While I was experimenting with wildcard records, I noticed that Windows DNS servers ignored the GQBL and answered requests for WPAD through wildcards. At this point in the research timeline though, I hadn’t started working with LDAP. I could only add records through dynamic updates. Since the ‘*’ character didn’t work correctly with dynamic updates, I decided to look for a GQBL bypass method that would work with dynamic updates.

The first additional method I found was through DNAME records. Windows DNS servers would resolve WPAD if a DNAME record of ‘wpad’ was present in a zone.

Normally, DNAME records do not resolve requests that match the actual record. The DNS server should only answer requests for a host within the mapped domain such as ‘host.wpad.inveigh.net’. In this case, the root of ‘wpad.inveigh.net’ would resolve.

Strangely, I found that Windows DNS servers answered requests for the root of a DNAME record when certain conditions were met. The record needed to match a host that was listed on the GQBL and the GQBL needed to be enabled. With regards to WPAD, the default enabled GQBL actually made things worse.

Unfortunately, I couldn’t get DNAME records to work with dynamic updates. So, back I went looking for another bypass. I found this one in the form of adding an NS record for a WPAD subdomain.

This method is slightly more complicated since it requires that the NS record points to a DNS server under your control. DNSChef, available on Kali, provides a simple way to just setup a DNS server that will answer any received request.

Again, I couldn’t get the bypass to work with dynamic updates. Once I finally started working with LDAP, all three bypass methods became trivial to implement.

Note, there appears to be a slight difference in behavior for 2016 versus previous server versions. If you work with a record type that expects to point to a DNS records instead of IP addresses, you will indeed need to use a DNS record. Earlier DNS server versions worked with IP addresses in most cases. With 2016, if an existing target record does not already exist, you may need to add an additional record to get some record types setup as required for your attack.

CVE-2018-8320

I included details for the three GQBL bypasses when I turned my ADIDNS research over to Microsoft back in June. They informed me that they would assign CVE-2018-8320 for the GQBL and release a patch in October. I then disclosed the ADIDNS research while excluding any reference to WPAD and the GQBL.

The patch did indeed land in October. Here is a run-through of each bypass method on fully patched systems.

Wildcard records no longer resolve requests for hosts listed on the GQBL.

DNAME records no longer resolve requests for hosts listed on the GQBL.

As you can see in the above screenshot, NS records continue to bypass the GQBL.

Domain Suffix Search Order

In the original blog post, I recommended administrator controlled wildcard records as a defense against both ADIDNS wildcard attacks and LLMNR/NBNS spoofing. In a conversation that took place on r/netsec, a couple of people pointed out that wildcard records could cause problems when multiple domain suffixes are assigned to the search list through group policy.

After performing a few tests, I confirmed that they were correct. A wildcard placed in the zone of the higher domain suffix will prevent valid non-fully qualified requests from falling down to any lower domain suffixes where the matching valid record exists.

This behavior leads to an entirely new attack approach. Instead of targeting non-existent records in a zone, you can target requests for existing records. If you can add records to a zone listed as a suffix, you can target valid hosts in any lower priority domain suffix. Non-fully qualified requests for the targeted host will be resolved by the record you added.

Note, DNS suffixes should be taken into consideration when performing wildcard attacks. If you find a search list with multiple DNS suffixes, wildcard attacks could lead to disruptions when injecting into anything but the last zone on the list.

ADIDNS Attacks Through Phishing

With LLMNR/NBNS spoofing, the spoofing tool must continue to run throughout the attack. ADIDNS attacks however are conducted through only a small number of initial actions. Because of this, I believe that ADIDNS attacks are easier to deliver through phishing. Only one AD connected phishing target would need to execute a payload in order to add records potentially capable of sending traffic to remote, attacker controlled systems. You can use these records for things such as C2 or setting up additional phishing attacks.

Above is an example of adding a record pointing to a public IP using one of my PowerShell tools. For an actual phishing attack, you can use something more payload appropriate.

This is another area where NS records can be helpful for attacks. Once you setup the NS record, you can simply add additional records to the controlled subdomain through your own DNS server.

Domain Borrowing

ADIDNS attacks from outside the perimeter are particularly interesting when a company’s internal AD domain matches their public domain. In this scenario, you may be able to leverage the trust of the public domain to get around content filtering.

Of course, there are limitations with this technique. You will only be in a position to impact resources that are using the targeted ADIDNS for name resolution. There is also a chance that the records themselves, or any corresponding event IDs, will give you away. Most importantly, you will have a hard time setting up a trusted certificate for HTTPS due to lack of domain ownership.

C2 and Exfiltration Techniques

A while back, harmj0y posted an interesting blog about using AD as a C2 channel. How does that tie into ADIDNS? To review, when adding dnsNode objects, authenticated users receive full control upon creation. The dnsNode objects also contain a number of writable attributes. This results in dnsNode objects being candidates for C2 and exfiltration techniques through AD.

Of course, purely DNS based C2 and exfiltration techniques are also possible.

ADIDNS Defense Revisited

As mentioned, if you are using a search list with multiple DNS suffixes, an administrator controlled wildcard A record may cause problems. As an alternative, you can create a wildcard using a record type, such as a TXT record, that will not resolve name requests.

Since all record types are stored on a dnsNode object, adding any form of wildcard record will prevent an unprivileged user from adding their own dnsNode named ‘*’. Unfortunately, a non-resolving wildcard record will not have the added benefit of being a defense against LLMNR and NBNS spoofing.

Ultimately, locking down the zone permissions is the cleanest way to mitigate authenticated user ADIDNS attacks. Depending on your setup, you may be able to take advantage of a dedicated DNS dynamic updates account within DHCP. This may allow you to remove the ‘Create all child objects’ permission for ‘Authenticated Users’ altogether.

Finally, keep in mind that many name resolution attacks are made possible by non-fully qualified name requests. User generated requests of this type are difficult to eliminate. When it comes to system and application configurations though, I would recommend always using fully qualified domain names if possible.