Spoofing Internal Packets for Multihomed Linux Devices

Spoofing Internal Packets for Multihomed Linux Devices

During several assessments, we’ve encountered interactions between multihomed Linux devices and common firewall configurations, with Linux’s stateful firewall (conntrack module). We have successfully exploited this vulnerability on multiple occasions, allowing us to spoof and inject packets into internal communication streams via an external/public interface.

Since this attack involves spoofing internal IP addresses (typically within private IP ranges), successful exploitation usually requires the attacker to have a foothold on an adjacent network.

We’ve authored a detailed white paper Conntrack – Spoofing Packets for Linux Multihomed Devices, which outlines this issue and presents several exploit scenarios.

TL;DR

In short, the conntrack module, which tracks connections for the stateful firewall, does not account for the interface on which a connection was established. As a result, a firewall rule allowing established and related connections applies to all connections, not just those directed to external hosts. For example, the following is a typical firewall configuration:

> sudo iptables -L -v
Chain INPUT (policy DROP 248K packets, 289M bytes)
 pkts bytes target     prot opt in     out     source               destination         
  190 37764 ACCEPT     all  --  lo     any     anywhere             anywhere            
1140K 1346M ACCEPT     all  --  wan0   any     anywhere             anywhere             ctstate RELATED,ESTABLISHED
3531K 4113M ACCEPT     all  --  lan0   any     anywhere             anywhere

This configuration drops all traffic by default, allows all packets on the internal lan0 interface, and permits only RELATED,ESTABLISHED packets on the wan0 interface. While simplified, this firewall setup is typical of what we see in real-world environments. The key rule here is the one allowing RELATED,ESTABLISHED packets.

What qualifies as an ESTABLISHED packet? Any packet associated with an ongoing traffic flow tracked by the conntrack module. As mentioned earlier, conntrack does not track the interface on which packets are received. Therefore, packets arriving on the wan0 interface that share the same IP address and ports as an established connection on the lan0 interface will match the firewall rule and be allowed through.

This enables an attacker on the external interface to spoof and inject packets into internal traffic flows. We've successfully exploited these issues to:

  • Inject data into a Lidar stream on an autonomous vehicle.
  • Spoof NAT-PMP/PCP packets to create dynamic port mappings on a NAT router.
  • Spoof mDNS responses.
  • Inject packets into communications between two internal hosts behind a NAT router.

The following video demonstrates an example of injecting into a Lidar stream and corrupting the data:

 

What is Vulnerable?

This issue applies to multihomed Linux devices, which are simply devices connected to multiple networks. For example:

NAT routers are an obvious target, but multihomed devices appear in many other contexts as well. For example, when you spin up a virtual machine, the Linux host is connected to multiple networks—some of which may be virtual—but this distinction is irrelevant to conntrack. VPNs are similar, though they may include their own packet filtering components. Embedded devices, automotive systems, and drones can also be vulnerable, as many of these devices contain internal networks for sensors and other components.

Any Linux system with multiple interfaces that lacks anti-spoofing firewall rules is likely to be vulnerable.

Limitations

There are some limitations to exploiting this issue:

  • The attacker must be able to route internal traffic, typically from private IP address ranges, to the external/public interface. This often requires a foothold on a network adjacent to the target device or another means of routing the spoofed packets.
  • Blind injection or partial brute-forcing is typically necessary. Since source ports, internal addresses, and sequence numbers may not be fully known, the attacker will need to brute force some parameters.
  • Injecting into TCP connections is more challenging due to TCP sequence numbers, whereas UDP connections are much easier to spoof and inject into.
  • An internal host must be communicating with the targeted multihomed Linux system. If multiple hosts are communicating on the internal network directly to each other, their packets may not be exposed to conntrack and thus may not be exploitable. However, certain scenarios, such as those involving a NAT router, may elevate these connections to conntrack, making the traffic flows trackable and exploitable.

Despite these limitations, we have successfully spoofed and injected into critical data streams. The white paper provides more detailed descriptions of these limitations and potential workarounds.

Mitigations

We previously recommended using anti-spoofing firewall rules in DHCP Games with Smart Router Devices, and they are effective mitigations for this issue as well. If the Linux firewall had rules to protect its internal interfaces and drop packets with spoofed IP addresses on external interfaces, it would have prevented this vulnerability from being exploited. For instance, the following rules would protect connections on lan0, which has an IP address in the 192.168.0.0/24 network:

> sudo iptables -I INPUT 1 -s 192.168.0.0/24 -i ! lan0 -j DROP
> sudo iptables -I INPUT 1 -d 192.168.0.0/24 -i ! lan0 -j DROP

Additionally, services intended for internal interfaces should use the SO_BINDTODEVICE socket option to restrict packet reception to a specific interface. (Note: This is different from binding the socket to an internal address, which still leaves it exposed to packets from external interfaces.) To demonstrate this, we created an LD_PRELOAD wrapper around socket() and setsockopt() to bind sockets to a user-specified interface. This tool can be used on external software for which one does not have the source code in order to still restrict it to certain interfaces. This tool can be found here.

Summary

Common Linux firewall rules, along with how the conntrack module tracks traffic flows, frequently allow packet spoofing and injection into internal communications from an external/public interface. This is primarily due to the omission of anti-spoofing rules in many firewall configurations. For a more detailed explanation, including discussions on limitations, strategies to minimize brute forcing, examples, and mitigation techniques, refer to the white paper.

About the Author

Michael Milvich is a Fellow at Anvil Secure. Prior to joining Anvil, Michael worked as a Senior Principal Consultant IOActive Inc, and as a Cyber Security Researcher at Idaho National Laboratory (INL). Michael got his start in embedded security hacking SCADA and ICS systems and later broadened to encompass a wide variety of embedded systems across many industries. Michael’s strong technical background combined with his years of general consulting have been utilized to assist some of the leading technologies and most advanced security groups in improving their security posture.

Tools

awstracer - An Anvil CLI utility that will allow you to trace and replay AWS commands.


awssig - Anvil Secure's Burp extension for signing AWS requests with SigV4.


dawgmon - Dawg the hallway monitor: monitor operating system changes and analyze introduced attack surface when installing software. See the introductory blogpost


nanopb-decompiler - Our nanopb-decompiler is an IDA python script that can recreate .proto files from binaries compiled with 0.3.x, and 0.4.x versions of nanopb. See the introductory blogpost


ulexecve - A tool to execute ELF binaries on Linux directly from userland. See the introductory blogpost


usb-racer - A tool for pentesting TOCTOU issues with USB storage devices.

Recent Posts