DNS Relay Exfiltration Assessment Tool by VoidJarr For authorized penetration testing use only.
Tests a corporate DNS resolver for susceptibility to DNS-based data exfiltration / relay abuse using a linear seven-test model (T1–T7):
- T1 — External relay viability (UDP + TCP)
- T2 — Record type coverage (UDP full set; TCP limited to A+TXT)
- T3 — Label length tolerance + qname minimization advisory
- T4 — High-entropy / IDS pattern tolerance
- T5 — Response payload capacity (TXT + EDNS probes, truncation, TCP fallback)
- T6 — Rate limiting (30-query burst + optional ~90-query sustained at ~1 QPS)
- T7 — Direct egress bypass (UDP/53, TCP/53, DoH, best-effort DoT)
Results include per-transport details, explicit OOB verification labels for heuristic tests, and actionable remediation. TCP is on by default with nested transport.udp / transport.tcp results. Use --udp-only for quieter runs.
This tool must only be used against systems you own or have explicit written authorization to test. Unauthorized use against third-party infrastructure may constitute a criminal offense under applicable cybercrime legislation.
- Python 3.6+
dig(part ofdnsutils/bind-utils)- An OOB domain you control with an authoritative nameserver (your attack box) — required for T3/T4 confirmation
# Debian / Kali
sudo apt install dnsutils
# RHEL / CentOS / Fedora
sudo dnf install bind-utilsNo Python dependencies beyond the standard library.
# Clone / copy the script
chmod +x bounce53.py
# Minimum required arguments
python3 bounce53.py -r 10.0.0.53 -d oob.foobar.com
# Full example with custom output and timeout
python3 bounce53.py -r 10.0.0.53 -d oob.foobar.com \
-o /tmp/client-dns-report -f json \
--timeout 8
# Quiet mode (lower footprint — skips T4 entropy, T7 bypass, and T6 rate-limit burst)
python3 bounce53.py -r 10.0.0.53 -d oob.foobar.com \
--skip-ratelimit --skip-entropy --skip-bypass
# TCP is on by default for T1–T6 and T5 (response). Use --udp-only for reduced noise / query volume.
python3 bounce53.py -r 10.0.0.53 -d oob.foobar.com --udp-only
# Opt-in sustained low-and-slow rate test (after burst)
python3 bounce53.py -r 10.0.0.53 -d oob.foobar.com --stealth-rate
# Pipe-safe output (no ANSI codes)
python3 bounce53.py -r 10.0.0.53 -d oob.foobar.com --no-color > output.txtFor T3 (label length) and T4 (entropy) results to be conclusive, watch your authoritative nameserver for incoming queries:
# On your OOB NS / attack server
sudo tcpdump -i any -n port 53
# Or via BIND query log
tail -f /var/log/named/queries.logA query arriving at your NS confirms the label passed through the corporate relay — even if the resolver returns NXDOMAIN locally.
| Flag | Required | Default | Description |
|---|---|---|---|
-r, --resolver |
✅ Yes | — | Target corporate DNS resolver IP |
-d, --oob-domain |
✅ Yes | — | OOB domain you control (NS must point to your server) |
-o, --output |
No | bounce53_report |
Base name for output file(s) (no extension) |
-f, --format |
No | txt |
Comma-separated output formats (txt, json). Default txt only. |
--timeout |
No | 5 |
Per-query timeout in seconds |
--skip-ratelimit |
No | off | Skip T6 — omits 30-query concurrent burst, reduces footprint |
--skip-entropy |
No | off | Skip T4 — avoids sending high-entropy encoded subdomains |
--skip-bypass |
No | off | Skip T7 — avoids direct egress probes to 8.8.8.8/1.1.1.1/9.9.9.9 and DoH/DoT |
--no-color |
No | off | Disable ANSI color output (safe for piping and logging) |
--no-raw |
No | off | Omit raw dig command/output details from the JSON report (smaller files) |
--udp-only |
No | off | Disable TCP sub-probes (T1–T6 + T5 response capacity). TCP is on by default with nested transport.udp / transport.tcp results. |
--stealth-rate |
No | off | Enable T6 sustained phase (~90 queries at ~1 QPS) after the burst. Opt-in; adds ~90s. |
--skip-doh-dot |
No | off | Skip DoH/DoT sub-checks in T7 (UDP/53 + TCP/53 still run). |
--sleep |
No | 0.5 | Seconds to sleep between tests (default 0.5; use 0 for fast runs). |
TCP is a first-class sub-dimension. By default (unless --udp-only), T1, T2, T3, T4, T5 (response capacity), and T6 run over both UDP and TCP. Results are reported under a nested transport object:
"T1_external_relay": {
"severity": "HIGH",
"finding": "...",
"transport": {
"udp": { "vulnerable": true, "detail": "..." },
"tcp": { "vulnerable": true, "detail": "..." }
}
}Overall test severity takes the worst across the two transports (when both run). --udp-only produces {"skipped": true, "reason": "udp-only"} for the TCP leg and reduces query volume/noise.
T7 (direct egress) always attempts UDP/53 + TCP/53; DoH/DoT are included unless --skip-doh-dot.
T1 — External Relay Viability Tests whether the resolver will forward queries for external names (google.com + t1-relay.). UDP + TCP by default. Severity (if either leg relays): HIGH
T2 — Record Type Coverage Tests A/TXT/MX/CNAME/NS/AAAA over UDP (full set) and A+TXT over TCP. TXT is the highest-risk type for high-bandwidth exfil. Severity (if TXT relays over UDP): HIGH
T3 — Query Payload: Label Length
Tests 30/45/60/63-char labels. Reports max_passing_chars and per_label_results per transport. Includes qname_minimization_risk: "unknown".
OOB verification required (exact long labels are printed for easy log searching).
Severity (60+ "pass"): HIGH (heuristic)
T4 — Query Payload: Entropy / IDS Tests three specific high-entropy patterns + a low-entropy baseline. Baseline failure downgrades severity. OOB verification required (exact pattern labels printed). Severity (0 patterns blocked): HIGH (heuristic)
T5 — Response Payload Capacity
Measures TXT response size from the OOB payload record (or google.com fallback) plus EDNS buffer-size probes (512/1232/4096), truncation detection, and TCP fallback when TC is seen.
Severity: scales on observed TXT length (≥200 = HIGH, ≥50 = MEDIUM).
T6 — Rate Limiting & Sustained Throughput
30-query concurrent burst (UDP + TCP). Optional --stealth-rate adds a ~90-query ~1 QPS sustained phase with success rate and duration stats.
Severity (no limiting on burst): HIGH
T7 — Direct DNS Egress Bypass
Tests direct reachability from the assessment host to public resolvers over UDP/53, TCP/53, DoH (Cloudflare + Google), and best-effort DoT. --skip-doh-dot skips encrypted paths.
Severity (any path reachable): CRITICAL
Strong caveat: results reflect only the machine running the tool. Re-test from representative internal hosts.
By default, only a .txt report is produced from the --output base path (default bounce53_report).
Use -f json (or -f txt,json) to also generate the machine-readable JSON report, which includes findings, transport details, raw_queries (unless --no-raw), limitations_and_caveats, and remediation.
The TXT report uses the same concise, aligned formatting as the live terminal (including OOB Check labels for T3/T4/T6).
Use --no-raw for smaller JSON files when you don't need the full dig traces.
| Rating | Meaning |
|---|---|
CRITICAL |
Direct external DNS bypass open — filtering completely absent |
HIGH |
Relay open, TXT/long labels pass, no rate limiting — full exfil tool suite viable |
MEDIUM |
Partial relay (A-only), soft rate limiting, or partial entropy blocking |
LOW |
Controls present but incomplete — limited residual risk |
NONE |
Test passed / control effective |
Overall severity reflects the single worst finding across all tests.
T3 and T4 rely on resolver RCODE heuristics (NXDOMAIN/NOERROR for non-existent subdomains). These responses are frequently synthesized by RPZ, security products, firewalls, or the resolver itself — they do not prove the query reached the authoritative server.
T7 measures only the assessment host's direct egress. Compromised internal hosts almost always face stricter controls.
Always cross the raw_queries (or the explicit OOB check labels printed for T3/T4/T6) against real OOB/authoritative logs for ground truth. The tool surfaces the exact names/patterns you should search for.
These points (and more) are included in every generated report under the LIMITATIONS & CAVEATS section.
| Technique | ID | Tactic |
|---|---|---|
| Application Layer Protocol: DNS | T1071.004 | Command and Control |
| Exfiltration Over Alternative Protocol | T1048.003 | Exfiltration |
./bounce53.py -r 192.168.91.1 -d uid.oastify.com
▗▖ ▄▄▄ █ ▐▌▄▄▄▄ ▗▞▀▘▗▞▀▚▖▄▄▄▄ ▄▄▄▄
▐▌ █ █ ▀▄▄▞▘█ █ ▝▚▄▖▐▛▀▀▘█ █
▐▛▀▚▖▀▄▄▄▀ █ █ ▝▚▄▄▖▀▀▀█ ▀▀▀█
▐▙▄▞▘ ▄▄▄█ ▄▄▄█
by VoidJarr
[INFO] Target: 192.168.91.1 | OOB: uid.oastify.com | Timeout: 5s | Output: bounce53_report | TCP: enabled
[INFO] Capture OOB traffic or check dashboard.
T1 — External Relay Viability
[PASS] UDP google.com + t1-relay.uid.oastify.com → answer(s) received
[PASS] TCP google.com + t1-relay.uid.oastify.com → answer(s) received
T2 — Record Type Coverage
[PASS] UDP relayed: A, TXT, MX, CNAME, NS, AAAA
[PASS] TCP (A+TXT only) relayed: A, TXT
T3 — Query Payload: Label Length
[PASS] UDP 30-char label (baseline) → resolver returned NXDOMAIN/NOERROR (heuristic)
[PASS] UDP 45-char label (medium exfil chunk) → resolver returned NXDOMAIN/NOERROR (heuristic)
[PASS] UDP 60-char label (typical dnscat2/DNSExfil) → resolver returned NXDOMAIN/NOERROR (heuristic)
[PASS] UDP 63-char label (DNS spec maximum) → resolver returned NXDOMAIN/NOERROR (heuristic)
[INFO] UDP max passing chars: 63
[PASS] TCP max passing chars: 63
[INFO] OOB check: 60-char: ifaucqkbifaucqkbifaucqkbifaucqkbifaucqkbifaucqkbifaucqkbifau.uid.oastify.com
63-char: ifaucqkbifaucqkbifaucqkbifaucqkbifaucqkbifaucqkbifaucqkbifaucqk.uid.oastify.com
T4 — Query Payload: Entropy / IDS
[INFO] UDP baseline reached: True
[PASS] UDP base32 encoded (repeating pattern, 40 chars) → reached auth NS
[PASS] UDP base32 encoded (random bytes, max entropy, 40 chars) → reached auth NS
[PASS] UDP hex encoded (32-char hex string) → reached auth NS
[INFO] UDP patterns blocked: 0/3
[INFO] TCP baseline reached: True
[PASS] TCP base32 encoded (repeating pattern, 40 chars) → reached auth NS
[PASS] TCP base32 encoded (random bytes, max entropy, 40 chars) → reached auth NS
[PASS] TCP hex encoded (32-char hex string) → reached auth NS
[INFO] TCP patterns blocked: 0/3
[INFO] OOB check: ifaucqkbifaucqkbifaucqkbifaucqkbifaucqkb-t4b32rep.uid.oastify.com
ja4ffihnng3vqyzjhrh4gwlodbze2tveng5klhjb-t4b32rnd.uid.oastify.com
4f3a9c2b7e1d6f8a0b5c9d3e7f2a4b6c-t4hex.uid.oastify.com
T5 — Response Payload Capacity
[PASS] UDP TXT payload → 66 chars via t5-payload.uid.oastify.com
[PASS] TCP TXT payload → 66 chars via t5-payload.uid.oastify.com
T6 — Rate Limiting & Sustained Throughput
[INFO] UDP burst: 30/30 @ 26.9 QPS (1.1s)
[INFO] TCP burst: 30/30 @ 32.3 QPS (0.9s)
[WARN] No rate limiting detected — 30/30 resolved at 26.9 QPS (UDP burst)
[INFO] OOB check: *.t6-ratelimit.uid.oastify.com
T7 — Direct DNS Egress Bypass
[PASS] UDP/53: ['8.8.8.8', '1.1.1.1', '9.9.9.9']
[PASS] TCP/53: ['8.8.8.8', '1.1.1.1', '9.9.9.9']
[PASS] DoH: ['cloudflare', 'google']
[PASS] DoT: ['8.8.8.8']
══════════════════════════════════════════════════════════════
ASSESSMENT SUMMARY
══════════════════════════════════════════════════════════════
Target Resolver : 192.168.91.1
OOB Domain : uid.oastify.com
Duration : 11.4s
Overall Risk : CRITICAL
Note : verify T3/T4/T6 via OOB; T7 reflects this host only.
Test Severity Finding
───────────────────────────────────────────────────────────────────────────────
T1 — External Relay Viability HIGH Resolver relays external DNS queries
T2 — Record Type Coverage HIGH TXT relay open — high-bandwidth covert channel viable (dnscat2, DNSExfiltrator)
T3 — Query Payload: Label Length HIGH Resolver returns NXDOMAIN/NOERROR for labels up to 63 chars
T4 — Query Payload: Entropy / IDS HIGH No SERVFAIL/drops for tested patterns
T5 — Response Payload Capacity MEDIUM Moderate TXT payload relayed (66 chars) — chunked exfil viable
T6 — Rate Limiting & Sustained Throughput HIGH No rate limiting detected — 30/30 resolved at 26.9 QPS (UDP burst)
T7 — Direct DNS Egress Bypass CRITICAL Direct DNS egress available — filtering absent or incomplete
[INFO] Report saved → bounce53_report.txt (raw queries: 108)
[INFO] Global OOB search terms: see per-T OOB Check sections above (T3/T4: full long labels; T6: *.t6-ratelimit.* and *.t6-sustained.*)
This project is licensed under the MIT License.
Copyright (c) VoidJarr
Released for authorized offensive security research and penetration testing. No warranty is provided. The author assumes no liability for misuse.