Virtualized Lab; Abuse Cisco DTP to hit VLANs
GNS3 and Cisco VIRL IOSv/IOSvL2 images make it easy and cheap.
Travis dropped
Layer 2 attacks are ancient and the enlightened world (all 5 of us, including you) has moved on to assume that transport is broken focusing instead on application layer protections. Still, abusing these old Layer 2 defects can be fun, and occasionally the difference between failure and Access1.
Dynamic Trunking Protocol (DTP) is Cisco’s proprietary Layer 2 switch configuration protocol - DTP is enabled by default on Cisco switches and has been known to allow random endpoints to impersonate switches and access arbitrary VLANs since the late 90’s. Regardless of this, Cisco devices still leave DTP Auto as the default mode - and many networks neglect to turn it off. From a certain point of view it’s a weakness similar to Windows Pass-The-Hash attacks, but dumber.
‘VLAN Hopping’ sounds pretty cool, but the barrier to experimentation has long been buying a Cisco device, or using someone else’s2. Thankfully, virtualization hasn’t been lost on the networking crowd - and GNS3 provides a great platform to virtualize Layer 2 networks - replete with virtualized Cisco devices - at whatever whimsical topology you can imagine.
In this article - I’ll show you how to set up a fully virtualized lab environment to test out Layer 2 attacks and demonstrate how to abuse Cisco’s default DTP Auto to spoof a trunk, and gain access to a sensitive VLAN. There are a few resources which show how to carry out the attack - but assume you have configured Cisco switches and routers, and those that configure Cisco switches and routers, but fail to show the DTP attack. Here I show a minimal configuration for a Cisco router and switch, that works under virtualization, and demonstrates the attack.
Credited Sources
I spent a weekend in Cisco references, digging around GNS3 references, and so on. Aside from those these were the most informative resources;
- WhiteWinterWolf - Network layer 2 practical exploitation and protection - 2017
- What I started with - I found the provided commands didn’t work on my images - and have greatly reduced the lab network complexity. WhiteWinterWolf teases, but doesn’t cover DTP. Overall - I think this article is targeted at audiences with familiarity and interest in Cisco devices and their configuration. You’ll note many similarities (read: theft) between these two articles.
- BlackLabsSecurity - DTP Exploitation
- Provides extra commands for examining the switch state throughout the DTP attack - but not configuration, and assumes you’re using actual hardware.
- DigiNinja - Abusing DTP - 2013
- Tight, solid coverage, but missing configuration details & assumes actual hardware.
- Sean Convery @ Cisco - BlackHat-US 2002 - Hacking Layer 2: Fun with Ethernet Switches
- A dump of @Stake’s work on Layer 2 attacks. Much of this, in 2002, was difficult to carry out - before the release of
yersinia
3 in 2005.
Lab Setup
We’re going to set up a virtual router, R1
, and a switch, ESW1
. R1
is going to run DHCP for our VLANs, establish the 4 security zones, and route traffic between them. We’re going to put some boxes on the VLANs {Admin, Wordpress, Chump, Kali}, and carry out some Layer 2 shenanigans that work around the security zone limitations R1
imposes.
Dependencies
Here’s what you’ll need to set up and carry out interesting attacks.
You
Are comfortable with Linux and can set up and manage virtual machines without instruction. You have a computer with 8+GB of RAM. Ideally, that computer runs bare-metal Linux.
You do not need to know anything about Cisco devices, how to navigate their CLI, or configure them. You needn’t have ever heard of GNS3.
Host Software
We’ll walk through GNS3 below - but you’ll want a working install of wireshark
, and a user set up for packet capture.
You want a hypervisor, I’m using VirtualBox.
Virtual Machines
We want 4 in total;
- Server
- Some garbage service that we can sniff logins to. I, like WhiteWinterWolf, use Bitnami’s Wordpress Appliance. You could make do with a box that simply has
netcat
installed. - Admin
- To simulate an admin logging into the server. I use a linked-clone of a Debian install.
- Kali
- A Kali Linux box to simulate our attacker.
sudo apt install yersinia ettercap vlan
. - Chump
- To simulate an average joe on the same VLAN as our intrepid attacker. I use a linked-clone of a Debian install.
Router Images
We’re going to use two images provided by Cisco VIRL (a mere $200) to set up a toy network that gets us 3 VLANs; an Admin segment, a User segment, and a Server segment.
According to the internet vios_l2-adventerprisek9-m.03.2017.qcow2
and vios-adventerprisek9-m.vmdk.SPA.156-3.M2
are better versions - with support for SPAN
ports, something called QinQ
, and other features that get Cisco certification people excited.
GNS3
Follow GNS3 Docs - Getting Started with GNS3 - put this on a bare-metal Linux host, or try your luck with the GNS3 VM. You need QEMU support.
Disable QEMU KVM
I mix QEMU and VirtualBox virtualization on the same machine - if you do the same (do the same) you’ll run into KVM conflicts. QEMU can be instructed, instead, to use full-virt / non KVM, at the cost of marginally more CPU use.
Add enable_kvm = False
and require_kvm = False
lines under [Qemu]
to gns3_server.conf
- mine was at ~/.config/GNS3/gns3_server.conf
.
Appliance Setup
The next step is to start a project, and point GNS3 at our Virtual Machines and Router images. If you’re already familiar with GNS3, register the router images and lab virtual machines - then move onto the next section.
Launch GNS3 via gns3
, and name your first project.
After creating the project - you’re in the main GNS3 project screen. We’re going to work with functions along the left hand side - click the cluster of 4 icons, just above the ethernet cable icon. Scroll down until you see an entry for Cisco IOSv, then try to drag it into the main window.
GNS3 is going to pop up a dialog box asking us to point it to our router images, select the version 15.6-T(2)
, then click the import button to import the image.
Next, apply what you’ve learned to Cisco IOSvL2.
You’re 1/2 way to GNS3 expert. Next - drag out an instance of Cisco IOSv 15.6-T(2)
and an instance of Cisco IOSvL2 15.2.4055
to the main screen.
You can rename those elements by double clicking directly on the labels - GNS3 gives you a ‘hostname’ prompt dialog. Go ahead and rename the IOSv router to R1
and the IOSvL2 multi-layer switch to ESW1
.
Click the Ethernet cable icon to add a link between these two nodes. A link is a virtual physical connection, when you click R1
you should see one card with four ports, labeled Gi0/0
- Gi0/4
, and ESW1
should list 4 cards Gi0
- Gi3
with 4 ports each. Connect R1
Gi0/1
to ESW1
Gi0/0
. If you don’t get it right, you can right click a link to delete it. Pressing esc
ends link mode.
Next - register your 4 VirtualBox VMs with GNS3, do that by clicking + New appliance template
found at the bottom-left hand side of the window.
Rinse and repeat until you have all four virtual machines added. There’s one configuration change to make - and it can be done from GNS3 Settings under VirtualBox VMs. You have to let GNS3 manage all of the target VMs interfaces.
Drag each of the VirtualBox VMs into the main window until you end up with a setup resembling our reference;
Network Setup
We’ll get everything set up, we’re almost to the good part.
Network Design Overview
Recall, we’re going to rely on R1
to provide DHCP and inter-VLAN routing. Your switch actually controls what ports end up on what VLANs, and in vanilla 802.1q
encapsulated networks, all switches can transit any VLAN.
We’re going to set up four VLANs, numbered 1-4, and four corresponding Cisco Security Zones (NOBODY
(1), ADMINS
(2), SERVERS
(3), USERS
(4)). Along with an inspect policy INSPECT_ALL
, that allows traffic from one security zone to the other - in this network, we want USERS
and ADMINS
to access SERVERS
, but we won’t allow USERS
to access ADMINS
, or SERVERS
to access USERS
and ADMINS
.
Because ESW1
is going to serve different VLANs to different physical ports - we’ll reserve ports on the Gi0
card for transit, Gi1
for USERS
, Gi2
for ADMINS
, and Gi3
for SERVERS
.
Next, we’ll bring R1
and ESW1
online for configuration.
R1 Configuration
First, let’s bring R1
online, right click the node and select Start
. Afterwards, you can bring up a management console by double clicking on the node. Give it a few minutes to start, eventually you’ll see that the image passed code signing verification
, hit the enter key to get to a console prompt - now you’re talking directly to the router.
Let’s issue our first command to check out what interfaces are available for configuration by executing show interfaces summary
.
From this, we can see that what GNS3 calls Gi0/0
- Gi0/3
the Router calls GigabitEthernet0/0
- GigabitEthernet0/3
.
The console interface supports tab completion - and has built in help. For example, show ?
lists all the various topics you ca
n explore through show
.
Further, commands can be shortened to the shortest non-conflicting name; show
to sh
and show interfaces summary
to sh int su
, for instance.
The prompt gives us some good information, a #
indicates privileged mode, and a >
indicates user mode. If you’re staring at a >
issue an enable
- if you’re lucky you earn a #
privileged prompt without needing a password.
Let’s try some simple configuration - the router can be configured a few ways, but we’re going to use terminal configuration, enter this mode by typing in configuration terminal
.
Let’s start by changing the router’s name from Router
to R1
by issuing hostname R1
- then issue an end
to exit config
mode.
Next - in order, we’re going to set up the inspect policy, define security zones, zone-pair security policies allowing cross-VLAN traffic, interface assignments, and finally DHCP configuration for each VLAN.
The policy below presumes you’ve connected R1
Gi0/1
to ESW1
Gi0/0
. Just paste the whole blob into the console window.
Next, we can persist our running-config
across device reboots by copy
ing it to startup-config
. Issue copy running-config startup-config
.
For extra credit, we set up realistically bad creds (as is tradition in networking equipment), a web-interface, and SNMP, for continued amusement;
For kicks, let’s take a look at the full running configuration using show running-config
. Pressing enter advances line by line, spacebar pages, and q
terminates. If everything looks good, let’s move right along.
ESW1 Configuration
We’re going to bring ESW1
online, but before we do - let’s start a traffic capture on the link between R1
and ESW1
by right clicking the link between them, and selecting Start capture
. This should launch a Wireshark session capturing the traffic between the two.
Now that we’re drawing uncomfortable parallels, let’s bring ESW1
online and see what happens.
Compared to our router, the switch configuration is short. We’re setting up a Cisco VLAN Trunk Protocol (VTP) domain - and associating Gi1
with VLAN 4, Gi2
with VLAN 2, and Gi3
with VLAN 3. Gi0/0
is set to trunk with dot1q
802.1q encapsulation.
Wireshark should now show you a bunch of Spanning Tree Protocol (STP) messages, along with LOOP and CDP.
Let’s check out the state of ESW1
’s ports with show interface status
;
OK - so we’ve explicitly configured ESW1
to serve VLANs on all available interfaces, with a single trunk port on Gi0/0
.
Bring up the VMs
Bring up the rest of the Virtual Machines and verify everything is working as expected.
- Server
- Our Bitnami instance is verified to have pulled a DHCP entry out of the pool @
192.168.3.x
. - Admin
- Pulls an IP from
192.168.2.x
. - Chump
- Pulls from
192.168.4.x
. - Kali
- Pulls a
192.168.4.x
.
Verify Chump, Kali, and Admin can access Server;
Kali (192.168.4.100
) can hit Server (192.168.3.101
), but can’t hit Admin (192.168.2.100
);
Attack Execution
Same-VLAN DHCP Spoofing
Our Kali box can carry out various MITM attacks, such as ARP-Poisoning and DHCP Spoofing against targets in its VLAN, let’s briefly review;
Inspect traffic between Kali and ESW1
, then try to simulate a login from Chump to Server using wget -O /dev/null http://192.168.3.101/login.php?username=dank\&password=dankpw
. ESW1
isn’t flooding the traffic locally - these switches are smart enough not to send Chump’s traffic to Kali. DHCP requests are broadcast wide - on the other hand, so let’s try the classic DHCP ACK injection attack.
- From Kali
- Start a DHCP attack using ettercap with
sudo ettercap -Tzq -M dhcp:/255.255.255.0/192.168.4.1
- From Chump
- Grab the link local interface and device from
ip addr
, then renew DHCP, and simulate a login.
You may have to try this two or three times before ettercap wins the race. Eventually;
You’ll notice Chump’s outbound traffic is showing up on ESW1
to Kali link. This is a half-duplex attack… you can amuse yourself with full-duplex / ARP Poisoning, or move right along.
Why can’t we just use ARP Poisoning or DHCP spoofing attacks against Admin? Pretty simple - Admin is on a different VLAN. Go ahead and pull a new IP on Admin;
From Wireshark you can see that Admin’s DHCP packets aren’t ever broadcast to the Users VLAN, we need to get closer, we need to get on the admin VLAN.
VLAN Hopping using the magic of DTP
this behavior isn’t a security problem, because that’s the way DTP works
From Kali, review the network situation again; you can reach Chump and Bitnami, but not Admin. We need to get closer.
Let’s also refresh our memory of ESW1
’s interface status;
If you’re curious about Yersinia - you can start it in user-friendly GTK mode yersinia -G
or ncurses yersinia -I
. Here’s let’s just skip to sending out our DTP packet to the switch;
That’s it, you’re a switch now. Hunt through wireshark to find the Yersinia generated DTP message;
Finally, we can confirm that we’ve become a trunk by asking ESW1
;
You might be wondering, self, didn’t I explicitly configure everything on Gi1/0-3 to serve out dot1q
packets for VLAN 4? Well, you’re not wrong, and you wouldn’t be wrong for thinking that maybe setting up a port should override automatic discovery protocols that are so obviously abused. Cisco’s official party line is “this behavior isn’t a security problem, because that’s the way DTP works” - which you might buy if you’re a fan of circular logic.
As a switch, you’ll notice that you’ve lost the ability to access network peers, including Server and Chump. Because you’re a trunk ESW1
is now sending you 802.1q encapsulated frames - but Linux just doesn’t know it yet.
Let’s change that by loading the 8021q
kernel module, and adding interfaces for the various VLANs using vconfig
.
If you can’t actually access anything at all - your routing table might be hosed. Review them with ip route
- then delete / replace as necessary e.g. ip route add default via 192.168.2.1
.
Now that we’re cozy with Admin, let’s see if we can pull off ARP Poisoning against the Admin VLAN. Before we do - we need to tear down all the other network links - because they’ll confuse Ettercap (if there’s commandline magik to get around this I don’t know it).
From Kali, launch Ettercap in GTK mode; sudo ettercap -G
. Hit sniff > Unified Sniffing
, then Hosts > Scan for Hosts
.
Hit Hosts > Hosts list
, then drop 192.168.2.1
. Then start ARP Poisoning from Mitm > ARP Poisoning....
include Sniff remote connections.
From Admin, navigate to http://192.168.3.101/?username=dank&password=dankpw
.
If 192.168.3.101
logins are really the target, you’re better off sniffing it instead. Now you’ve got a environment that you can continue working on.
Just to recap - we’ve used DTP to become a trunk, jumped onto VLAN 2, and carried out a Layer 2 MITM attack to sniff credentials. Rad.
That’s a wrap
Before you close it up for the day, you can pursue some more threads;
While Ettercap is running, visit http://192.168.2.1 and login with cisco
/cisco
.
From Kali, try and brute force the SNMP community strings; nmap -sU --script snmp-brute 192.168.1.1
.
You’ve got a nice network to set up further labs; Windows DC and workstation network might be a nice next step.
-
To the Asset. ↩︎
-
SEN: Someone Elses’ Networks ↩︎
-
FullDisclosure Mailing List September 2005 - The Yersinia Authors - VLAN Hopping, myth or reality?. Can you believe this is still a problem? ↩︎