Yeah…it’s about time we talk about this, isn’t it?
As part of mitigating the threat posed by the Kaminsky vulnerability, which Dan explains in detail in a blog post he published a while ago, Microsoft released patches to the Windows DNS servers that included a feature called “socket pool”. This was released as Microsoft Security Bulletin MS 08-037.
In Windows 7, there is another additional feature that adds another layer of security called “cache locking”. I’ll talk a bit about both these features now.
The Socket Pool is the way Windows DNS achieves source port randomization. Instead of using a predicable source port when issuing queries, the DNS server will now randomly pick a source port from a pool of sockets that it opens when the service starts. Depending on the OS version, the socket pool is opened either in the 49k to 64k range or the 10k to 49k range. An attacker will have to guess this source port in addition to the random transaction ID to be able to successfully execute the cache poisoning attack.
The size of the socket pool is stored in the registry under HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\SocketPoolSize. If you open regedit and don’t see this key present, then that means that the DNS server is using a default of 2,500 ports. The registry key only gets created when you attempt to modify this value.
When the DNS service starts up, it reads the value of the socket pool size from this registry location. It then calls the TCP/IP stack and begins to open up these sockets. Once they’re all open, the DNS server randomly picks a socket for each query it sends.
By default, the socket pool size is 2,500. Note that this means 2,500 ports for IPv4 and 2,500 ports for IPv6. The max value for the socket pool is 10,000.
How do you control the value of this setting?
Ø Dnscmd /Info /SocketPoolSize will tell you the current size of the socket pool
Ø Dnscmd /Config /SocketPoolSize <val> sets the socket pool size to #val
Ø Once you reset the size, you must restart the DNS service. Use net stop dns to stop the service, and net start dns to restart the service. Once the service has restarted, the new socket pool will come into effect.
Now some customers experienced loss of Internet connectivity after installing this patch on computers that had certain versions of ZoneAlarm installed. ZoneAlarm released a bulletin to address this issue.
Last week NetworkWorld.com published an article that said that one in four DNS servers are still vulnerable to Kaminsky flaw. If you’re running Windows DNS and haven’t patched yet, do so! Do it now. Remember, this mainly affects recursive DNS servers, so if you have no recursive DNS servers, you can panic less.
In Windows Server 2008 R2 DNS server, we’ve made an additional tweak to the socket pool. The patch released only allows you to turn on/off the socket pool and specify a socket pool size. However in R2, you can now specify an exclusion list – i.e. a list of ports/port ranges that the DNS server should not bind to. Therefore, if you have another application on your DNS server that you know binds to a specific port in the 49k – 65k range, then you can add that port to the exclusion list. DNS server will not bind to that port (or ports) and leave them free for the other application to use.
To set up this exclusion list (available only on Windows Server 2008 R2), use:
Ø Dnscmd /Config /SocketPoolPortExclusionList
Now Windows Server 2008 R2 DNS server (aka Windows 7 server) contains an additional layer of security with a feature called cache locking. Understanding TTLs is key to understanding this feature.
Each DNS resource record comes with a Time-To-Live (TTL) value. This tells another caching server/resolver how long to keep the record in the cache before deleting it. Accordingly, until the TTL expires, the server will retain the record in the cache. However there is nothing preventing the server from overwriting the entry in the cache before the TTL expires if it receives updated information about that name.
One of the most dangerous aspects of the Kaminsky attack is that it allows an attacker to overwrite a pre-existing cached delegation. A reasonably valid assumption is that for any domain that is worth attacking, all DNS servers that are serving a typical set of clients will have a valid cached delegation in memory in the steady state. As soon as the valid cached delegation expires, another client is likely to fairly quickly submit a query for a name in the zone, causing the delegation to be re-cached.
Cache locking is measured as a % value. For example, if the cache locking value is set to 50%, then the DNS server will not overwrite a cached entry for 50% of its TTL. So, if the DNS server has a cached entry for www.contoso.com with a TTL of 60 minutes, for the first 30 minutes after creating the cache entry, the DNS server will not overwrite the entry even if it receives different data about www.contoso.com.
How does this protect against the Kaminsky vulnerability? Think about what the attacker is doing – he is running the race over and over again, by querying for 1.contoso.com, 2.contoso.com, 3.contoso.com and bombarding a reply that essentially says “Don’t know where n.contoso.com is, but ask www.contoso.com, who by the way is at <attacker’s IP>.” And, to successfully complete the attack, he’s counting on the fact that if/when he does win the race, his IP address gets cached against www.contoso.com, overwriting what already may be there.
By default, the cache locking percent value is 100. This means that cached entries will not be overwritten for the entire duration of the TTL.
The value is stored in this registry location: HKLM\SYSTEM\CurrentControlSet\Services\DNS\Parameters\CacheLockingPercent. As with the socket pool, if you look at the registry and don’t see this registry key, then the DNS server will assume a default of 100. The registry key only gets created when you attempt to modify the value.
Here’s the magic that makes it work (available only on Windows Server 2008 R2):
Ø Dnscmd /Info /CacheLockingPercent will tell you what the current value of the cache locking percent is.
Ø Dnscmd /Config /CacheLockingPercent <val> will set the cache locking percentage to #val.