At IETF 72 in Dublin I gave a demonstration of DNS spoofing based on the attack on DNS described by Dan Kaminsky. I was able to successfully inject a fake DNS record in to the cache of a name server with a fixed port in a few seconds and sometimes in well under a second.
Bert Hubert published a description of the math behind this attack on namedroppers and I have been playing with the spoofer to see how close I can get the experiment and theory.
I ran my spoofer on a network consisting of three machines linked by a cheap gigabit switch. The attacker was on a Mac Pro, the target nameserver was on a Mac Book Pro and the authoritative server, that the attacker was pretending to be, was on a old FreeBSD box (100Mb). I used DUMMYNET to simulate a longer link to the authoritative server (delay = 30ms).
I ran the spoofer 1000 times and plotted a histogram of the frequency of success against time.
The pink bar shows the median of all the times recorded. If I recall my A level maths correctly, this should coincide with the 50% chance of success predicted by the math.
The math presented by Bert Hubert considers the expansion of the binomial
Ps = probability of success on a single attempt
Pf = probability of failure on a single attempt
( Ps + Pf )^n = 1
Expanding this and remembering that the sum of all the terms containing success = (1- the term for always failing) leads to the probability of combined success
Pcs(n) = 1 – (1 – Ps)^(n)
We know that n = T/W so we get
Pcs(t) = 1 – (1 – Ps)^(t/W)
Bert Hubert tells us that Ps = (D*R*W)/(N*P*I) where
I: Number distinct IDs available (maximum 65536)
P: Number of ports used (maximum around 64000 as ports under 1024
are not always available, but often 1)
N: Number of authoritative nameservers for a domain (averages
around 2.5)
R: Number of packets sent per second by the attacker
W: Window of opportunity, in seconds. Bounded by the response
time of the authoritative servers (often 0.1s)
D: Average number of identical outstanding queries of a resolver
(typically 1, see Section 5)
I used the following values
I=65535
R=36000 – From looking at the traffic I was sending
W=0.030 – From the settings I gave DUMMYNET
N=1.0 (I fixed this)
P=1 (I fixed this)
D=1
Plotting this on the same graph as the histogram gives:
The blue circles are the predicted probability of combined success (Their y axis runs from 0 to 1 and is not shown). As you can see the predicted 50% chance (black cross lines) occurs slightly before the median but it is fairly close.
In order to improve things I added an extra term to the equation to account for the time that the window is closed (This is due to the spoofer taking a bit of time to notice that it has been unsuccessful and to try again). So:
n = T/(W+Wc)
Ps = (D*R*W))/(N*P*I)
where Wc is measured to be about 0.003 seconds. The graph now looks like
That seems like good agreement to me. The median in this case is 1386ms.
BTW: The graphs were plotted using R. This is the code I used
#Plot a histogram of frequency of success against time mydata <- read.table("/tmp/speed-test-30ms",header=TRUE) #Plot both on a single graph h <- hist(mydata$time,breaks=100,plot=FALSE) plot(h,freq=FALSE, xlim=range(h$mids),ylim=range(h$density), sub="Histogram showing time to success of real spoofer (pink line shows median)", main="DNS Spoofer Performance", ylab="Density", xlab="Time/ms") abline(v=median(mydata$time),col=70) #Plot Bert Hubert's math D=1.0 R=36000.0 W=0.030 Wc=0.003 N=1.0 P=1 I=65535 Ps <- ((D*R*W)/(N*P*I)) Pcs <- function(t){1 - (1 - Ps)**((t/1000)/(W+Wc))} par(new=TRUE) nx <- sample(h$mids) y=Pcs(nx) #Scale plot to same as histogram my=max(y) ny=y*max(h$density)/my plot(nx,ny, xlim=range(h$mids),ylim=range(h$density),col="blue", ann=FALSE) #Calculate time for 0.5 chance time5 = 1000*(W+Wc)*(log10(0.5)/log10(1 - Ps)) abline(v=time5) abline(h=0.5*max(h$density)/my)
Wouter
Pingback: intir.net » Blog Archive » Why DNS is Broken, in Plain English