Summary

  • Kaminsky-class poisoning renewed an off-path guessing race with fresh queries, letting a forger keep trying to make one fabricated response match a resolver's outstanding question before the authentic answer arrived.
  • The coordinated 2008 patches did not authenticate DNS data. They enlarged the local acceptance space with unpredictable transaction IDs and per-query source ports, a gain that had to survive NAT and firewall behavior and be verified on the wire.

A resolver did not decide which answer was true

A recursive resolver in 2008 usually asked an authoritative server over unsigned UDP and waited. It had no cryptographic proof inside an ordinary response. Instead, it checked whether the reply looked like an answer to work already in flight.

RFC 5452 later stated the boundary with unusual clarity. The reply's question had to match an outstanding question. Its transaction ID had to match. It had to appear to come from the address queried and return to the address and port from which the resolver had sent the question. In general, the first response satisfying those conditions was accepted.

That rule made speed part of effective authority. An off-path attacker could not see the query, but could forge the source address of an authoritative server and send many candidate replies. One candidate needed the right observable tuple and had to beat the legitimate packet. Once accepted, the resolver repeated the false data to clients until the cache state changed.

The result could redirect web traffic, mail and other name-dependent services. Yet the mechanism was narrower than “the attacker controlled DNS.” It controlled what one cache believed, for the names and lifetime admitted by the forged material. The distinction matters because every defense acts on a different boundary: query admission, response matching, cache relevance, effective randomness, or cryptographic validation.

The race learned how to restart itself

Cache poisoning and transaction-ID guessing were not new in 2008. RFC 3833 had documented ID prediction and name-chaining threats four years earlier. The 16-bit ID offered only 65,536 values, and some implementations made even less uncertainty available through weak generators or predictable behavior. A fixed UDP source port contributed no fresh secret.

Dan Kaminsky's contribution was to show the practical force of combining known weaknesses into repeated opportunities. An attacker could induce the resolver to ask for a previously unseen label beneath a target domain. Because that random label was absent from cache, the resolver had to send a new authoritative query. The attacker then raced forged answers against it. Another new label opened another race.

The disposable label was the trigger, not necessarily the prize. A forged response could attempt to install delegation information affecting the parent target, subject to the resolver's relevance and bailiwick rules. A failed guess therefore did not require waiting for an attractive cached record to expire. The attacker manufactured another cache miss and tried again.

RFC 5452 describes the consequence as an effectively near-zero TTL for repetitive attack classes. Under one stated model—7,000 forged packets per second and one source port—the probability of success reached 50 per cent in about seven seconds. That is not a universal exploit time. It is a calculation whose assumptions expose the control failure: when the race can be renewed cheaply, a small per-attempt chance becomes a practical path.

The emergency patch added a second dial

The coordinated response changed what a forged packet had to predict. Instead of sending every recursive query from one stable UDP port, patched resolvers selected an unpredictable source port per query and used unpredictable transaction IDs. The port became an additional local identifier.

The arithmetic changed sharply. RFC 5452 estimated that an unknown port drawn from roughly 64,000 choices expanded the problem space by the same factor. Under its repetitive 7,000-packet-per-second example, the 50 per cent point moved from about seven seconds with one port to about 116 hours with 64,000. CERT/CC described the design as adding approximately 16 bits of randomness in principle, while stressing that reserved and occupied ports reduce the usable set.

This was a powerful mitigation because it preserved the wire protocol. Authoritative servers did not need a new packet format to answer a query sent from a different source port. Resolver vendors could change their running implementations, operators could deploy updates, and interoperability could continue.

It was not free. ISC warned that its initial BIND patch could have noticeable performance impact above roughly 10,000 queries per second and offered beta branches with optimized behavior. Firewalls configured to permit DNS only from one outbound source port needed correction. High-volume resolvers behind stateful devices could consume more translation entries.

The patch therefore moved risk rather than abolishing engineering. It traded a predictable acceptance tuple for a larger socket and state-management problem. That trade was rational, measurable and locally reversible. It was not magic.

The wire could erase the host's entropy

Package inventory could say “patched” while effective traffic remained predictable. NAT and port-address-translation devices can rewrite outgoing source ports. CERT/CC warned that such a device could reduce or eliminate the benefit supplied by the resolver; RFC 5452 said devices that serialize or sharply limit ports could dramatically reduce randomization.

Neither source says every NAT is harmful. A translator can preserve, reduce or in some cases add apparent variation. The operational point is that security belongs to the complete path, not the package label. The value an attacker must guess is the value visible after host selection, firewall policy and translation.

DNS-OARC turned that principle into an observable test. Its port and transaction-ID services answered special DNS queries with a view of the values received at the authoritative side. Operators could inspect the distribution their resolver actually emitted rather than infer it from a version number.

That is Running-Code Primacy in concrete form. A bulletin can identify affected releases. A package manager can report an installed update. Only running traffic can show whether the acceptance entropy survived the local system surrounding the resolver.

A multivendor release was coordination, not command

DNS-OARC records a private summit at Microsoft's offices on 31 March 2008. CERT/CC published VU#800113 on 8 July alongside patches from many vendors. ISC shipped BIND updates; Microsoft changed transaction-ID generation, UDP socket choice and cache logic; other suppliers issued their own fixes.

The secrecy window did not last until the planned public explanation. DNS-OARC's timeline records an effective leak on 21 July, working exploit code on 23 July and further implementations on 24 July. Microsoft's 25 July advisory said the threat had increased because the mechanism and code were public. It also said Microsoft was not then aware of active attacks or customer impact and that the published exploit it tested did not affect systems with MS08-037 installed.

Those statements must remain separate. Public exploit code increased capability. Absence of known attacks inside Microsoft's observation was not proof of global non-use. A tested patch blocking a published exploit was evidence about that implementation and test, not a certificate for every resolver and middlebox combination.

Kaminsky presented the full issue at Black Hat on 7 August. RFC 5452 arrived in January 2009. The chronology matters: deployed patches supplied an emergency compatibility-preserving defense before the standards-track document recorded the common matching and unpredictability rules. The document consolidated the lesson; it did not retroactively cause the July code to run.

Entropy makes a lie expensive; it does not make an answer authentic

Source-port randomization decreased the probability that an off-path forged packet would pass the resolver's filters. It did not prove that accepted unsigned data came from the delegated zone owner. Enough guesses, leaked state, a weakened middlebox or a different vantage could still change the odds. An on-path attacker faces a different problem because it can observe the query.

ISC therefore called DNSSEC the definitive solution, while also acknowledging that immediate deployment was unrealistic. DNSSEC lets a validating resolver test data origin and integrity through signatures and a chain of trust. That is a different security property from making an unsigned race harder to win.

The two controls are complements. RFC 5452 notes that cryptographically secured DNS still benefits from rejecting bogus packets cheaply before expensive validation. Port and ID entropy protect the transport-facing acceptance gate. DNSSEC decides whether the data carries authorized proof. Each layer has a job, and neither should claim the authority of the other.

Heng Lu's Minimum Initial Specification helps draw the boundary. The common layer should require exact response matching and preserve the invariant that unrelated packets cannot enter an outstanding transaction. It need not dictate one vendor's random-number generator, socket allocator, cache scheduler or deployment calendar. Those choices remain local, judged by the behavior they produce.

Voluntary adoption does not mean passive security. An operator may refuse a particular implementation, but counterparties and customers may refuse to rely on a resolver whose observable entropy or validation behavior is inadequate. Publication creates information; deployment creates a compatibility and risk decision. The running system, not the ceremony, reveals which protection exists.

Evidence limits

The record supports a large multivendor exposure and a materially more practical attack. It does not establish that every resolver shared one defect, that every operator patched on 8 July, or that one calculated attack time describes all networks. Source-port randomization made off-path poisoning much harder under stated assumptions; it did not eliminate every poisoning route. DNSSEC offered authentication, but its specification did not prove immediate validation in deployed resolvers.

The precise lesson is stronger than catastrophe language. DNS trust had been resting partly on a small race whose uncertainty many systems accidentally collapsed. The repair made that uncertainty explicit, enlarged it locally, exposed it to measurement and left cryptographic proof as a separate unfinished deployment task.

Sources