# Final Project - Network Tap/MitM

For this project, I will be constructing my transparent network tap / monster-in-the-middle device using a raspberry pi 3B+ (hostname pitap)

## Background

This device will be constructed and deployed on my home network. Specifically, I will insert this device between an IP camera I own (hostname reolink) and a network switch, which connects to the rest of my home homework, including my desktop from which I normally access the cameras RTSP stream or HTTP web interface.

At this point, I have physically configured my network to support this project, so let's take a look. Here is a rough sketch.

![uml](./photos/background/uml.png)

And here are a couple photographs of the hardware - the parts most relevant networking-wise are in red.

![nest](./photos/background/nest.png)

![reolink](./photos/background/reolink.png)

For reference, here is a table of the relevant devices

| Device              	| Adapter      	| MAC               	| IP                     	|
|---------------------	|--------------	|-------------------	|------------------------	|
| Router (ZyXel)      	| WAN          	| 08:26:97:5B:9A:01 	| 97.120.207.11          	|
| Router (ZyXel)      	| LAN (eth+wl) 	| 08:26:97:5B:99:FE 	| 192.168.0.1            	|
| Switch (cisco)      	| eth          	| 00:9E:1E:0E:CF:02 	| X                      	|
| pitap               	| eth0         	| b8:27:eb:8a:05:87 	| 192.168.0.38 (temp)       |
| pitap               	| eth1         	| 24:f5:a2:8b:4a:06 	| X                      	|
| pitap               	| wlan0        	| b8:27:eb:df:50:d2 	| 192.168.0.42           	|
| Desktop (pop-os)    	| enp7s0       	| 04:42:1a:93:54:da 	| 192.168.0.56           	|
| IP Camera (reolink) 	| eth          	| ec:71:db:d1:1c:ca 	| 192.168.0.4 (assigned) 	|

Before proceeding, we should consider how the reolink device will appear on my network upon successfull configuration of the network tap. In my case, the reolink camera has an IP assignment (DHCP reservation) from my gateway of 192.168.0.4

![lease](./photos/background/lease.png)

At this time with the current wiring, the reolink appears unavailable to my network, and the pitap is present on the network on ethernet. For the end result, we expect the pi to no longer appear on ethernet (it will then be on wireless), and we expect the reolink device to return to the network on ethernet with the expected hostname, MAC, and IP address that the gateway is already familiar with. 

![device](./photos/background/device.png)

I have other interesting devices connected to my home network, including additional switches, raspberry pi's, IP cameras, wireless extenders, and an active multiplayer game server. These will be ignored.

## Baseline statistics

Before moving on to configuration, we should have an idea of the network performance without the pitap so we have something to compare to later on. We hope the pitap will introduce minimal network performance degredation, as this would increase the chance of detection. For this section, I will revert my network by shutting down pitap and plugging the reolink camera back into my switch. 

A quick ping shows an average latency of .378ms, and a high spike of 1.36ms

![ping](./photos/baseline/ping.png)

Getting a maximum measurement of theoretical bandwidth is not straightforward. Reolink does not (easily) provide ssh access to the underlying operating system, so I cannot use a tool like `iperf3` to test the bandwidth. However, in my current network configuration, I can consider some things to get an idea

* All ethernet cables used support gigabit links (Cat 6 or Cat 5e)
* All of my primary networking devices support gigabit links (desktop PC, switch, router, fiber modem, ISP subscription)
* My reolink camera supports [100 Mbps max](https://reolink.com/us/product/rlc-510a/#specifications) ethernet connection
* The PoE being injected to the reolink camera would redundantly limit bandwidth to 100BASE-T given that it uses half of the conductors
* The [pi 3b+](https://www.raspberrypi.com/products/raspberry-pi-3-model-b-plus/) is said to have a built-in gigabit network adapter but is limited to ~300Mbp/s since ethernet passes through the USB 2.0 bus
* The [belkin USB to ethernet adapter](https://www.belkin.com/usb-c-to-gigabit-ethernet-adapter/P-F2CU040.html) I am using with the pi is rated for gigabit speeds. However, this is also going through the USB 2.0 bus (at the same time), so I expect the overall maximum performance of pitap to be 300Mbps/2 or ~150Mbps

With all this in mind, the bottleneck at the link layer is my reolink camera itself, and I do not expect this performance to be degraded by using the pitap.

However, we can do a little better to understand the bandwidth I expect to get under normal circumstances. According to my cameras web UI panel, the maximum bitrate it can transmit is 8192 Kbps. This is using its highest performance "Clear" stream with the maximum resolution of 2560x1920, 30 frames per second, and H.264 encoding. As a note, audio is also supported on this stream.

![stream](./photos/baseline/stream-stats.png)

Last, I decided to open the "Clear" RTSP stream in VLC and look at the network statistics

![baseline](./photos/baseline/baseline.png)

When looking at the content bitrate, the number stays in the range of ~4,500 kb/s to ~12,000 kb/s (low end shown above) consistently flipping between higher and lower values once per second. This aligns very well with the 8192 Kbps maximum bitrate reported by the camera itself. After watching the stream for several minutes, I also notice there are only 2 discarded/corrupted frames. Subjectivly, I can also say the stream is very clear and smooth when viewed fullscreen on my 1440p monitor, with no visual artifacts or stutters. 

All said, for the pitap to be "undetectable" the above performance should be maintained.

## Pitap Configuration

Now the pitap is back on the network and phyiscally connected between the switch and the reolink camera as described in the background. I'll start by ssh'ing to the pi over the wireless IP address (192.168.0.42)

![ssh](./photos/config/ssh.png)

My research shows that [`bridge-utils`](https://help.ubuntu.com/community/NetworkConnectionBridge) is likely to be a good choice to help create the tap. As I understand, this utility is purpose built for creating such bridges at the link layer, but some extra steps will have to be taken to function the same way, yet remain invisible at the link layer. An approach with `iptables` and forwarding rules may also be possible but I would expect this to be more difficult since `iptables` seems to operate at the network layer. I have also found a [guide](https://blog.coffinsec.com/howto/2017/03/30/Building-RaspberryPi-Network-Tap.html) which I credit for helping with some of the knowledge needed for this part of the project.

### 1. Install `bridge-utils`

This step is straightforward

![install-bridge.png](./photos/config/install-bridge.png)

### 2. New entry `/etc/network/interfaces.d/pitap.conf` to add the new bridge interface

I start by adding a new network interface configuration here, which is derivative of the one provided by the above mention guide. Modifications were made because I am not interested in changes to the wireless interface, and also I am including this config file as a seperate entry in `interfaces.d`

![pitap.conf.1.png](./photos/config/pitap.conf.1.png)

After rebooting the pi, we have some interesting observations. In the terminal on the left, we see that we can now reach the reolink from my desktop. We perhaps have paid a ~1 ms latency for this, but the bridge does work.

However, on the right we see the bridge has an IP address, so it has a presense at the network layer, and this is a problem

![bridged.png](./photos/config/bridged.png)

### 3. Improvements for network transparency

First I update `/etc/network/interfaces.d/pitap.conf` again, and set the `br0` interface from `dhcp` (as seen in the guide) to `manual` mode. This should help prevent the bridge from trying to ask for an IP address from the gateway

Then, I update `/etc/dhcp/dhclient.conf`

![dhclient.conf.png](./photos/config/dhclient.conf.png)

Specifically, I will comment out those active lines and for good measure I add `denyinterfaces eth0 eth1 br0`. This may be redundant or conflict with the changes to `pitap.conf` but the goal is that no interface on the tap shall perform any type of dhcp activity.

Now I will reboot the pi and attempt to validate results

### 4. Validation

To help with validating the transparency of pitap, I have made a few simplifications

1) Removed the cisco network switch, and plugged the pitap directly into my router
2) Disabled wifi on the pitap to avoid confusion about it's visiblity on my network (`sudo ip link set wlan0 down`)
3) Connected periphrals to the pitap so I can interface with it
4) Put the pitap on a dedicated power supply to avoid brownouts

#### Pitap adapter info
The following `iwconfig -a` shows us the pitap does not have any assigned IP addresses on our network. Aside from a link local Ipv6 assigned to `br0`. I do not fully understand the implication of this, but I do not think it matters. Overall, this is a good sign

![pitap-iwconfig.png](./photos/validation/pitap-iwconfig.png)

#### Router admin panel

The router admin panel shows us the reolink appears with the expect IP and MAC (192.168.0.4 and ec:71:db:d1:1c:ca), just as it did before using the tap. Another good sign

![router-panel.png](./photos/validation/router-panel.png)

#### Router and ARP table
The route table shows that all LAN traffic is itself going through a bridge (`br0`) on the router, which I then assume uses some sort of MAC address table to determine which physical port to communicate on. 

The arp table shows us the IP devices and their associated MAC addresses, and we confirm that none of the MAC addresses associated with the pitap appear here. 

![router-arp.png](./photos/validation/router-arp.png)

Though things look good, at this point I face a final roadblock in confirming my network tap is transparent. I would like to view the MAC address table/Content Addressable Memory which as I understand would show associations between MAC addresses and physical ports on my router, entirely at the link layer. This table could prove or disprove that the link layer in my router has not 'learned' any MAC address of the pitap and that true transparency is achieved. If it was not, I would go back and re-visit my configuration step.

The issue is that my lousy ISP provided router does not seem to make viewing this possible, either in the web UI or terminal. The terminal claims to provide the command `brctl` but it is broken and returns no output. The terminal also provides an elevated `sh` command which could possibly help but that is locked down by an unknown password.

The next step would be for me to flash a new firmware like OpenWRT on my router to get this information. I can not do that at this time as I run a game server with active players on my network and any issues with the firmware upgrade risk causing an extended outage or brick my router. When I aquire another router in the future, this upgrade will then be possible.

In conclusion, I know pitap is transparent at the network layer, and I think it is also transparent at the link layer but I can not prove it.

#### Connecting to reolink
I am able to access the stream again on the reolink with no issues, and video quality appears good. However, we can see that the content bitrate is now lower than before, appering in the range of 1,400 kb/s to 5,500 kb/s with an average of about 3,450 kb/s. This could be because of a bandwidth bottleneck in the pitap, or because now it is dark outside and H.264 can work more efficiently with less color in the image. In this regard I am not sure.

Like before, discarded/dropped frames number only 1 or 2 over a period of several minutes. This is good. 

![reolink](./photos/validation/reolink.png)


### 5. Capture + Forward

Now it is time to do something interesting with pitap by capturing and forwarding the traffic. 

The script [`capture.py`](./capture.py) is intended to do just this. Using scapy, the script works by sniffing all traffic on an interface provided from arguments, and saving those to a unique timestamped file. Every time a file is saved, it attempts to transmit them to a supplied ip address and port with the intention that a listening netcat server can capture and save the contents.

### 6. Attack