{
  "finding_id": "DF-2609",
  "status": "reproduced",
  "reproduced": 1,
  "impact": "leak",
  "confidence": "certain",
  "verdict": "REPRODUCED on the stock INVARIANTS guest: sysctl net.inet6.icmp6.nodeinfo defaults to 3 (in6_proto.c:398, live-confirmed) and a single unauthenticated ICMPv6 NI query (RFC 4620) to any of the host's unicast addresses returns the system hostname (QTYPE FQDN, no-subject oldfqdn path icmp6.c:1182-1186, bit-0 gate icmp6.c:1275) and the complete IPv6 address inventory across all interfaces incl. link-local (QTYPE NODEADDR, ni6_store_addrs icmp6.c:1660-1806). hostname 'dfbsd' and all 4 addresses disclosed; negative control (foreign dst) silent; sysctl=0 silences the responder (live fix matrix 0/1/3). Recon-grade info disclosure, no memory-safety involvement; NI replies carry no uninit/pad bytes (exact lengths).",
  "exploit_chain": "",
  "evidence": "run.log: 'FQDN ttl=0x00000000 name=dfbsd' after a 16-byte query to ::1; 'NODEADDR count=4' listing fe80::5054:ff:fe12:3456/2001:db8::1/::1/fe80::1 exactly matching ifconfig; queries to 2001:db8::1 (global unicast) answered; 2001:db8::99 -> 'NO REPLY (timeout)'; sysctl matrix: nodeinfo=0 -> all queries time out, =1 -> FQDN only, restored 3 -> 5/5 replies. env.txt: 'net.inet6.icmp6.nodeinfo: 3' on uname 'DragonFly dfbsd 6.5-DEVELOPMENT #0 Thu Jul 2 06:02:54 UTC 2026'.",
  "kernel_refs": [
    "sys/netinet6/in6_proto.c:398",
    "sys/netinet6/icmp6.c:632",
    "sys/netinet6/icmp6.c:1142-1159",
    "sys/netinet6/icmp6.c:1182-1186",
    "sys/netinet6/icmp6.c:1275",
    "sys/netinet6/icmp6.c:1279",
    "sys/netinet6/icmp6.c:1660-1806",
    "sys/netinet6/raw_ip6.c:326",
    "sys/netinet6/raw_ip6.c:393-418"
  ],
  "poc_changes": "Standalone raw-socket NI query tool written from scratch (no seed). Two fixes during verification: (1) raw ICMPv6 sockets deliver replies WITHOUT the IPv6 header - parser offset auto-detection added; (2) nodeaddr queries require a 16-byte subject equal to the queried destination because ICMP6_NI_SUBJ_IPV6==0 (icmp6.h:165) - subject added.",
  "attempts": 3,
  "guest_uname": "DragonFly dfbsd 6.5-DEVELOPMENT DragonFly 6.5-DEVELOPMENT #0: Thu Jul  2 06:02:54 UTC 2026  root@dfbsd:/usr/obj/usr/src/sys/X86_64_GENERIC  x86_64",
  "runtime_sec": 120,
  "guest_dirty": 0,
  "build_cmd": "cc -O2 -Wall -o niq niq.c",
  "run_cmd": "sh run.sh   (as root on the DF guest; canonical matrix in run.sh/run.log)",
  "code_hash": "8b07a5b9eb41826e31905959ff38f1cb69a5caef78e7c2374e9b25be3e5b2390",
  "notes": "Query injection needs a raw socket (root) only as a test convenience; the responder itself serves any remotely-routed packet with no auth/capability/scope check - the threat is the remote unauthenticated peer. Guest left clean (vm.sh reset with-src after run; kmem/sysctls were not touched by this PoC).",
  "recommended_fix": "Default icmp6_nodeinfo to 0 in in6_proto.c:398 (match FreeBSD); defense-in-depth: restrict responder to link-local destinations in ni6_input.",
  "fix_status": "fixed",
  "fix_kernel_uname": "",
  "fix_baseline_reproduced": 1,
  "fix_patched_reproduced": 0,
  "fix_verdict": "Operational fix validated live without a kernel rebuild: the fix.diff only changes the compiled-in default of the exact sysctl variable exercised at runtime. Baseline (default 3): hostname + full address inventory disclosed on every query. With net.inet6.icmp6.nodeinfo=0 (the fixed default, set at runtime): 0 replies across all query types (run.log FIX CHECK section). Rebuild of the one-line default flip is trivially equivalent and was not separately booted.",
  "fix_evidence": "run.log: 'sysctl -w net.inet6.icmp6.nodeinfo=0' followed by './niq ::1 fqdn' -> 'NO REPLY (timeout)' and './niq ::1 nodeaddr 002e' -> 'NO REPLY (timeout)'; restored to 3 -> replies return."
}
