9.8 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
10 High
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:N/AC:L/Au:N/C:C/I:C/A:C
0.973 High
EPSS
Percentile
99.8%
Performs DNS cache snooping against a DNS server.
There are two modes of operation, controlled by the dns-cache-snoop.mode
script argument. In nonrecursive
mode (the default), queries are sent to the server with the RD (recursion desired) flag set to 0. The server should respond positively to these only if it has the domain cached. In timed
mode, the mean and standard deviation response times for a cached domain are calculated by sampling the resolution of a name (www.google.com) several times. Then, each domain is resolved and the time taken compared to the mean. If it is less than one standard deviation over the mean, it is considered cached. The timed
mode inserts entries in the cache and can only be used reliably once.
The default list of domains to check consists of the top 50 most popular sites, each site being listed twice, once with “www.” and once without. Use the dns-cache-snoop.domains
script argument to use a different list.
which of two supported snooping methods to use. nonrecursive
, the default, checks if the server returns results for non-recursive queries. Some servers may disable this. timed
measures the difference in time taken to resolve cached and non-cached hosts. This mode will pollute the DNS cache and can only be used once reliably.
an array of domain to check in place of the default list.
nmap -sU -p 53 --script dns-cache-snoop.nse --script-args 'dns-cache-snoop.mode=timed,dns-cache-snoop.domains={host1,host2,host3}' <target>
PORT STATE SERVICE REASON
53/udp open domain udp-response
| dns-cache-snoop: 10 of 100 tested domains are cached.
| www.google.com
| facebook.com
| www.facebook.com
| www.youtube.com
| yahoo.com
| twitter.com
| www.twitter.com
| www.google.com.hk
| www.google.co.uk
|_www.linkedin.com
local dns = require "dns"
local formulas = require "formulas"
local nmap = require "nmap"
local shortport = require "shortport"
local stdnse = require "stdnse"
local string = require "string"
local table = require "table"
description = [[
Performs DNS cache snooping against a DNS server.
There are two modes of operation, controlled by the
<code>dns-cache-snoop.mode</code> script argument. In
<code>nonrecursive</code> mode (the default), queries are sent to the
server with the RD (recursion desired) flag set to 0. The server should
respond positively to these only if it has the domain cached. In
<code>timed</code> mode, the mean and standard deviation response times
for a cached domain are calculated by sampling the resolution of a name
(www.google.com) several times. Then, each domain is resolved and the
time taken compared to the mean. If it is less than one standard
deviation over the mean, it is considered cached. The <code>timed</code>
mode inserts entries in the cache and can only be used reliably once.
The default list of domains to check consists of the top 50 most popular
sites, each site being listed twice, once with "www." and once without.
Use the <code>dns-cache-snoop.domains</code> script argument to use a
different list.
]]
---
-- @args dns-cache-snoop.mode which of two supported snooping methods to
-- use. <code>nonrecursive</code>, the default, checks if the server
-- returns results for non-recursive queries. Some servers may disable
-- this. <code>timed</code> measures the difference in time taken to
-- resolve cached and non-cached hosts. This mode will pollute the DNS
-- cache and can only be used once reliably.
-- @args dns-cache-snoop.domains an array of domain to check in place of
-- the default list.
--
-- @usage
-- nmap -sU -p 53 --script dns-cache-snoop.nse --script-args 'dns-cache-snoop.mode=timed,dns-cache-snoop.domains={host1,host2,host3}' <target>
--
-- @output
-- PORT STATE SERVICE REASON
-- 53/udp open domain udp-response
-- | dns-cache-snoop: 10 of 100 tested domains are cached.
-- | www.google.com
-- | facebook.com
-- | www.facebook.com
-- | www.youtube.com
-- | yahoo.com
-- | twitter.com
-- | www.twitter.com
-- | www.google.com.hk
-- | www.google.co.uk
-- |_www.linkedin.com
author = "Eugene V. Alexeev"
license = "Same as Nmap--See https://nmap.org/book/man-legal.html"
categories = {"intrusive", "discovery"}
portrule = shortport.port_or_service(53, "domain", "udp")
local DOMAINS = {}
local MODE = "nonrecursive"
-- This domain is used as a default cached entry in timed mode.
local TIMED_DUMMY_DOMAIN = "www.google.com"
-- How many samples to collect for the time taken to resolve the dummy domain.
local TIMED_NUM_SAMPLES = 25
-- In timed mode, times below mean + TIMED_MULTIPLIER * stddev are
-- accepted as cached. Using one standard deviation gives us a roughly
-- 84% chance that a domain with the same response time as the reference
-- domain will be detected as cached.
local TIMED_MULTIPLIER = 1.0
-- This list is the first 50 entries of
-- http://s3.amazonaws.com/alexa-static/top-1m.csv.zip on 2013-08-08.
local ALEXA_DOMAINS = {
"google.com",
"facebook.com",
"youtube.com",
"yahoo.com",
"baidu.com",
"wikipedia.org",
"amazon.com",
"qq.com",
"live.com",
"linkedin.com",
"twitter.com",
"blogspot.com",
"taobao.com",
"google.co.in",
"bing.com",
"yahoo.co.jp",
"yandex.ru",
"wordpress.com",
"sina.com.cn",
"vk.com",
"ebay.com",
"google.de",
"tumblr.com",
"msn.com",
"google.co.uk",
"googleusercontent.com",
"ask.com",
"mail.ru",
"google.com.br",
"163.com",
"google.fr",
"pinterest.com",
"google.com.hk",
"hao123.com",
"microsoft.com",
"google.co.jp",
"xvideos.com",
"google.ru",
"weibo.com",
"craigslist.org",
"paypal.com",
"instagram.com",
"amazon.co.jp",
"google.it",
"imdb.com",
"blogger.com",
"google.es",
"apple.com",
"conduit.com",
"sohu.com",
}
-- Construct the default list of domains.
for _, domain in ipairs(ALEXA_DOMAINS) do
DOMAINS[#DOMAINS + 1] = domain
if not string.match(domain, "^www%.") then
DOMAINS[#DOMAINS + 1] = "www." .. domain
end
end
local function nonrecursive_mode(host, port, domains)
local cached = {}
for _,domain in ipairs(domains) do
if dns.query(domain, {host = host.ip, port = port.number, tries = 0, norecurse=true}) then
cached[#cached + 1] = domain
end
end
return cached
end
-- Return the time taken (in seconds) to resolve the given domain, or nil if
-- it could not be resolved.
local function timed_query(host, port, domain)
local start, stop
start = nmap.clock_ms()
if dns.query(domain, {host = host.ip, port = port.number, tries = 0, norecurse = false}) then
stop = nmap.clock_ms()
return (stop - start) / 1000
else
return nil
end
end
local function timed_mode(host, port, domains)
local cached = {}
local i, t
-- Insert in the cache.
timed_query(host, port, TIMED_DUMMY_DOMAIN)
-- Measure how long it takes to resolve on average.
local times = {}
for i = 1, TIMED_NUM_SAMPLES do
t = timed_query(host, port, TIMED_DUMMY_DOMAIN)
if t then
times[#times + 1] = t
end
end
local mean, stddev = formulas.mean_stddev(times)
local cutoff = mean + stddev * TIMED_MULTIPLIER
stdnse.debug1("reference %s: mean %g stddev %g cutoff %g", TIMED_DUMMY_DOMAIN, mean, stddev, cutoff)
-- Now try all domains one by one.
for _, domain in ipairs(domains) do
t = timed_query(host, port, domain)
if t then
if t < cutoff then
stdnse.debug1("%s: %g is cached (cutoff %g)", domain, t, cutoff)
cached[#cached + 1] = domain
else
stdnse.debug1("%s: %g not cached (cutoff %g)", domain, t, cutoff)
end
end
end
return cached
end
action = function(host, port)
local domains = DOMAINS
local mode = MODE
local args = nmap.registry.args
if args then
if args["dns-cache-snoop.mode"] then
mode = args["dns-cache-snoop.mode"]
end
if args["dns-cache-snoop.domains"] then
domains = args["dns-cache-snoop.domains"]
end
end
local cached
mode = string.lower(mode)
if mode == "nonrecursive" then
cached = nonrecursive_mode(host, port, domains)
elseif mode == "timed" then
cached = timed_mode(host, port, domains)
else
return string.format("Error: \"%s\" is not a known mode. Use \"nonrecursive\" or \"timed\".")
end
if #cached > 0 then
nmap.set_port_state(host, port, "open")
end
return string.format("%d of %d tested domains are cached.\n", #cached, #domains) .. table.concat(cached, "\n")
end
9.8 High
CVSS3
Attack Vector
NETWORK
Attack Complexity
LOW
Privileges Required
NONE
User Interaction
NONE
Scope
UNCHANGED
Confidentiality Impact
HIGH
Integrity Impact
HIGH
Availability Impact
HIGH
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
10 High
CVSS2
Access Vector
NETWORK
Access Complexity
LOW
Authentication
NONE
Confidentiality Impact
COMPLETE
Integrity Impact
COMPLETE
Availability Impact
COMPLETE
AV:N/AC:L/Au:N/C:C/I:C/A:C
0.973 High
EPSS
Percentile
99.8%