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:

network topology
Figure 1 – GNS3 Network Topology

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.

  1. Create a VLAN-aware bridge

    /interface/bridge add name=br1

  2. 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

  3. 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

  4. 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

  5. Enable VLAN filtering on the bridge

    /interface/bridge set br1 vlan-filtering=yes

DHCP Configuration

  1. 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

  2. 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.254

    NOTE: 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

  1. Start NetworkManager’s TUI

    nmtui

  2. Navigate to Edit a Connection

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

    edit an ethernet connection
    Figure 3 – Selecting network interfaces with NetworkManager
  4. Set IPv4 Configuration to Automatic, then click OK
    ipv4 automatic
    Figure 4 – Configuring network interface as a DHCP client
  5. From the interface list, select Back to return to the main menu, then select Activate a connection
  6. Cycle the connection to request a new DHCP lease by pressing Deactivate to disable the interface, then pressing Activate to bring it back up
    disable interface
    Figure 5 – Deactivating the network interface
  7. From the interface menu, select Back, then Quit to return to the terminal
  8. After the DHCP server is online, verify that the client received an IPv4 address
    ip -c -br a

NetworkManager CLI

  1. Return to the Guest machine and display the NetworkManager connection profiles, and note the connection name associated with the Ethernet interface

    nmcli connection show

    nmcli connection profiles
    Figure 6 – Listing available connection profiles
  2. Set the IPv4 method to Automatic

    nmcli connection modify “netplan-enp0s3” ipv4.method auto

  3. Cycle the connection to request a new DHCP lease

    nmcli connection down “netplan-enp0s3”

    nmcli connection up “netplan-enp0s3”

  4. 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
  1. Return to the MikroTik switch and list the current addresses that have been leased

    /ip/dhcp-server/lease print

    leases
    Figure 7 – Current DHCP leases
  2. Return to the Guest and check that the default gateway of Guest points to the switch’s VLAN 10 interface

    ip route show default

    default
    Figure 8 – L3-Switch gateway assigned
  3. Ensure that the Attacker can ping both the Guest and the Server

    fping -I eth0 10.0.10.199 10.0.20.200

    fping
    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.

  1. In the L3-Switch, manually delete the Guest DHCP entry

    /ip/dhcp-server/lease remove [find host-name=Guest]

  2. Return to Guest and disable Guest‘s network interface

    nmcli device disconnect enp0s3

  3. 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.

  4. 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.

  1. 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

    starve
    Figure 10 – Attacking the DHCP server’s lease pool
  2. 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

    50
    Figure 11 – Lease pool exhausted
  3. 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.

  1. In the Attacker, start Yersinia in Interactive Mode

    sudo yersinia -I

    yersinia
    Figure 12 – Yersinia’s default view
  2. Press G to display the list of protocols you can target and select DHCP
  3. Press X to view available DHCP attacks and choose 2 to create a rogue DHCP server
  4. 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
    yersinia
    Figure 13 – Configuring a rogue DHCP server
  5. Press enter to continue
  6. Restart NetworkManager in Guest to send a fresh DHCPDISCOVER

    systemctl start NetworkManager.service

  7. After a few seconds, check if the default gateway has changed to Attacker‘s address
    new default
    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.

  1. 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
  2. Now flush Attacker‘s route cache to remove any saved redirects
    sudo sysctl --write net.ipv4.route.flush=1
  3. Try pinging the Server from the Guest
    ping fail
    Figure 15 – Inter-VLAN ping failure
  4. 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

    tcpdump
    Figure 16 – TCPDump traffic inspection

IP Forwarding

  1. Check whether IP forwarding is active on Attacker (1 = enabled, 0 = disabled)

    cat /proc/sys/net/ipv4/ip_forward

  2. Enable IP forwarding
    sudo sysctl --write net.ipv4.ip_forward=1
  3. Pinging Server from Guest will now be successful
    ping
    Figure 17 – Inter-VLAN ping success
  4. 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
    wireshark
    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

  1. 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

  2. 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

  3. 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

  4. Restart the broker to apply configuration changes

    systemctl restart mosquitto.service

  5. 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>”

    sub
    Figure 19 – Starting an MQTT subscriber

Guest MQTT Configuration

  1. 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>”

    pub
    Figure 20 – Sending a message over MQTT protocol
  2. Looking at Server‘s subscriber session, you should see the message come through
    sub
    Figure 21 – Receiving an MQTT message

Hacking MQTT

  1. 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’

    listening on the wire
    Figure 22 – Half of MQTT session
  2. Extract the username and password used by Guest

    tshark -i eth0 -n -Y ‘mqtt.msgtype==1’ -T fields -e ‘mqtt.username’ -e ‘mqtt.passwd’

    intercepting mqtt username and password
    Figure 23 – Intercepting the MQTT session username and password
  3. Extract the message that was published to the broker

    tshark -i eth0 -n -Y ‘mqtt.msgtype==3’ -T fields -e ‘mqtt.msg’

    extracting mqtt message over the wire
    Figure 24 – Extract MQTT message
  4. Decode the captured message from hexadecimal

    echo ‘<string>’ | xxd -r -p

    decoding message from hexadecimal
    Figure 25 – Decoding the MQTT message from hexadecimal

Phase V – Mitigations

MITRE ATT&CK recommends two primary strategies for mitigating DHCP Spoofing attacks: Network Intrusion Prevention (M1031) and Filter Network Traffic (M1037). The following section outlines potential implementations of these mitigations in MikroTik RouterOS.

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.

  1. On L3-Switch, enable DHCP snooping on the bridge

    /interface/bridge set br1 dhcp-snooping=yes

  2. 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

  3. 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

  4. 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

    dhcp snooping disabled
    Figure 26 – DHCP Snooping security measure stopping rogue servers
  5. For reference, here is what this looks like with DHCP snooping disabled
    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.

  1. Enable IP firewall filtering on the bridge

    /interface/bridge/settings
    set use-ip-firewall=yes
    set use-ip-firewall-for-vlan=yes

  2. Add new filter rules

    /ip/firewall/raw

  3. 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

  4. 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”

  5. 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”

    dhcp abuse logs
    Figure 28 – Log messages alerting to DHCP pool exhaustion attack
  6. 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

    rule statistics
    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).

dhcpstarv before firewall rules
Figure 30 – DHCP starvation normal execution

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.

dhcpstarv after firewall rules
Figure 31 – DHCP starvation is hindered by network filtering

End of Lab

License

Icon for the Creative Commons Attribution-NonCommercial 4.0 International License

Mastering Enterprise Networks (3rd Ed) Copyright © 2026 by Mathew J. Heath Van Horn is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License, except where otherwise noted.