Man in the Middle: Viewing and Modifying Victim Traffic
When I was a student first getting into security, I had a school project that involved attempting to find cryptographic vulnerabilities within some custom code. I had heard of the concept of a Man in the Middle (MITM) attack but did not know how I could view and intercept network traffic. Fast forward to today, and I use a MITM for logging and testing purposes on almost every assessment I perform. Hopefully this post can help pass on the knowledge that I’ve gained to others who are attempting to get into this field.
HTTPS and Certificates
It is important to note that HTTPS adds some complexities to any MITM attempt. The difference between HTTP and HTTPS is that HTTPS adds in the TLS protocol in order to encrypt communication between the client and the server. As part of this protocol, the server proves its identity using the public half of a cryptographic key intended for this purpose, known as a certificate. These certificates come from trusted sources known as Certificate Authorities (CAs), where each client device has a list of CAs that are considered trusted.
The specifics of TLS handshakes are not necessary to understand the topic of MITM setups, but the (oversimplified) end result is that each session is encrypted in a way that is tied to the server’s public certificate. This actually prevents a MITM setup from working, since the setup either has to work with encrypted traffic that can’t be read or must communicate separately with the client and with the server. This second method will cause the certificate that is read by the client to be incorrect, leading to the client rejecting the connection. There are two main ways around this issue, both of which require access to the client device. Firstly, you can disable TLS verification on the client. This is a supported feature in many applications for debugging purposes, such as the curl --insecure
command on Linux. Disabling TLS verification simply tells the client to accept any certificate that it is shown, even if it comes from an untrusted CA. This allows the MITM to provide its own certificate using its own CA and still be accepted. For a more permanent and system-wide solution, the MITM can create its own CA and add it to the client device’s list of trusted authorities. This would cause every application on the client device to accept the custom certificates, allowing the MITM to spoof any servers that it desires.
MITM Proxy Tools
Like all tools, there are many good options for MITM proxies. Each have their own strengths and weaknesses, and which one to use is entirely personal preference. Within the ivision security team, two common options are Burp Suite and the open source mitmproxy with many of us even choosing to use both regularly. Both of these tools work similarly to proxy traffic from a client by listening for incoming connections on a specific port (the default for both is port 8080
) and using a custom CA to create ephemeral certificates pretending to be whatever server the original request was intended for. The specifics of how these tools work is out of scope for this post, but the mitmproxy documentation provides detailed descriptions of how everything works.
For this blog post, examples will be using mitmproxy
on a Linux operating system. At this point, a simple setup such as proxying a web browser on the localhost is very simple to use. First, start mitmproxy
, either with no flags or with optional flags according to your preferences (I am using mitmproxy --showhost
as I prefer to see the hostname in the list of proxied requests). This will create a proxy listener on port 8080, which can be used with a tool such as curl
as is shown below:
$ curl --insecure --proxy localhost:8080 https://example.com
Executing the above curl
command while mitmproxy
is running should result in the curl
command working as expected and receiving the normal response. However, the request should also be visible from within mitmproxy
.
MITM Networks
As shown above, creating a working MITM setup is surprisingly easy when the client application is running locally and/or supports specifying a proxy. However, not all applications support this feature. For example, you may want to proxy a smartphone application. You could set a system-wide proxy in the device’s settings, but that leaves the possibility to forget to turn it off which is annoying and can break your device’s network connectivity until you remember. Instead, for cases such as this I personally prefer to create a WiFi network where all traffic on the network gets proxied before going to the internet.
A setup such as this requires a network card that can support broadcasting a network. From there, the traditional method to create the MITM network would be to use a variety of networking tools such as dhcpcd
and iptables
in tandem. Instead, I use a script called lnxrouter that handles the networking automatically. This allows the network to be created in a single command:
$ sudo lnxrouter --tp <proxy port> --ap <broadcast interface> <SSID> -p <password>
Double-ended MITM
The most unique MITM setup that we come across somewhat frequently is when testing a router or a similar device. In this case, we need to be able to connect to the router’s Local Area Network (LAN) in order to perform most of the testing. However, we also need to be able to connect to the device’s Wide Area Network (WAN) in order to observe what ports are exposed on that interface. We additionally would like to setup a MITM on both sides of the device in order to observe all traffic being sent to or from the device. This creates an interesting scenario where the consultant’s laptop needs to be connected to the internet for normal activities, to the device’s LAN, and also to the device’s WAN simultaneously.
To facilitate all of these connections on my laptop’s limited network cards, I have two ethernet to USB adapters that I use for connecting to both sides of the router. They can be clearly differentiated thanks to a piece of electrical tape that I put on one of them and I even gave them custom interface names so I can more easily reference them in commands (detailed instructions on how to do this can be found on the Arch Linux wiki). I named the interfaces mitm_wan
and mitm_client
, for the adapters that are plugged into the device’s WAN and LAN respectively. For this article, I will be using the mitm_wan
and mitm_client
names to refer to the interfaces.
Attempting to MITM the LAN side of the router is fairly self-explanatory. Simply connect the mitm_client
adapter to the router’s LAN port and proxy traffic that is destined for the router through your proxy tool of choice. The WAN side is a bit more complicated, due to the fact that it also needs to provide internet connectivity (assuming that’s necessary for testing). Additionally, this testing will likely require installing the proxy’s CA in the router, as was mentioned previously. Luckily, the same lnxrouter
tool can be used for providing this connectivity and routing the traffic through our MITM tool. First, connect the mitm_wan
adapter to the router’s WAN port. Then, the following command will create a network on mitm_wan
and proxy all incoming traffic on that interface before ultimately sending it to the internet:
$ sudo lnxrouter -i mitm_wan --tp <proxy port>
From here, assuming that HTTPS errors don’t cause any issues all traffic should be visible within the proxy tool of choice. Additionally, both mitm_client
and mitm_wan
will have their own IP address spaces to allow easily specifying which side of the router that traffic should be sent to. The networking can be easily tested by using curl
and its --interface
flag. Running curl --insecure --interface mitm_client http://example.com
should successfully receive the expected response, and the proxy listening on mitm_wan
should see the request since curl
was forced to route the traffic through the device being tested.
Security testing often requires creative networking solutions. These techniques, when combined with even more tools such as ssh
and its port forwarding capabilities, can help to enable in-depth testing of everything that a target may be doing on the network level. With just a few network adapters, anyone can understand how various applications and devices communicate over a network.
If you’re interested in more detail, or want to work with our team, reach out to research@ivision.com!