Sitemap

Stateful Connection With Spoofed Source IP — NetImpostor

Gain another host’s network access permissions by establishing a stateful connection with a spoofed source IP

9 min readMay 17, 2025

Overview

This blog reviews the technique for establishing a full stateful TCP connection with a spoofed source IP address from the same subnet using ARP poisoning.

The tool introduced in this blog (NetImpostor) is written entirely in GO and can be used as a proof of concept for the techniques reviewed below.

NetImpostor runs on Linux and can be used for defense evasion purposes, as well as for bypassing a firewall’s restrictions, by using the allowed source IP from the same subnet and impersonating another computer.

Source IP Spoofing

Source IP spoofing is the creation of Internet Protocol (IP) packets that have a modified source address to either hide the identity of the sender, to impersonate another computer system, or both.

All IP packets contain a header that precedes the body of the packet and contains important routing information, including the source and destination IP addresses. In a normal packet, the source IP address is the address of the sender of the packet. But, there are no strict restrictions or validations over the field, and if the packet has been spoofed, the source address will be forged and can have the arbitrary value of any IP address.

Problem With Source IP Spoofing

Internet Protocol header can have a spoofed source IP header with any arbitrary value, but using this technique alone faces a problem with stateful connections.

Since the source address of the packet will not be ours, we will not be able to receive the response sent back for it. The response will simply be sent to the forged IP, and we will not be able to retrieve it. So, with this technique alone, we can blindly send requests, but can’t receive any responses for them.

Long story short, we won’t have a stateful connection.

Address Resolution Protocol

ARP (Address Resolution Protocol) is a link-layer protocol that maps an IPv4 address to its corresponding MAC (hardware) address so a host can correctly encapsulate and deliver packets on a local Ethernet network.

We need ARP because network interface cards and switches forward frames based solely on MAC addresses — without translating an IP to a MAC, local LAN communication cannot occur.

Scenario for ARP communication is simple:

  1. Host-A broadcasts ARP Requests on the entire local subnet and asks for the MAC address of the specific IP.
  2. Since the message was broadcast, every single host in the subnet will receive it.
  3. The Host-B, with the IP address that was asked about, sends an ARP Response back, indicating its MAC address. (Other hosts will just ignore the request.)
  4. Host-A receives the ARP Response sent back to it and updates its ARP cache.

As a result of this communication, Host-A knows where to find Host-B and uses its updated ARP cache to communicate with it.

The scope for the ARP protocol is within the same subnet. ARP communication is held between the hosts that are located in the same subnet and use the same gateway.

ARP Poisoning

The interesting thing with an ARP protocol is that, by default, responses are not validated at all.

Any host can send a forged ARP Response, impersonating another IP with their own MAC. The target host will not validate the ARP Response and update its ARP cache with a record, indicating that the IP has moved to a different MAC address.

An even more interesting thing about the ARP protocol is that, by default, you do not need the request to send a response. You can simply just send a response, and it will be processed on the receiving end, regardless of whether it asked for it or not. You don’t have to wait for the target to send a request, so that you can send an impersonating response; you can simply send the response, and it will be processed the same way.

It’s worth noting that you can not forcefully add a new record in the host’s ARP cache by just sending an ARP response. The host needs to send an ARP Request first to create the new entry in the cache. Sending just the response works for just updating the existing record.

Some hosts, like the gateway, hold the record for every host in the subnet, and there is no need to worry whether the ARP record is already there or not. Without the gateway knowing MAC addresses for an entire subnet, it wouldn’t be able to route the response packets from outside of subnets back to the hosts that requested them, therefore, we can confidently assume that the gateway holds the MAC address of every host in the subnet in its own ARP table

Packet Routing In The Network

When sending packets within the same subnet, communication is held using MAC addresses, not IPs. All hosts in the subnet use their ARP cache to locate the MAC address for the specific IP and send packets to the identified MAC addresses. If the cache does not hold the MAC record for the required IP, the host will simply ask for it with the ARP protocol.

When the packets are sent outside of the subnet, they are routed via a Gateway. So every request will have the source MAC of the host itself, and the destination MAC of the gateway(the gateway forwards the requests). Flipped version of that for responses, they have the source MAC of the gateway and the destination MAC of the host(Since the gateway is the sender of the response).

The gateway holds the MAC addresses of every IP from the subnet in its own ARP cache. So, when the response for the specific IP comes, it locates the corresponding MAC address in its own ARP table and routes the packet to that MAC.

Stateful Connection With Spoofed Source IP

The technique is simple.

We take the IP address of any up-and-running host in our subnet and use it for outgoing packets as a source IP.

To route the response back to us, we poison the ARP cache of the host we’re communicating with, so it will route the traffic sent to that IP to our MAC, instead of the original MAC.

Note that it will practically halt the connections of the host we are impersonating, since the responses sent back to it (including those that were indeed requested by it) will be routed to us.

When the communication is held within the same subnet, we need to directly poison the ARP cache of the host we’re communicating with (since it will use its own ARP cache to route responses back)

When the communication is held outside of the subnet, we need to poison the ARP cache of the gateway, since it will be the host that will route and forward responses back.

Problem With Foreign Address

Since the IP address that we are impersonating does not belong to us, it is programmatically harder to bind to that address. We can manually craft the IP header, but it makes the task much more complex, and we lose support for some automated functionalities offered by the operating system and the libraries for network connections.

In addition to that, the kernel will ignore some of the packets.

For example, in most of the operating systems, the TCP Handshake is handled by the kernel. If we send the TCP SYN packet with a spoofed source IP and route the TCP SYN-ACK response back to us, when the kernel receives it, it will ignore or send RST back, because it won’t be able to handle the connection for the IP address that it does not have an interface for.

To solve this issue, we just need to let the kernel see a dummy interface with that IP. We can set up a simple virtual interface with macvlan:

#Set Up
sudo sysctl -w net.ipv4.ip_nonlocal_bind=1

sudo ip link add link eth0 name macvlan0 type macvlan mode bridge
sudo ip addr add 192.168.1.12/32 dev macvlan0
sudo ip link set macvlan0 up

#Clean Up
sudo ip link delete macvlan0
sudo sysctl -w net.ipv4.ip_nonlocal_bind=0

After that, we will be able to bind to that IP address, and the kernel will happily accept responses sent to it.

Protocol Specifications

To maintain full stateful connections for a long period, we need to periodically send impersonating ARP responses and repeatedly poison the ARP cache of the target. This is required because in the meantime, the target might randomly send the ARP Request, and the real host will respond with the valid MAC, so the target will update its ARP cache with a correct MAC, and the responses will now be routed back to the original host. As a result, we will lose our stateful connectivity. To avoid that, we need to continuously update the target's ARP cache with our MAC.

The shorter the interval between the responses, the better.

When the communication is held with a TCP(Transmission Control Protocol), a larger interval is not that much of a problem, because TCP checks if the packet was indeed received by the requesting end, and if not, it resends it. So, inbetween the intervals, if the real host updates the ARP cache of the target with the original MAC, it will recieve our responses, but since it won’t be able to process them, they will be marked as not delivered and when we re-route the traffic back to us, it will be sent again to our host.

When the communication is held with a UDP(User Datagram Protocol), short intervals are required, since UDP does not validate the packet statuses like TCP. (UDP support for NetImpostor is planned for future development.)

The IP address that is spoofed can not be outside of our subnet. The reason for this is that we use ARP to route responses back to us, and the scope of ARP is within the same subnet. We can go as far as a gateway and poison the ARP cache of it, but for the poisoning to do its job, the gateway must be hit with a response first. If the IP that we spoofed is outside of our subnet, our gateway won’t even be hit and asked to route the response back.

NetImpostor

NetImpostor (named as Network Impostor) is a tool that can automate the task of establishing stateful network connections with a spoofed IP address.

It offers a SOCKS5 interface and can dynamically switch the source IP address of every packet that goes through it.

NetImpostor can handle TCP connections. Implementing UDP is possible and is planned for future development.

It can be used simply as a proxy, dynamically spoofing IPs and continuously poisoning ARP caches for the targets.

NetImpostor offers a stateful network connection while impersonating other hosts in the same subnet and can be used to bypass network restrictions, like local IP tables or firewalls.

For example, if IP-1 is allowed to access some resource in or outside of the subnet, we, as IP-2, can impersonate IP-1 and gain the same access as well.

Demonstration

Setup overview — Interfaces:

Interface configuration before running NetImpostor

NetImpostor execution:

Impersonating 192.168.118.89 against the gateway — 192.168.118.24

Using NetImpostor:

Network side view:

As we can see in Wireshark, we have successfully impersonated another host and managed to establish a stateful TCP connection with a spoofed IP.

Network interfaces after the execution:

--

--

No responses yet