Poisoning DNS servers is nothing new. However this particular exploit is far more feasible and dangerous than its predecessors. Credit is generally given to Dan Kaminsky for raising awareness of the criticality of this issue and coordinating a massive effort with vendors to issue patches. He gave the vendors time to make patches, then the public time to apply them before publicly releasing all the details. In admirably white hat fashion, he did everything altruistically and "right". Kudos.
The exploit builds off the old trick of spoofing replies back to the requesting name server. The challenges for the attacker are:
- Knowing when a DNS server is issuing a particular DNS lookup,
- Guessing the DNS query's transaction ID (the spoofed reply must have a transaction ID matching what was used in the original query),
- Creating a proper spoofed packet with poisoned information in it, and
- Getting the spoofed response to the requester before the real response comes back.
- #1 is a real challenge since a DNS server will only perform a name lookup every once in a while (every Time To Live [TTL], usually hours or days). If the server doesn't already have a name cached, you know you can try to spoof the response right then, but you only get one shot.
- #2 is not as hard, theoretically it should be possible to blast back 65,536 spoofed responses (one for each transaction ID). The fact this ID is only 16 bit is generally accepted as being too weak.
- For #3, the vulnerable DNS servers in question reuse the same source port for every outgoing request, which makes crafting the spoofed return UDP packets trivial (DNS servers that already randomized the source port are generally seen as being practically immune to this exploit, since attackers would have to guess nearly 2^32 combinations instead of only 65,536).
- For #4, optional "good netizen" ISP egress filtering may stop spoofed packets. And latency may work against an attacker. But an attacker attacking his own ISP might not face either of these problems.
The two twists with the new exploit are that it overcomes challenge #1, and indirectly poisons the DNS server through the use of additional Resource Records (RRs). (Side note: as another security precaution, RRs are only trusted in a response if they're in the same "bailiwick", or domain, as the name requested (i.e. you can't poison a server with bad RRs for someone else's domain, say yahoo.com, if the lookup was for google.com). However this is not an issue at all for this particular exploit.). The attacker repeatedly asks the victim DNS server for tons of different lookups for subdomains of the desired name to spoof (1.google.com, 2.google.com, 3.google.com, etc), blasts tons of spoofed responses back hoping one transaction ID will match, and in each response adds an additional, poisoned RR, containing the name to spoof and whatever IP address the attacker desires.
- Attacker asks Victim DNS Server: who is 1.google.com?
- Victim DNS server asks the authority for google.com, who is 1.google.com?
- Attacker blasts Victim with spoofed responses, each containing a different transaction ID. The packet contains a response with an IP for 1.google.com, as well as an additional RR stating www.google.com is an IP address of the Attacker's choosing.
- (Here is the exploit) If a valid, spoofed response is received before the real response comes back, the Victim updates its cache with both the requested info as well as the poisonous IP information contained in the RR. The subsequent response from the authority for google.com is discarded.
10 minutes to replace cnn.com, or youtube.com, or any other popular site with a site of your own choosing. Defame a site, get people to read your manifesto or see something embarrassing or obscene, or try to phish for their personal information. Yes, this really is a big deal--yes, only for the people using the victimized DNS server, but if an attacker were able to target DNS servers at several large ISPs, it could have a huge impact.
If the above wasn't clear enough, I would recommend reading this copy of someone leaking the information before it should have been publicly disclosed (it has been mirrored everywhere). While it's not perfect (enough with the deli analogy), it does explain the problem fairly well.
Also this sample exploit code provides a good technical summary of what the problem is and how it works. It's worth reading through the code to get a feel for how it all works. I particularly like the technique in cmd_check() of discovering what port your DNS server uses to make requests (issuing a TXT lookup to spoofprobe-check-x-xxxxxx.red.metasploit.com, which returns a value of hostname:port).
This exploit attacks a fairly ubiquitous flaw in DNS implementations which Dan Kaminsky found and disclosed ~Jul 2008. This exploit caches a single malicious host entry into the target nameserver by sending random sub-domain queries to the target DNS server coupled with spoofed replies to those queries from the authoritative nameservers for the domain which contain a malicious host entry for the hostname to be poisoned in the authority and additional records sections. Eventually, a guessed ID will match and the spoofed packet will get accepted, and due to the additional hostname entry being within bailiwick constraints of the original request the malicious host entry will get cached.
So what's the fix? There really is no fix, short of using DNSSEC, or moving to some other cryptographic method of trust. Using TCP instead of UDP has come up (this would add the additional, now nearly impossible challenge of guessing sequence numbers), but was shot down as being too resource intensive. So the accepted workaround is what was already mentioned above: DNS servers should randomize their source ports. Then attackers would have a much, much harder time spoofing the return packets. There appears to be some reaction that this is old news, and many DNS server implementations had already done this, long ago. Just not the big ones :-) (e.g. BIND).
Finale: Patches for all affected DNS servers should be up by now. Be sure to patch your systems.
Update 6:12pm: a newer version of the example exploit code demonstrates how to replace NS records for an entire domain (vs. a single A record).