A regional hospitality chain cut outbound IPv4 to a phishing staging host after weekend scans hit its booking portal. Containment looked clean on the edge firewall. Twelve hours later, the same workstation still pulled tasking over a 6to4 tunnel that no security group, proxy, or SIEM rule had ever named. The IPv4 deny stood. The stack nobody owned kept working.
That pattern shows up wherever teams harden IPv4 first and treat IPv6 as a future project. Automatic tunnels, SLAAC leftovers, and default :: listeners turn “IPv4-only” networks into dual-path environments attackers already use. Recent reporting on cross-environment pivots inside modern SOCs, and on campaigns such as 0ktapus leaving live sessions after password resets, makes the same point from another angle: you contain what you can see. Untracked IPv6 paths are invisible until someone asks for them.
How shadow IPv6 shows up in production
Shadow IPv6 is any IPv6 capability that carries traffic without appearing in the same inventories, ACLs, and playbooks that govern IPv4. It is common on Windows endpoints with Teredo or ISATAP still enabled, on Linux hosts where cloud-init or vendor images enable SLAAC by default, and on switches that forward IPv6 while the firewall team only reviews IPv4 rulebases.
Hospitality and branch networks are frequent examples. Guest Wi-Fi, POS VLANs, and booking apps get IPv4 NAT, content filters, and rate limits. Endpoints still form link-local addresses, sometimes accept Router Advertisements from a misconfigured or rogue device, and sometimes open tunnels toward public relays. Your scrubber may report clean IPv4 transit while a workstation talks past the scrubber on another protocol family.
Signals that inventory is incomplete
- Hosts show AAAA records or Happy Eyeballs preference in browser and OS telemetry while the network diagram lists only RFC1918 ranges.
- Endpoint EDR reports connections to 2002::/16, 2001:0::/32, or other transition prefixes that never appear in firewall change tickets.
- Cloud security groups allow egress to ::/0 “temporarily” on jump boxes that still hold long-lived SSH or RDP trust.
- Packet captures during incident response show Neighbor Solicitation or ICMPv6 Type 2 traffic on segments labeled IPv4-only.
Start containment with an address-family checklist
When an abuse feed or internal alert points at a host, treat IPv6 as a first-class containment surface, not a follow-up. Pair identity and session work with stack coverage. After identity misuse stories such as 0ktapus, teams often reset passwords and revoke IdP sessions while overlooking that the same endpoint still holds an IPv6 neighbor cache entry and an outbound tunnel. Closing the login form without closing the path leaves tasking intact.
- Pull the host’s current IPv4 and IPv6 addresses from EDR, DHCP, and switch CAM/ND tables in one query window.
- Disable or block known transition interfaces (Teredo, ISATAP, 6to4) via GPO, MDM, or host firewall before you call the segment clean.
- Add explicit deny or inspect rules for IPv6 egress that mirror the IPv4 action you already took, including proxy exceptions and jump-host allowlists.
- Re-check listening sockets with ss -lntu6 or equivalent; management agents, databases, and vendor tools often bind :: by default when IPv4 was “secured” with bind-address=127.0.0.1 only.
- Record both families in the ticket timeline so the next analyst does not replay only IPv4 PCAP and declare victory.
Tradeoff: dual-stack containment slows the first fifteen minutes of IR. Caveat: dropping all IPv6 on a dual-stack datacenter VLAN can break DNS64/NAT64 paths and break PMTUD if you also over-filter ICMPv6. Prefer targeted interface and ACL changes over a blanket campus-wide IPv6 kill switch unless you have tested that blast radius.
Bring egress policy to parity without breaking necessary ICMPv6
Many IPv4 egress filters matured over a decade of proxy, DNS sinkhole, and deny-by-default work. IPv6 rulesets often still allow any outbound from trusted VLANs because “nothing uses it.” Attackers prefer that gap. Prefer Happy Eyeballs so the first successful path wins; if IPv6 is open and IPv4 is constrained, C2 follows IPv6.
Practical parity checks during change windows:
- For each IPv4 egress allow that requires proxy or DNS logging, require an IPv6 twin with the same destination intent and the same logging profile.
- Block transition prefixes at the edge unless a documented service needs them. Keep an exception register with owner and expiry.
- Allow the ICMPv6 types required for local operation and Path MTU Discovery (Destination Unreachable, Packet Too Big, Parameter Problem, Echo where policy permits) while rate-limiting and logging the rest. Over-blocking Packet Too Big creates silent black holes that look like application faults.
- On cloud accounts, search security group and NSG rules for ::/0 egress the same way you hunt 0.0.0.0/0. Treat jump hosts and CI runners as high priority.
Caveat: perfect ACL parity is rare on day one. Prioritize internet-facing VLANs, admin jump paths, and endpoints that handle credentials. Leave lab or OT islands for a scheduled second pass with owners present.
Detection that survives dual-path sessions
Temporary privacy addresses and multiple GUAs already complicate session stitching. Shadow tunnels make it worse: one user session can appear as an IPv4 proxy hit and an IPv6 direct connect minutes apart. Build correlations that join identity (user, device, certificate) to both address families before volume alerts dominate the queue.
Useful hunting seeds for SOC playbooks that already cover cross-environment pivots:
- Endpoint process that opens both an IPv4 connection to a known bad host and any IPv6 flow within a short window after an IdP or VPN alert.
- Sudden appearance of Teredo or ISATAP adapter counters on assets that never showed them in the last baseline week.
- DNS answers returning AAAA for internal admin hostnames when your design claims IPv4-only management.
- Edge denies on IPv4 paired with allows on IPv6 to the same ASN or certificate subject within the pre-listing contact window you already use for abuse-feed hunts.
Implementation detail: store canonical endpoint ID and authentication session ID on every flow record. IP alone will keep splitting the story across pipelines. When AI-assisted malware analysis or prose-based covert channels distract tooling, stack visibility still depends on whether your collectors ingest IPv6 headers and extension metadata at all.
Hardening defaults that shrink the surprise surface
Prevention beats mid-incident discovery. Pick controls that match how your fleet actually boots.
- Disable unused transition technologies on managed endpoints; verify with compliance scans, not only with a golden image checkbox.
- Decide SLAAC versus DHCPv6 deliberately per VLAN. Document which segments should have no GUA at all.
- Make application installs bind explicitly. CI templates that listen on 0.0.0.0 often listen on :: too when the stack is present.
- Include IPv6 in red-team and tabletop scopes. If the purple team only pivots on IPv4, your detection debt stays hidden.
- Align switch, firewall, and cloud owners on one IPv6 ownership map. Unowned means unmonitored.
Tradeoff: disabling IPv6 entirely on endpoints is simple and sometimes correct for locked-down OT. On modern SaaS-heavy campuses it can break Happy Eyeballs performance and force awkward NAT64 designs. Prefer managed, logged IPv6 over denial that operators will quietly reverse.
What to do in the next change cycle
Pick one production VLAN and one cloud account. Inventory every IPv6 address, tunnel interface, and :: listener. Mirror the IPv4 egress denials you trust onto IPv6 with logging. Update the containment runbook so the first IR checklist asks for both families before anyone writes “host isolated.” Re-test after the next identity incident drill: revoke the session, then confirm no residual IPv6 path still answers.
Shadow IPv6 stays dangerous because it looks like absence. Treat discovery as an operational control with an owner and a calendar, and containment will stop assuming the host was IPv4 only when the tunnel was already doing the work.