Network services, DNS, TLS, email, and appliances
This is a separate campaign branch: discovering a network service through a website does not automatically authorize testing it. Commands are documentation-verified examples; none were executed against targets. The budgets, sequence, and evidence thresholds below are operational recommendations.
Investigation modules#
Use these procedures with this playbook's setup and scope. Each contains the full testing sequence, command cheat sheet, interpretation, and checklist; open its canonical page for cross-target references.
Proxy normalization, cache isolation, and request boundariesInvestigate layered HTTP behavior with isolated cache keys and controlled front-end/back-end traffic.
Open canonical module and reverse references
- 01Map HTTP processing layers
- 02Prove isolation
- 03Establish normal cache behavior
- 04Change one interpretation input
- 05Verify second controlled client
- 06Purge and document
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Setup and invariant
Use a local proxy plus application, or a program-provided isolated cache namespace and upstream pool. Record protocol on each hop, request normalization, cache key, cache policy, authentication placement, and whether connections are reused. The invariant is: all layers agree on the request target, request boundary, and which client may receive a cached representation. These tests can affect requests other than your own; an unproven random query parameter is not isolation.
Numbered test procedure
- Map the layers. From configuration or operator-provided logs, identify browser → CDN/proxy → application. Capture an ordinary controlled URL from two independent clients. Record
Age, cache-status headers where present,Vary,Cache-Control, effective host/path, and origin logs. A header name or latency difference alone does not establish caching. - Prove the test namespace. Configure a dedicated local path or verified cache-key component. Request two distinct canary paths and confirm they remain separate through origin and cache logs. A query string may be ignored, normalized, or partially keyed. If separation cannot be established in a shared environment, keep mutation experiments in the replica.
- Test cache poisoning. On a fresh isolated key, vary one input that changes origin output but may not be in the cache key, such as an observed forwarding header used in a generated absolute link. Use a harmless marker host under your control. Make a second request without that input and inspect whether the marker persists. Confirm a control key remains clean. The evidence must show an altered representation served from shared cache to the second controlled client. Cache poisoning.
- Test cache deception. Create a private page containing A's unique synthetic marker. In the lab, compare the canonical path with one suffix/path-normalization variant that the origin resolves to the same page but the cache may treat as static. Request that variant as A, then as anonymous B. Verify B receives A's marker because of caching; compare B's direct origin response or a fresh key. Sharing via an intentionally public capability URL is not deception. Cache deception.
- Test parsing agreement in isolation. Capture the bytes seen by front end and backend for a normal request. In the lab, create one malformed framing case and observe whether both components reject it consistently. For ambiguous length/framing, verify how many requests each layer parsed and where the second controlled request begins. Do not treat a timeout as proof, or use unrelated users' responses to demonstrate desynchronization. HTTP/1.1 framing and HTTP/2-to-HTTP/1 translation must be assessed separately. HTTP/1.1 framing, Request smuggling.
- Verify consequence and clean up. Save origin/cache logs, exact requests, normalized targets, cache keys, and client identities. Purge only the dedicated test namespace or restart the disposable cache. Report whether the outcome is poisoned content, private response disclosure, authorization normalization bypass, or request-boundary disagreement; those are distinct findings.
Command card
These ordinary requests establish a local cache baseline. Configure /bb-cache/case-01 and /bb-cache/case-02 as separate keys in your own proxy first. A later poisoning probe must vary only a specific source-identified input.
mkdir -p evidence/cache
curl -q --noproxy '*' --max-time 10 -D evidence/cache/first.h \
-o evidence/cache/first.txt http://127.0.0.1:8080/bb-cache/case-01
curl -q --noproxy '*' --max-time 10 -D evidence/cache/second.h \
-o evidence/cache/second.txt http://127.0.0.1:8080/bb-cache/case-01
curl -q --noproxy '*' --max-time 10 -D evidence/cache/control.h \
-o evidence/cache/control.txt http://127.0.0.1:8080/bb-cache/case-02
Report threshold and checklist
Report a controlled second-client effect or demonstrated parser disagreement with a meaningful security boundary. Mere caching, unexpected 400/502 responses, reflected Host values, and differences caused by the testing proxy are common false positives.
- Cache namespace and upstream isolation verified.
- Every HTTP hop and protocol recorded.
- Normal, mutated, second-client, and clean-key controls saved.
- No production response-queue capture or broad desync probing.
- Test cache entries purged after evidence collection.
Local curl examples bypass environment proxies with --noproxy '*'; -q alone only suppresses curl configuration files. These snippets target loopback and do not follow redirects. curl manual.
Cache semantics and revocation control
Interpret response directives precisely: unqualified no-cache permits storage but requires validation before reuse; no-store prohibits storage/reuse subject to the specification's defined exceptions; unqualified private prevents shared-cache storage but permits private-cache storage. Set-Cookie alone does not disable caching. Requests containing Authorization have special shared-cache restrictions, with explicit exceptions such as public and s-maxage; cookie-authenticated requests need their own correct response policy and cache partitioning. Read the effective configuration and observe behavior. RFC 9111, sections 3.5, 5.2 and 7.3.
In an isolated namespace, compare A, anonymous B, and a fresh control key after A changes or deletes the private marker. Also exercise one normal conditional request if the application uses validators. Inspect which identity the origin checked and which stored body the cache reused after a 304. Do not infer privacy from an Age: 0, absent cache header, or an initial miss. Report stale post-revocation access against the product's promised lifecycle, distinguishing a previously downloaded copy from a newly served shared response.
- Storage, revalidation and private/shared-cache behavior distinguished.
- Fresh, cached and post-change responses compared where applicable.
Libraries and parsers: bounded fuzzing to a minimal reproducerBuild a realistic local harness, instrument the target, bound fuzzing resources, and turn unique faults into defensible library or consumer reports.
Open canonical module and reverse references
- 01Choose contract
- 02Build harness
- 03Instrument target
- 04Fuzz within bounds
- 05Minimize root cause
- 06Verify consumer impact
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Choose an attacker-relevant parser contract#
Select a public API and a realistic input boundary: imported image, archive, document, packet, model file, project metadata, or CLI input file. Record who supplies bytes, the consumer's preprocessing, format limits, parser options, and the privilege of the process. Fuzzing an internal helper with impossible arguments may reveal a harness defect rather than a violated library contract.
Keep the first harness narrow: one parse operation, deterministic configuration, fresh state for each input, bounded allocations, and cleanup on both success and failure. Remove network and uncontrolled filesystem side effects. Seed with a few valid, small representative samples to reach deeper code; an all-random corpus may spend every iteration failing the magic-header check.
Harness and build cheat sheet#
The following is a template: product_parser.h, ProductDocument, and the parser functions are placeholders to replace with the target's documented API. Return/error ownership must follow that API. The commands have not been executed here.
#include <cstddef>
#include <cstdint>
#include "product_parser.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) {
if (size > 65536) return 0;
ProductDocument* doc = product_parse(data, size);
if (doc != nullptr) product_document_free(doc);
return 0;
}
Build the target library itself with compatible sanitizer and coverage instrumentation; instrumenting only the harness misses much of the parser's behavior. Replace the source list with its reviewed build recipe. The example assumes Clang and a compatible C++ project. AddressSanitizer build guidance.
clang++ -g -O1 -fno-omit-frame-pointer \
-fsanitize=fuzzer,address,undefined -fno-sanitize-recover=undefined \
./fuzz_parser.cc ./parser.cc -o ./fuzz_parser
mkdir -p ./corpus ./artifacts ./evidence
./fuzz_parser ./corpus -max_total_time=120 -timeout=2 \
-rss_limit_mb=512 -max_len=65536 -artifact_prefix=./artifacts/
Add reviewed seed files before running. libFuzzer's time, input-length, timeout, and RSS settings bound the campaign; they are not a VM resource boundary. Run inside your local disposable environment with external memory/CPU limits appropriate for the workload. Track new coverage and distinct root causes rather than raw executions. libFuzzer reference.
Interpret the failure precisely#
| Observation | Immediate question | Defensible first claim |
|---|---|---|
| ASan heap read overflow | Does the public API permit this byte sequence? | Out-of-bounds read in the tested build |
| ASan write overflow | Which length check and allocation disagree? | Out-of-bounds write; execution impact unproven |
| Use-after-free | Did the harness violate ownership rules? | Lifetime defect if public usage is valid |
| UBSan arithmetic finding | Does overflow reach an unsafe allocation/index? | Undefined operation plus traced consequence |
| Timeout or RSS limit | Is it reproducible at modest input sizes? | Bounded evidence of resource exhaustion |
-fno-sanitize-recover=undefined makes the selected UBSan failures terminate instead of allowing a fuzzing run to continue after a diagnostic, which helps preserve reproducible failing inputs. UBSan checks selected undefined behaviors, not every arithmetic error. Unsigned integer wrap is defined in C/C++ and is not part of the default undefined group; choose additional checks when the target's threat model requires them. UndefinedBehaviorSanitizer.
Minimize and verify the consumer#
Copy one candidate into ./artifacts/repro.bin, then minimize with a unique output path. Preserve the original input, toolchain, build flags, revision, and symbolized trace.
./fuzz_parser -timeout=2 -rss_limit_mb=512 ./artifacts/repro.bin
./fuzz_parser -minimize_crash=1 -max_total_time=60 -timeout=2 -rss_limit_mb=512 \
-exact_artifact_path=./artifacts/minimized.bin ./artifacts/repro.bin
Replay the minimized bytes through a supported consumer in the pinned OSS lab. If the consumer rejects them before calling the library, report the library contract separately and leave consumer exposure unproven. A sanitizer crash is not proof of remote code execution, and its absence in an optimized build does not erase a confirmed memory-safety defect.
Hypothetical root cause: a header count is multiplied into a narrow allocation size, then a wider loop trusts the original count. Preserve the values, allocation site, failing access, and missing bound. The fix should bind accepted count to available input and checked allocation size; merely suppressing the crash is insufficient.
- Public API and ownership contract respected.
- Target code, not only harness, instrumented.
- Resources, seeds, revision, and toolchain recorded.
- Minimal input reproduces the same root cause.
- Normal input succeeds in affected and fixed builds.
- Library impact and real consumer exposure are stated separately.
Replay timeout and memory artifacts under the same resource limits as discovery. A minimized crash must retain the original root cause; a shorter input that fails differently is not equivalent evidence.
DNS, TLS and email trust boundariesSeparate dangling records, transfer/recursion exposure, TLS identity and SMTP relay into controlled protocol tests.
Open canonical module and reverse references
- 01Pin owned services and trust promise
- 02Collect exact protocol baseline
- 03Run one paired control
- 04Correlate protocol and receiver evidence
- 05Remove synthetic mail and fixtures
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Setup and invariant#
Treat DNS, TLS and SMTP as separate services with explicit owners, addresses, ports and test methods. Use an owned miniature zone, known certificate hostname and researcher-controlled mail sender and receiver. A service must enforce the claimed ownership, peer identity or relay boundary. Define the expected result before probing: public DNS answers are normally intentional; private zone transfer or unauthenticated external relay may not be.
Procedure#
Inspect DNS ownership without claiming resources. Record the exact CNAME or delegation chain, provider error, TTL and owner-supplied resource inventory. A missing backing resource creates a takeover candidate; it does not prove that another account can bind the hostname. Check provider validation and reservation rules. Do not claim dangling resources as a generic proof step. Azure dangling DNS guidance
Separate transfer and recursion. AXFR requests the zone contents, so test only an owned small zone or an explicitly supplied fixture. Compare the permitted transfer source with the denied source. For recursion, query one unique name in an owned authoritative zone through the tested resolver; correlate the authoritative log with the resolver response. Cached answers and the RA flag alone do not prove unrestricted recursion. AXFR protocol, BIND configuration
Verify TLS identity as the real client. Use the intended hostname, SNI, port and trust store. Compare the valid fixture certificate with an owned wrong-host certificate in a local client integration test. OpenSSL diagnostics confirm the fixture but do not establish that the product's client accepts an invalid identity. Certificate-chain trust and hostname matching both matter. OpenSSL s_client
Test SMTP relay with one synthetic message. Only when message delivery is allowed, use sender and receiver domains controlled by the researcher and outside the tested relay's local destination domains. Start from an untrusted source address with no SMTP authentication. The secure control rejects external-to-external relay; the permitted control uses the documented authenticated submission path. A test from an allowlisted office or VPN address does not prove an open relay.
Correlate SMTP acceptance with delivery. Retain the envelope, transcript, unique subject marker and receiver logs. A successful RCPT response or queue ID alone does not establish final delivery. Keep relay testing separate from SPF, DKIM and DMARC alignment findings. For sender-identity tests, the receiving policy and trusted authentication results determine the demonstrated impact. SMTP protocol
Command card#
Replace all example addresses only with owned fixtures. Run one command at a time. The AXFR example is limited to the small fixture zone; it retrieves that zone.
timeout 10 dig -r @192.0.2.53 fixture.example AXFR \
+tcp +time=2 +tries=1
timeout 15 openssl s_client -connect tls.fixture.example:443 \
-servername tls.fixture.example \
-verify_hostname tls.fixture.example \
-verify_return_error -brief </dev/null
timeout 20 swaks --config --server relay.fixture.example --port 25 \
--timeout 10 --from probe@sender.fixture.example \
--to receiver@recipient.fixture.example \
--header 'Subject: Bounty relay fixture 2026-01' \
--body 'Synthetic authorized relay test; no action required.'
Use a clean shell with no SWAKS_OPT_* overrides; --config disables automatic configuration files, not environment settings. Confirm the transcript contains no AUTH and exactly one intended recipient. The fixture message contains no credentials; this example does not claim transport-security testing. BIND dig, Swaks reference
Result and cleanup checklist#
- Public records distinguished from restricted zone contents.
- Dangling DNS labeled candidate unless claimability is established.
- TLS finding reproduced in the product's actual client.
- Relay test source is outside trusted networks.
- Acceptance, queueing and delivered fixture correlated.
- No real recipients contacted; synthetic mail and temporary zone/certificate fixtures removed.
Database, cache, queue and management service boundariesMove from a reachable socket to a minimal proof of unintended service authority using synthetic records and paired identities.
Open canonical module and reverse references
- 01Record exact endpoint and allowed method
- 02Establish authenticated baseline
- 03Read one forbidden fixture
- 04Compare identity and network controls
- 05Document and remove canaries
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Setup and invariant#
Record one service row: owner, exact IPv4 or IPv6 address, hostname, transport, port, product build, authentication method and intended access boundary. A hostname in web scope does not automatically include every backing service. Prepare a restricted account, an allowed account and one synthetic key, row, queue or management fixture. A network position or low-privilege account must not gain the protected data or administrative operation outside its stated permissions.
Use version banners only to select hypotheses. Vendor backports and disabled features can invalidate a banner-to-CVE match. First establish a normal connection, intended authenticated operation and expected rejection. Keep source network and timestamps constant when comparing identities.
Procedure#
Separate reachability from authority. Record a connection outcome without treating an open port as a vulnerability. Check whether the service is intentionally public, behind mutual TLS or protected by native authentication. A health response is not administrative access.
Use one exact resource. For Redis, request only the agreed canary key; do not run keyspace enumeration, configuration changes or flush commands. Compare anonymous access, the permitted principal and the restricted principal. Redis network protection, authentication, ACLs and TLS solve different parts of this boundary. Redis security
Check connection rules and database grants independently. In PostgreSQL, examine the owner-supplied host-based authentication rule selected by connection type, source, database and user. Establish whether authentication genuinely happened, then test permission for one fixture row. A trusted local administration connection is not evidence of internet exposure. PostgreSQL host authentication
Model queues as stateful resources. In an isolated broker, create two fixture virtual hosts and named queues. Compare whether A can declare, publish to or consume B's fixture according to the contract. Use a single marked message and account for acknowledgement behavior; consuming production messages changes application state. Broker login does not imply permissions across all virtual hosts. RabbitMQ access control
Evaluate management APIs and network parity. For an owned Docker daemon, review listener and client authentication configuration; use only an approved metadata endpoint for the initial proof. Do not create privileged containers to confirm broad authority on production. Compare an explicitly owned IPv4 and IPv6 service only when both are in scope: different exposure is relevant when it defeats the same promised restriction. Docker daemon protection
Command card#
The Redis endpoint below is an isolated local fixture. The environment removal prevents an inherited password from contaminating the unauthenticated control. The database example uses the supplied test account and private password file, with TLS identity verification and a read-only transaction.
env -u REDISCLI_AUTH timeout 10 redis-cli \
-h 127.0.0.1 -p 16379 --raw GET bounty:canary
timeout 15 psql -X -w \
"host=db.fixture.example port=5432 dbname=bounty_fixture user=lab_low sslmode=verify-full sslrootcert=./fixture-ca.pem connect_timeout=5 options='-c statement_timeout=3000'" \
-v ON_ERROR_STOP=1 \
-c "BEGIN READ ONLY; SELECT marker FROM bounty_canary WHERE id=1; ROLLBACK;"
An unauthenticated marker demonstrates read access to that fixture. NOAUTH, NOPERM, connection failure and an absent value mean different things; compare the known-good control. For PostgreSQL, distinguish TLS failure, authentication failure and SQL permission denial. Credentials can come from a password file even with -w; that flag disables prompting, not password authentication. Redis CLI, PostgreSQL connection parameters, psql options
Evidence, false positives and cleanup#
Save the endpoint, source, verified account, precise operation, response, fixture ownership and comparison. Public service banners, intentionally anonymous health checks and intended shared queues are not equivalent to data exposure. Reuse authorization matrices for per-resource checks and identity/session testing for revocation behavior.
- Allowed and denied controls have working connectivity.
- No wildcard reads, real queue consumption or configuration mutation.
- Network access distinguished from authentication and authorization.
- Lab result separated from unverified production applicability.
- Canary records, messages and test accounts removed using their recorded identifiers.
Hardware interfaces: production debug access and protected dataDistinguish diagnostic output from privileged UART, JTAG/SWD and firmware-secret boundary failures on an owned lab unit.
Open canonical module and reverse references
- 01Document access model
- 02Observe baseline
- 03Classify interface
- 04Check protected capability
- 05Confirm production state
At each step: retain the control → record the observation → continue only while the next boundary is understood.
Setup and security invariant#
Record exact retail SKU, board revision, installed firmware, provisioning state and whether the case must be opened. Distinguish unauthenticated nearby access, opened-case access and already privileged administrator access. Use a recoverable owned bench device, its matching documentation and a passive capture first. The invariant is: the documented physical access level does not expose a protected command, memory region or reusable credential without the required authorization.
Use the shared authorization matrix for local service roles and identity/session checks when the device also has app/cloud identities. Network callbacks or downloaded configuration belong in the shared SSRF boundary procedure; permission to inspect a purchased device does not extend to unrelated cloud services.
Controlled procedure#
- Preserve the retail baseline. Photograph configuration and interface locations without unnecessary serial numbers. Record whether secure boot, flash encryption and debug locks are configured, using read-only vendor diagnostics when available. A development board or previously unlocked unit cannot establish behavior on a locked retail device.
- Observe UART without transmitting. Verify pinout, ground and logic voltage before connecting a receive-only capture adapter or logic analyzer. Keep transmit and power pins disconnected for passive observation. Record baud/framing from documentation or the capture, startup stage and visible data. Do not assume that an RS-232 adapter and a TTL UART use compatible electrical levels.
- Classify the capability. Separate boot logs, an authenticated console, an unauthenticated restricted monitor and a privileged shell. A prompt string proves neither interactivity nor privilege. If a console is within the lab scope, use a benign identity query or read a synthetic fixture after documenting why that access should be restricted. Compare logged-out versus correctly authenticated behavior. OWASP's internal-interface tests distinguish exposed functionality and authorization. OWASP internal interfaces
- Assess JTAG/SWD conservatively. Start from documented lock state and allowed read-only diagnostics. Prove a specific protected capability only on a suitable lab unit; avoid unlock, erase, fuse and flash commands. Finding pads or a debug identifier is weaker than reading a protected synthetic memory region. CWE-1191 specifically covers access control for on-chip debug and test interfaces. CWE-1191
- Classify recovered secrets. In offline firmware, distinguish public certificates, password hashes, test credentials, per-device private keys and fleet-wide credentials. Compare two authentic owned-device images if available. Demonstrate a candidate credential's function on a local service, with redacted output; do not try it against vendor infrastructure. Installed-firmware review includes exposed authentication material and configuration. OWASP installed firmware
- Confirm and restore. Reproduce after a supported clean reset if needed and safe for the unit. Record what access survived, what was configured during testing and whether recovery succeeded. State emulation or missing hardware limitations explicitly.
Offline command cheat sheet#
rg -n -i 'login|console|debug|jtag|swd|password|private.key' extracted-rootfs
readelf -hW extracted-rootfs/usr/sbin/example-daemon
readelf -lW extracted-rootfs/usr/sbin/example-daemon
sha256sum evidence/uart-capture.bin
These commands inspect an already extracted filesystem and saved UART capture. Replace the daemon with an identified ELF; readelf is not useful for arbitrary compressed firmware. -h shows the ELF header, -l program headers and -W wide output. GNU readelf
Evidence and completion#
Capture access level, wiring diagram, voltage, tool version, production lifecycle state, before/after decisions and protected capability. A verbose boot log, root access granted to an intended administrator, generic missing hardening, or readable public key is not automatically a vulnerability.
- Retail and debug configurations are distinguished.
- Passive observation precedes any authorized interaction.
- Prompt visibility and protected capability are separate findings.
- Secret classification is supported without exposing usable values.
- No irreversible debug unlock or device write was performed.
Vulnerability reference#
Web cache poisoning · Web cache deception · HTTP request smuggling / desynchronization · Out-of-bounds memory read · Out-of-bounds memory write · Use after free in a public API or parser lifecycle · Integer overflow affecting allocation or bounds · Parser resource exhaustion and decompression amplification · Namespace or workload network restriction is ineffective · Supported deployment default exposes a protected service · Dangling DNS reference to a retired service · Restricted DNS zone transferable from an unintended source · DNS recursion available outside the intended client network · SMTP relay allows unauthenticated external delivery · Redis authentication or key ACL boundary failure · PostgreSQL trust authentication exceeds the approved network boundary · Message broker permissions cross a virtual-host boundary · Container daemon management endpoint lacks required client authentication · TLS peer certificate or hostname verification failure · Firmware contains a reusable shared authentication credential
Stage 1 — define the service boundary#
Create one inventory row per owner → environment → address family → IP → transport → port → service → identity/tenant. Retain the hostname, SNI and HTTP Host when virtual hosting applies. Distinguish a website's public edge from its origin and from the provider's control plane. An IP resolving from an authorized hostname is not automatically a target for every service; a CIDR does not necessarily include unrelated customer workloads inside it.
TCP/443, UDP/443 and a VPN on UDP/500 are separate surfaces. An A record does not authorize IPv6; an AAAA record does not authorize an entire IPv6 prefix. Querying an AAAA record over IPv4 is not an IPv6 connectivity test. Expand only into address families, protocols, ports and ownership categories covered by the policy. Avoid brute-force IPv6 address discovery across huge prefixes.
Gate: save the exact scope entry, exclusions, approved source address, allowed time window, credentials, concurrency/rate budget, and emergency contact. If appliance disruption or parser tests are excluded, move those hypotheses into a local product lab.
Stage 2 — separate inventory from vulnerability confirmation#
Start with public vendor documentation, existing network-index records and historical DNS. Searching previously collected records is passive relative to the target; requesting a new third-party scan is active. DNS queries, TCP connections, UDP packets and TLS negotiations are active even when no login or state change occurs.
For authorized services, establish a normal protocol exchange and identify the product, build, deployment mode and authentication challenge. Keep the network vantage point and timestamps: filtered or open|filtered are observations from that vantage, not proof a service is absent or vulnerable. UDP silence is especially ambiguous. Nmap port states.
Treat banner-to-CVE matches as candidates. Vendor backports can fix vulnerabilities without adopting the upstream version number that a scanner expects. Match vendor advisory, package build, enabled feature and exploit prerequisites; validate behavior safely before claiming vulnerability. A stale banner is not remote code execution. Red Hat backporting.
Stage 3 — bounded command reference#
Replace these documentation addresses only with approved assets. Here 192.0.2.53 is an authorized DNS server and 192.0.2.10 an explicitly approved host. Run commands individually; inspect each result before continuing. No default broad scans, NSE script sets, OS detection, traceroute or version detection are enabled.
# 1. One UDP SOA query to an approved authoritative server.
dig -r @192.0.2.53 example.com SOA \
+norecurse +notcp +ignore +time=2 +tries=1
# 2. One AAAA lookup; still uses IPv4 transport to this DNS server.
dig -r @192.0.2.53 app.example.com AAAA \
+norecurse +notcp +ignore +time=2 +tries=1
# 3. Inspect the domain's published DMARC record.
dig -r @192.0.2.53 _dmarc.example.com TXT \
+norecurse +notcp +ignore +time=2 +tries=1
# 4. TLS handshake with the intended SNI and certificate identity.
timeout 15 openssl s_client -connect app.example.com:443 \
-servername app.example.com -verify_hostname app.example.com \
-verify_return_error -brief </dev/null
# 5. SMTP STARTTLS negotiation only: no AUTH or message delivery.
timeout 15 openssl s_client -starttls smtp \
-connect mail.example.com:587 -servername mail.example.com \
-verify_hostname mail.example.com -verify_return_error \
-brief </dev/null
# 6. Explicitly approved TCP ports on one approved IPv4 address.
nmap -sT -Pn -n --disable-arp-ping -p 22,443 \
--max-rate 1 --scan-delay 1s --max-parallelism 1 \
--max-retries 0 --host-timeout 30s \
-oX network-one.xml 192.0.2.10
dig -r ignores inherited .digrc options; +ignore prevents automatic TCP fallback after a truncated UDP response. A truncated answer is incomplete, so request TCP separately only if allowed. +norecurse suits a known authoritative server; a referral is not a complete answer. Use record types A, CNAME, NS, MX, SPF TXT or a known DKIM selector only as separately reviewed queries. BIND 9.20.13 dig manual.
SNI selects a virtual TLS service; hostname verification checks identity. OpenSSL's STARTTLS option performs the protocol negotiation needed before TLS. A successful handshake does not test authentication or mail delivery. OpenSSL s_client.
Nmap -p overrides its default port set, and -Pn skips ordinary host discovery that could touch additional ports. -n avoids reverse DNS. Scan timing options do not constitute a hard limit on every kernel-generated packet. For separately authorized IPv6 testing, use -6 and the exact approved IPv6 address. Do not append -sV: version detection introduces additional protocol probes and potential side effects. Nmap port selection, host discovery, timing, IPv6, version detection.
Stage 4 — test a concrete hypothesis#
| Hypothesis | Preconditions and minimal action | Evidence / reporting threshold | Stop condition |
|---|---|---|---|
| DNS delegation or CNAME is abandoned | Authorized DNS review; inspect current chain and provider ownership requirements | Record chain, error and claimability evidence; classify unconfirmed takeover honestly | Do not register a domain/resource or replace DNS without the approved proof method |
| Resolver allows unintended recursion | That DNS service and recursion checks are allowed; query one unique name in your own zone | Resolver response plus your authoritative log establishes one recursive lookup; report according to policy impact | No spoofed source, ANY/amplification batches, or load measurement |
| TLS identity/transport boundary fails | Expected hostname and trust model known; one handshake and a controlled client comparison | Explain which actual client accepts the wrong identity or exposes sensitive traffic | No live interception of unrelated users; no exhaustive stress negotiation |
| Database/queue/file service bypasses authentication or ACL | Dedicated test account and synthetic resource supplied | Restricted account accesses a forbidden test key, row, queue, share or administration function | Stop at first proof; no listing/dumping real datasets or consuming production messages |
| IPv6 exposes a management path blocked on IPv4 | Both exact addresses are authorized; compare the same approved service | Same product/service, different access boundary, actual privileged exposure | Do not expand into neighboring addresses or internal routes |
| SMTP relay or sender-identity control fails | Policy allows mail tests; sender, recipient and relevant endpoints controlled | One delivery, envelope/header identity, trusted receiver results and relay transcript | No staff recipients, unsolicited messages, forwarding to customers or bulk delivery |
| Appliance parser crosses a security boundary | Own isolated hardware/VM, exact firmware, snapshots and recovery | Minimized input plus reproducible crash/authorization or memory-safety evidence | Production reproduction requires its own allowed method; never cause an outage to verify a lab result |
For databases, queues, SSH, SMB/NFS, LDAP and management APIs, test authentication and authorization separately. A TCP connection or banner does not grant data access. Prefer one read of a supplied canary over list all, queue consumption or configuration export. Compare limited and privileged test identities; examine revocation and certificate-to-account mapping. Redis documents separate protected mode, authentication, ACL and TLS controls; PostgreSQL's host-based authentication evaluates connection type, address, user and database. Redis security, PostgreSQL authentication.
DNS and email: prove the relevant impact#
DNSSEC provides DNS data authenticity and integrity; it does not encrypt DNS or provide authorization for zone updates. Missing DNSSEC alone does not demonstrate a practical takeover. A broken chain may create availability problems for validating resolvers; record the observed resolution failure without deliberately breaking records. Requesting DNSSEC records with dig +dnssec does not itself perform cryptographic validation. RFC 4033, BIND manual.
SPF evaluates authorized sending hosts for envelope/HELO identities. DKIM verifies a signature associated with a signing domain. DMARC relates authenticated SPF/DKIM identifiers to the visible From domain through alignment; a passing DKIM signature from an unrelated domain is insufficient. Evaluate the actual message path, including forwarding, instead of treating these controls as interchangeable. SPF RFC 7208, DKIM RFC 6376, DMARC RFC 7489.
Missing SPF, a DKIM selector returning NXDOMAIN, DMARC p=none, or an “AUTH offered” banner does not independently prove accepted impersonation or mailbox access. A guessed selector can simply be wrong. Check whether email spoofing is eligible before investing in it. If allowed, send one inert, clearly identified test to a researcher-owned mailbox using the agreed identity; save trusted receiver-generated authentication results, raw headers and timestamps. Delivery to a permissive receiver you control does not prove a protected recipient would accept the mail. Distinguish SMTP acceptance, queueing and actual delivery; 250 during a transaction is not sufficient proof of final delivery or open relay. SMTP RFC 5321.
Router, VPN, and protocol-parser lab branch#
Choose one product family and obtain authorized firmware or a vendor trial. Record hardware revision, firmware hash, enabled modules and initial configuration. Isolate management and simulated clients from your normal network; supply local DNS, identity and callback services. Capture a legitimate protocol conversation first. Map pre-authentication versus authenticated parsers, management versus data plane, and low-privilege versus administrator commands.
Review exposed handlers and parsers, reproduce one hypothesis, minimize the triggering input, then compare vulnerable and fixed builds. Preserve logs, crash trace, exact configuration and a reset procedure. A crash establishes an availability or memory-safety lead; do not claim code execution without evidence. For a private target running the same appliance, report validated applicability and remaining uncertainty; obtain an agreed canary or lab-equivalent verification if production testing would disrupt service. No persistence, firmware replacement or route changes on a live target are needed for a useful report.
Exit checklist#
- Exact IPv4/IPv6, transport, port, owner and environment are authorized.
- Shared hosting, origin, provider and customer boundaries are documented.
- Active requests are separated from historical third-party discovery.
- DNS server, query type and UDP/TCP behavior are explicit.
- Commands have explicit ports, timeouts and bounded concurrency.
- Service identity includes build/configuration and possible vendor backports.
- SNI and expected TLS hostname are recorded.
- Authentication and resource authorization have separate test cases.
- Synthetic data or owner-provided canaries support evidence.
- DNS/mail configuration observations are tied to eligible impact.
- Parser/appliance testing has isolation, recovery and minimized inputs.
- First-proof stopping, cleanup and private reporting are completed.
Extend the canary method to LDAP, file shares and SSH#
These services need protocol-specific boundaries in addition to a working socket. Use the shared network-service module for endpoint identity and allowed/denied controls.
| Surface | Exact controlled comparison | Interpretation |
|---|---|---|
| LDAP | Read one known fixture DN and one synthetic attribute as the intended account and restricted account; keep the bind method, TLS and base scope constant | Successful bind does not grant all directory attributes. A root DSE response or intended anonymous discovery is not private-entry disclosure. OpenLDAP ACLs |
| SMB file shares | Open one owner-supplied share and retrieve one predetermined synthetic file under each identity | Share access, filesystem permissions and authenticated identity must all be understood; a share name or successful negotiation alone is insufficient. Samba client |
| SSH/SFTP | Compare the account's promised restricted subsystem with permitted local fixtures; inspect effective Match rules, forced command and forwarding controls | A forced command does not independently disable forwarding. Authentication success is not proof of a restricted-account escape. Any forwarding check must terminate at an owned canary endpoint. OpenSSH server configuration |
For LDAP, account for referrals and client behavior before following a response into another server. For SMB, save whether guest mapping occurred instead of assuming the requested username was authenticated. For SSH, record whether the promised restriction comes from the server configuration, authorized-key options or a surrounding gateway. Test the actual control layer rather than a deliberately weakened lab substitute.
Keep the proof narrow: one known entry, attribute, file or owned connection. A lab administrator can confirm presence when a low-privilege client returns no result. Preserve object ownership, effective identity, exact operation, allowed control and expected denial. Reuse the same synthetic resource after the proposed fix; remove only the recorded fixture objects and accounts.
Source registry#
All accessed 2026-09-11. Undated means a reliable publication date was not established. RFCs below substantiate protocol mechanics, not a claim that no later updating RFC exists.