Nmap Development mailing list archives
Re: DNS cache snooping script
From: Ron <ron () skullsecurity net>
Date: Mon, 12 Apr 2010 13:55:42 -0500
For what it's worth, I tested the script against a bunch of different DNS servers, and it worked as advertised. I'm pretty sure none of the servers lied in their responses, though. Am I crazy, or did you copy/paste the script straight into your email? Can you send it as an attachment instead? I had to fix a bunch of formatting before I could run it. Thanks! On Mon, 12 Apr 2010 10:50:29 -0600 Eugene Alexeev <eugene.alexeev () gmail com> wrote:
Ron, Thanks! I'm glad you like the script. I based the default list on the the thought: "If I was doing a pen test against someone, what would I like to know?". The answer I came up with for this question was: 1. If I have to do social engineering, where can I find the employees? 2. What operating systems are present in the environment, even if they are not visible during the nmap scan? 3. [How] do they patch and how frequently? 4. How would I detect that the DNS server is lying to me? So based on that, I stuck in: common social sites, email login pages, operating system pages, some update pages, and some obscure pages (like kernel.org and insecure.org). I've also built in the ability for the user to supply their own queries via --script-args snoop_hosts={host0\,host1\,hostN}. I have not looked into multiple host names per query, but I will investigate it. Timed mode takes the longest because the script does 25 look ups on www.google.com once it's been cached to profile how long a cached query takes. I've not benchmarked the script, but the default configuration appears to perform reasonably (~ under 15 seconds). My unofficial observations are that cached queries take between 10-130ms on average and non-cached queries can take as long as 4 seconds. So, it all depends on you patient you can afford to be! Eugene On Mon, Apr 12, 2010 at 10:33 AM, Ron <ron () skullsecurity net> wrote:Hey Eugene, That script looks really cool! I was thinking of writing something similar, but you saved me the trouble. Out of curiosity, where did you get the list of domains you look for, or is it simply arbitrary? I'm trying to think of which domains would be the most interesting - maybe others will have some better input than me. My first thought is those used by automatic updaters (java update, oracle, windows, etc), those used by different Linux distributions, and those used by known malware. All of them could be interesting when testing a network. I was thinking of the top-xxx sites from some service (Alexa, I think?), but I don't think that'd give you anything interesting. How long does it take to look up the different domains? Are/can you look up more than one hostname per DNS request to speed it up? How many domains can be realistically checked in a single query? Tens, hundreds, thousands? On Mon, 12 Apr 2010 10:18:23 -0600 Eugene Alexeev <eugene.alexeev () gmail com> wrote:All, I'm submitting the following NSE script for your scrutiny. Please note that it may error out with versions that do not include the fix to dns.lua that was addressed by svn revision 17270. description = [[ Performs DNS cache snooping against a DNS server. This script has two modes of operation: non-recursive (used by default) and timed. The default mode makes DNS type A queries to the dns server with the Recursion Desired (RD) flag set to 0 and tries set to 0. Any successful queries are assumed to come from the server's cache. The timed mode uses temporal analysis to deterime where or not each host is in the server's cache. First, it sends a recursive DNS query for www.google.com to the server. This ensures that the response for www.google.com has been cached. It then makes recursive requests for each host in the list and records their timing information. Then the mean cached query time is calculated along with cached query time sigma. Each host's timing data is then evaluated, if the query tooklonger than cached mean + ( cached sigma * multiplier), then the response is considered not to have been cached. Please note that the timed mode will pollute the DNS server's cache. ]] --- -- @param snoop_mode timed: use the timed mode rather than the default -- non-recursive mode. -- @param snoop_multiplier x.x: can be used to adjust the maxDeviation parameter -- used in timed mode. -- @param snoop_hosts {host0,host1,hostN}: check if the supplied hosts are -- in the DNS cache rather than querying using default -- snoop_hosts table. -- -- @output -- 53/udp open|filtered domain -- | dns-cache-snoop: DNS cache contains: -- | --> login.yahoo.com -- | --> mail.aol.com -- | --> my.screenname.aol.com -- | --> gmx.com -- | --> hotmail.com -- | --> login.live.com -- | --> www.facebook.com -- | --> facebook.com -- | --> www.twitter.com -- | --> twitter.com -- | --> www.linkedin.com -- |_--> linkedin.com -- -- @usage -- nmap --script dns-cache-snoop.nse \ -- --script-args snoop_mode=timed, -- snoop_multiplier=x.x, -- snoop_hosts={host0\,host1\,hostN} require('shortport') require('dns') require('stdnse') require('nmap') require('math') author = "Eugene V. Alexeev" license = 'Same as Nmap--See http://nmap.org/book/man-legal.html' categories = {'default', 'intrusive', 'discovery'} portrule = shortport.portnumber(53, 'udp') --- Default list of hosts to check --@class table --@name snoop_hosts local snoop_hosts = { 'mail.google.com', 'gmail.com', --- Gmail 'mail.yahoo.com', 'login.yahoo.com', --- Yahoo Mail 'mail.aol.com', 'my.screenname.aol.com', --- AOL/AIM Mail 'www.gmx.com', 'gmx.com', --- GMX Mail 'hotmail.com', 'login.live.com', --- Hotmail / MSN Live 'www.facebook.com', 'facebook.com', --- Facebook 'www.twitter.com', 'twitter.com', --- Twitter 'www.linkedin.com', 'linkedin.com', --- LinkedIn 'www.plaxo.com', 'plaxo.com', --- Plaxo 'www.myspace.com', 'myspace.com', --- MySpace 'www.ivillage.com', 'ivillage.com', --- iVillage 'www.flickr.com', 'flickr.com', --- Flickr 'www.youtube.com', 'youtube.com', --- Youtube 'www.digg.com', 'digg.com', --- Digg 'www.reddit.com', 'reddit.com', --- Reddit 'www.craigslist.com', 'craigslist.com', --- Craigslist 'update.microsoft.com', --- MS Patches 'www.microsoft.com', 'microsoft.com', --- General MS 'technet.microsoft.com', --- Technet Access 'rhn.com','rhn.redhat.com','redhat.com', --- RHN Access 'www.novell.com', 'novell.com', --- SLES / SLED 'www.kernel.org', 'kernel.org', --- Kernel Sources, etc 'www.ubuntu.com', 'ubuntu.com', --- Ubuntu 'www.debian.com', 'debian.com', --- Debian 'www.freebsd.org', 'freebsd.org', --- FreeBSD 'www.openbsd.org', 'openbsd.org', --- OpenBSD 'www.oracle.com', 'oracle.com', --- Oracle 'docs.sun.com', 'www.sun.com', 'sun.com', --- Sun/Solaris Docs 'www.centos.org', 'centos.org', --- CentOS 'www.nmap.org', 'nmap.org', --- Couldn't Resist 'ha.ckers.org', 'sla.ckers.org' --- Should not be present --- in most caches! } --- Default snoop_multiplier, used to control the maxDeviation paramter in -- timed mode, has no meaning in non-recursive mode. -- @class number -- @name snoop_multiplier local snoop_multiplier = 1.0 --- Function to determine the standard deviation of a table -- @class function -- @name standardDeviation -- @param t table containing numeric values --- @return sigma for values in table t -- THIS FUNCTION WAS NOT WRITTED BY ME, FULL CREDIT GOES TO THE AUTHOR OF: -- http://lua-users.org/wiki/SimpleStats function standardDeviation( t ) local m local vm local sum = 0 local count = 0 local result m = mean( t ) for k,v in pairs(t) do if type(v) == 'number' then vm = v - m sum = sum + (vm * vm) count = count + 1 end end result = math.sqrt(sum / (count-1)) return result end --- Function to determine the mean value of a table -- @class function -- @name mean -- @param t table containing numeric values -- @return the mean for values in table t -- THIS FUNCTION WAS NOT WRITTED BY ME, FULL CREDIT GOES TO THE AUTHOR OF: -- http://lua-users.org/wiki/SimpleStats function mean( t ) local sum = 0 local count= 0 for k,v in pairs(t) do if type(v) == 'number' then sum = sum + v count = count + 1 end end return (sum / count) end --- Wrapper for nselib/dns.query function, performs non-recursive DNS queries -- @class function -- @name nr_query -- @param hostname hostname to look up -- @param host host table provided by NSE -- @param port port table provided by NSE -- @return true if an answer is received -- @return false if no answer is recevied function nr_query(hostname, host, port) local q = dns.query(hostname, -- Host name to query for {host=host.ip, -- IP of DNS server port=port.number, -- Port of DNS server tries = 0, -- Do not query other servers norecurse=true}) -- Perform a non-recursive query if q then return true else return false end end --- Function to calculate the time (ms) it took to perform a specific recursive -- DNS query. -- @class function -- @name timed_query -- @param hostname hostname to look up -- @param host host table provided by NSE -- @param port port table provided by NSE -- @return response time in ms -- @return -1 if an error occured function timed_query(hostname, host, port) local start = nmap.clock_ms() local q = dns.query(hostname, -- Host name to query for {host=host.ip, -- IP of DNS server port=port.number, -- Port of DNS server tries=0, -- Do not query other servers norecurse=false}) -- Perform a recursive query local stop = nmap.clock_ms() if q then return (stop - start) else return -1 end end action = function(host, port) local inCache = {} if nmap.registry.args.snoop_hosts ~= nil then stdnse.print_debug("Will snoop for %d custom hosts", #nmap.registry.args.snoop_hosts) snoop_hosts = nmap.registry.args.snoop_hosts end --- Timed mode if nmap.registry.args.snoop_mode ~= nil and nmap.registry.args.snoop_mode == "timed" then stdnse.print_debug("Using timed mode.") if nmap.registry.args.snoop_multiplier ~= nil then stdnse.print_debug("Setting snoop_multiplier to %f", nmap.registry.args.snoop_multiplier) snoop_multiplier = nmap.registry.args.snoop_multiplier end timed_query('www.google.com', host, port) local cachedTimes = {} for i=1,25 do local ms = timed_query('www.google.com', host, port) if ms > 0 then table.insert(cachedTimes, ms) end end local queryTimes = {} for i,hostname in ipairs(snoop_hosts) do local ms = timed_query(hostname, host, port) if ms > 0 then queryTimes[hostname] = ms end end local cachedMean = mean(cachedTimes) local cachedSigma = standardDeviation(cachedTimes) local maxDeviation = cachedSigma * snoop_multiplier local maxCachedTime = cachedMean + maxDeviation stdnse.print_debug("Mean cached response time: %f ms", cachedMean) stdnse.print_debug("Cached response time sigma: %f ms", cachedSigma) stdnse.print_debug("Max Deviation: %f ms", maxDeviation) for hostname, response_time in pairs(queryTimes) do stdnse.print_debug("%s : %f", hostname, response_time) if response_time > 0 and response_time <= maxCachedTime then table.insert(inCache, hostname) end end --- Non-recursive mode else for i,hostname in ipairs(snoop_hosts) do if nr_query(hostname, host, port) then table.insert(inCache, hostname) end end end --- Organize and return the results local resultString = "DNS cache contains:\n" for i,hostname in ipairs(inCache) do resultString = resultString .. "-->\t" .. hostname .. "\n" end if # resultString > 20 then return resultString else return end end Thanks for your time & looking forward to your feedback. Eugene _______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/-- Ron Bowes http://www.skullsecurity.org http://www.twitter.com/iagox86 _______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
-- Ron Bowes http://www.skullsecurity.org http://www.twitter.com/iagox86
Attachment:
_bin
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- DNS cache snooping script Eugene Alexeev (Apr 12)
- Re: DNS cache snooping script Ron (Apr 12)
- Re: DNS cache snooping script Eugene Alexeev (Apr 12)
- Re: DNS cache snooping script Ron (Apr 12)
- Re: DNS cache snooping script Eugene Alexeev (Apr 12)
- Re: DNS cache snooping script David Fifield (May 14)
- Re: DNS cache snooping script Eugene Alexeev (May 15)
- Re: DNS cache snooping script David Fifield (May 15)
- Re: DNS cache snooping script David Fifield (Jun 11)
- Re: DNS cache snooping script Martin Holst Swende (Jun 12)
- Re: DNS cache snooping script David Fifield (Jun 12)
- Re: DNS cache snooping script Eugene Alexeev (Apr 12)
- Re: DNS cache snooping script Ron (Apr 12)
- Re: DNS cache snooping script Eugene Alexeev (Apr 12)