Cisco Dynamic Trunk Protocol Hacking with Scapy

A port on a Cisco switch is either an access port or a trunk port. Access ports belong to a single VLAN and do not provide any identifying marks on the frames that are passed between switches. Access ports also carry traffic that comes from only the VLAN assigned to the port.

A trunk port is required to carry traffic for all VLANs between the switches. To distinguish between the traffic from different VLANs, a trunk port must mark the frames with special tags as they pass between the switches. Trunking is a function that must be enabled on both sides of a link. If two switches are connected together, for example, both switch ports must be configured for trunking, and they must both be configured with the same tagging mechanism (ISL or 802.1Q).

The Dynamic Trunking Protocol (DTP) is a proprietary networking protocol developed by Cisco Systems for the purpose of negotiating trunking on a link between two VLAN-aware switches, and for negotiating the type of trunking encapsulation to be used. It works on Layer 2 of the OSI model.

The goal of the tutorial is to perform a VLAN hopping attack by negotiating a trunk between a Cisco switch and a Kali machine with Scapy installed.

Figure 1 - Network Topology

The network topology consists of two Cisco switches and end hosts. VLANs 10 (Accounting) and 999 (Parking) are created on both switches.

PC1 and PC2 switchports (Gi0/1) are assigned to VLAN 10 (Figure 2).

interface GigabitEthernet0/1
 switchport access vlan 10

The operational mode of both Gi0/1 interfaces is static access, so untagged traffic received from connected end hosts belongs to VLAN 10 (Figure 2). Tagged traffic is discarded.

Figure 2 - S2 Switchport Gi0/1

However, DTP could successfully negotiate a trunk on Gi0/1 if the neighbor port was set to Dynamic desirable, because the administrative mode is set to Dynamic auto and trunk negotiation is enabled. The following example summarizes the result of trunk negotiation based on the port configuration on both sides of the link.

Dynamic desirable <-> Dynamic desirable = Trunk
Dynamic desirable <-> Dynamic auto = Trunk
Dynamic auto <-> Dynamic auto = Static access
Static access <-> (Static access or Dynamic Desirable or Dynamic Auto) = Static access

Interfaces Gi0/0 on both switches are configured as a permanent trunk port with only VLAN 10 allowed. The interface Gi0/0 becomes a trunk interface even if he neighboring interface is not a trunk interface.

interface GigabitEthernet0/0
 switchport trunk allowed vlan 10
 switchport trunk encapsulation dot1q
 switchport mode trunk

VLAN 999 is a Parking vlan; all unused interfaces should be swiched off and placed in parking vlan.

interface GigabitEthernet0/2
 switchport access vlan 999

The Gi0/2 switchport administrative mode is also Dynamic Auto (Figure 3). DTP is sent from the Gi0/2 interface to Kali Linux, so an attacker can use DTP to negotiate a remote connection. The attacker can gain network access to all allowed VLANs on the trunk; in our case, access to PC1 and PC2.

Figure 3 - S2 Switchport Gi0/2

Using Scapy, we will manipulate a received DTP packet to demonstrate trunk negotiation when the switch port is set to dynamic auto mode (or worse, dynamic requested mode).

Start pyhon console using the command  sudo python3 and import scapy module:

$ sudo python3

>>> from scapy.all import *

Load Scapy contrib DTP module to make variables, objects and functions available globally. If the DTP module were not loaded, the DTP layer could not be parsed.

>>> load_contrib("dtp")

Capture one frame sent from the Cisco S2 Gi0/2 to well known multicast MAC address.

>> pkt = sniff(iface="eth0", count=1, filter="ether dst 01:00:0c:cc:cc:cc")

Thepk is a Scapy list, which in our case contains only one captured packet. To view the contents of the first element of the pkt list, enter the command:

>>> pkt[0].show()

Figure 4 - Content of Captured DTP Packet

As the next step, we modify the values highlighted in red in pkt[0]. After making all the changes, we send the modified packet back to the Cisco switch to negotiate the trunk.

Change the source MAC in pkt[]0] element to match the MAC address of the eth0 (Kali) interface.

>>> pkt[0].src = "0c:c0:1e:ee:00:00"

Change the MAC address of the neighbor to match the MAC address of the eth0 interface.

>>> pkt[0][DTP][DTPNeighbor].neighbor = "0c:c0:1e:ee:00:00"

Let's change the "status" variable in the "DTP status" sublayer. The value \x04 means that the switchport mode dynamic auto command is configured on the gi0/2 interface of switch S2. We need to change it to \0x03 - dynamic desirable mode, so that the operating mode will be trunk even if the Cisco switch is in dynamic auto mode.

>>> pkt[0][DTP][DTPStatus].status = '\x03'

The last variable that we need to modify before we send he packet back to S2 is dtptype in he DTP Type sublayer. The ASCII char @ is 0x40 in hex. The value 0x40 (or @ in ASCII) in DTPType of the captured packet is 0100 0000 in binary which corresponds to Trunk

The last variable we need to modify before sending the packet back to S2 is the "dtptype" in the "DTP Type" sublayer. The ASCII character @ is 0x40 in hexadecimal. The value 0x40 (or @ in ASCII) in the DTPType of the captured packet is 0100 0000 in binary, which corresponds to the Trunk operating type: ISL and Trunk Administrative Type: Negotiated (Figure 5).

Figure 5 - Trunk Type Field DTP Packet Sent from S2 to Kali

We need to change ASCII char @ to E for DTPType variable which corresponds to hex value 0x45 or binary 0100 0101 (Figure 6). In such case, the trunk Operating mode is ISL and Trunk Administrative Type: 802.1Q.

Figure 6 - DTP Sent from Kali to S2 with Trunk Administrative Type 802.1Q

>>> pkt[0][DTP][DTPType].dtptype = 'E'

The resulting DTP packet that we send from Kali to S2 is shown in Figure 7.

Figure 7 - Resulting DTP Packet with Modified Variables Highlighted in Red

As the last step, we will continue sending our modified DTP packet to S2.

>>> while True:
    time.sleep(20)
    sendp(pkt[0], iface="eth0", verbose=1)

After a while, a trunk is negotiated on the Gi0/2 interface of S2.

Figure 8 - S2 Switchport Gi0/2 Negotiated as 802.1q Trunk

Configure Kali to Tag Ethernet Frames with VLAN ID 10

Configure Kali to tag Ethernet frames with VLAN ID 10 and assign an IP address 192.168.10.50/24 to eth0 interface

$ sudo vconfig add eth0 10
$ sudo ifconfig eth0.10 10 up
$ sudo ifconfig eth0.10 192.168.10.50 netmask 255.255.255.0

In order to test VLAN hopping, ping the PC1 (VLAN10) from Kali.

Figure 9 - Ping Successful Between Kali and PC1

Countermeasures

Using the "Switchport mode access" command, the port becomes an access port and each device connected to that port will only be able to communicate with other devices that are in the same VLAN.

S2(config)# interface range gigabitEthernet 0/1 - 3
S2(config-if-range)# switchport mode access

Notice, the Administrative mode of S2 is now changed to static access (Figure 10).

Figure 10 - S2 Gi0/2 is Access Port

The switchport Gi0/2 is now forced to become an access port.

Python script

Python script dtp_attack.py automates the sending of a malicious DTP packets. The argument to the script is the MAC address of the Kali Linux OS interface. Change the interface name in the script accordingly.

$ sudo python3 ./dtp_attacl.py 0c:c0:1e:ee:00:00

End.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.