Raspberry PI 3 + MITMProxy

The Problem

For a recent project I was working on, I had a need to be able to intercept the http and https requests being made by an application on a mobile device.  This sounded like the perfect opportunity to put my Raspberry Pi 3 to good use.

The Setup

This diagram shows the flow of what I am going to accomplish.  It’s rather simple and straightforward.  The eth0 interface points out to the internet, and the wlan0 interface will host the access point for devices to connect.

Getting Started

Step 1:  Start by getting the latest version of Raspbian on your Raspberry Pi 3.  To do so, take a look at the guide hosted here.

Step 2: Enable ssh.  Look here for more information on that.

Note: With the November build of Raspbian, ssh is disabled by default. To enable it in a headless environment, you can simply place a file named ‘ssh’ in the boot partition of the sdcard.

Configure the Network Interfaces

Step 1: Start by editing your networking interfaces.

sudo vi /etc/network/interfaces

Step 2: Change eth0 and wlan0 to reflect the following:

iface eth0 inet manual

allow-hotplug wlan0
iface wlan0 inet static
    address 192.168.13.1
    netmask 255.255.255.0

Note: You can set whatever you’d like for the address space, just make note as you will need it later when you configure DHCP. Also, this is assuming we will be granted an IP address on eth0 via DHCP.

Step 3: Stop dhcpcd from being greedy.

sudo vi /etc/dhcpcd.conf

Step 4: Add the following line to the bottom of the file.

denyinterfaces wlan0

Note: In recent versions of Raspbian, dhcpcd handles interface configuration by default. We need to tell it to ignore wlan0, as we will be configuring it with a static IP address.

Step 5: Restart the wlan0 interface.

sudo ifdown wlan0
sudo ifup wlan0

Enable the Access Point

Step 1: Install hostapd.

sudo apt-get install hostapd

Step 2: Create the hostapd configuration file.

cd /etc/hostapd/
sudo cp /usr/share/doc/hostapd/examples/hostapd.conf.gz .
sudo gunzip ./hostapd.conf.gz

Step 3: Edit the configuration file.

sudo vi /etc/hostapd/hostapd.conf

Step 4: Change the values in the config file to reflect the following:

interface=wlan0
driver=nl80211
ssid=Pi3-MITM-Wifi
hw_mode=g
channel=6
ieee80211n=1
wmm_enabled=1
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_key_mgmt=WPA-PSK
wpa_passphrase=raspberry
rsn_pairwise=CCMP

Note: At this point, you can test to see if your access point is functioning properly. To test the access point, simply run the following:

sudo /usr/sbin/hostapd /etc/hostapd/hostapd.conf

You should see the access point Pi3-MITM-Wifi if everything went smoothly. You can stop it from running with the keyboard sequence Ctrl+C.

Step 5: Configure the access point to launch at boot.

sudo vi /etc/default/hostapd

Step 6: Change DAEMON_CONF to point at the hostapd configuration file.

DAEMON_CONF="/etc/hostapd/hostapd.conf"

Step 6.5: On some Raspberry Pi units, there is an issue with the entropy used for encryption. Luckily, the pi has a hardware random number generator that’s actually loaded but not used by default. Let’s enable it.

sudo apt-get install -y rng-tools

Step 7: Launch the hostapd service.

sudo systemctl restart hostapd.service

Note: You can check the status by running the following:

sudo systemctl status hostapd.service

Install and Configure DHCP

Step 1: We will install and use dnsmasq.

sudo apt-get install -y dnsmasq

Step 2: Edit the dhcp server configuration file.

sudo vi /etc/dnsmasq.conf

Step 3: Modify the configuration file values to read similar to the values below:

interface=wlan0  
bind-interfaces
server=8.8.8.8
domain-needed  
bogus-priv  
dhcp-range=192.168.13.10,192.168.13.240,12h

Note: Make sure the IP space is the same as what you configured in your /etc/network/interfaces configuration.

Step 4: Restart the service so that it applies our configuration changes.

sudo systemctl restart dnsmasq

Note: You can check to make sure the service is running by executing the following:

sudo systemctl status dnsmasq

Connecting the Access Point to the Internet

Step 1: Turn on IP forwarding and set up iptables.

sudo sysctl -w net.ipv4.ip_forward=1
sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
sudo iptables -A FORWARD -i eth0 -o wlan0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i wlan0 -o eth0 -j ACCEPT
sudo sh -c "iptables-save > /etc/iptables.rules"

Step 2: Edit the network configuration so that the iptables.rules file will load at boot.

sudo vim /etc/network/interfaces

Step 3: Add the following to the bottom of the file.

up iptables-restore < /etc/iptables.rules

Step 4: Edit sysctl so IP forwarding persists:

sudo vi /etc/sysctl.conf

Step 5: Change the config to reflect the following:

net.ipv4.ip_forward = 1

Update OpenSSL

At the time of writing this, OpenSSL 1.0.2 was not in the apt-get repository. Thus, we have to enable jessie-backports.

Step 1: Add the repository for backports to the sources.list.d

sudo vi /etc/apt/sources.list.d/backports.list

Step 2: Add the following line:

deb ftp://ftp.nl.debian.org/debian jessie-backports main contrib non-free

Step 3: Update apt-get.

sudo apt-get update

Note: This will return a couple of key errors. They will look something like this:

W: GPG error: ftp://ftp.nl.debian.org jessie-backports InRelease: The following signatures couldn't be verified because the public key is not available: NO_PUBKEY 8B48AD6246925553 NO_PUBKEY 7638D0442B90D010

Step 4: Resolve the key issues:

gpg --keyserver pgpkeys.mit.edu --recv-key 8B48AD6246925553
gpg -a --export 8B48AD6246925553 | sudo apt-key add -
gpg --keyserver pgpkeys.mit.edu --recv-key 7638D0442B90D010
gpg -a --export 7638D0442B90D010 | sudo apt-key add -

Step 5: Update apt-get again.

sudo apt-get update

Step 6: Install OpenSSL

sudo apt-get install -t jessie-backports -y openssl libssl-dev

Install Python 3.5.x

At the time of writing this, Python 3.5.x was not in the apt-get repository. Thus, we need to download the source, compile, and install.
Step 1: Download Python 3.5.2 Sources:

cd /tmp && wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tar.xz
tar -xvf Python-3.5.2.tar.xz
cd Python-3.5.2
./configure
make
sudo make install

Step 2: Upgrade pip:

sudo pip3 install --upgrade pip

Install mitmproxy

Step 1: Install the dependencies:

sudo apt-get install -y libffi-dev libxml2-dev libxslt1-dev libjpeg8-dev zlib1g-dev libyaml-dev

Step 2: Install mitmproxy.

sudo pip3 install mitmproxy

Note: Do not install mitmproxy with apt-get. It will install a really old version.

Step 3: Change the rules in iptables to enable a transparent proxy.

sudo vi /etc/iptables.rules

Step 4: Change the POSTROUTING section to read as follows:

:POSTROUTING ACCEPT [0:0]
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -i wlan0 -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8080
-A POSTROUTING -o eth0 -j MASQUERADE

Step 5: Reload the rules

sudo iptables-restore < /etc/iptables.rules

Step 6: Run mitmproxy and have some fun!

mitmproxy -T --host

Next Steps

Start experimenting with mitmproxy. You can add scripts to help automate how things run by passing a -s yourscript.py onto the mitmproxy or mitmdump command.

If you so desire, you can configure Raspberry Pi 3 to boot straight into mitmproxy by doing the following:

sudo vim /etc/rc.local

..and add the following line before the exit 0:

/usr/local/bin/mitmdump -T -s /home/pi/yourscript.py &

Important: Be sure to keep the & at the end of your command, or your Pi WILL NOT BOOT!

Hope it helps! If you have issues, leave a comment.

Cheers,

–Adam

Adam Engle

Mobile Security Guru | Hunter | Dog Lover | Droid Collector

9 thoughts to “Raspberry PI 3 + MITMProxy”

  1. Hey Adam! Awesome blog post. I’ve been trying for a while to get MITMproxy working on the Pi and while there’s a fair few articles out there, none are as up to date as yours. And it worked first time!

    If I wanted to route traffic to a second wifi connection (a nano USB wifi adaptor for example) would I just configure the wifi adaptor as standard and change the references above from eth0 to wlan1?

    Thanks again!

  2. Hey Adam,

    I’m developping a hacking station based on RPi as my graduation work. Somehow I can’t get the mitmproxy working in transparent mode. I’ve installed openssl 1.0.2 via jessie backport but I anyways get an error message telling me “HTTP/2 disabled . OpenSSL 1.0.2+ required. ALPN support missing”. I’m not sure what I’m doing wrong.
    I’m using pyenv since mitmproxy requires python3.5 and above and there is only python 3.4 available on the raspberry pi.

    Since not many people have made a tutorial on this and I’ve been looking for hours to find information I’ve decided to ask you, if you could give me some advice.

    Best regards

    1. I recall having issues with that. That is why I added the section on installing python3.5 from source. This should eliminate your issues. Make sure you then use the correct pip (pip3) to install mitmproxy. Let me know if you still have issues.

  3. Will this work on a public university WiFi space?

    What steps could I omit if I just want to use mitmproxy on my Pi to analyse my Pi’s traffic?

    I’ve had a number of issues getting this up and running at home, mainly with configuring the access point, but I believe that was because I had an incorrect OS installed that was messing with my ability to connect to a WiFi. Not really sure, but will be going through the setup again with this fresh install.

    Thank you seriously for this write up, it has been very helpful

    1. Jake,

      I’m glad it was helpful for you. To answer your question, you would omit any of the stuff related to the hotspot. You would then need to configure whatever application (Firefox, etc) to use your localhost as the proxy (make traffic go through MITMProxy).

  4. Thank you for your wonderful tutorial.
    Prior to reading your post I have completed setting up my pi3 with the newest image of 2017-11-29 and as an AP through this tutorial: https://cdn-learn.adafruit.com/downloads/pdf/setting-up-a-raspberry-pi-as-a-wifi-access-point.pdf
    First, because of that reason I have skipped most of your steps until the Update OpenSSL section. I then skipped step 1 and only ran step 2 with this command: sudo apt-get install -y openssl libssl-dev –> everything went smoothly.
    Second, at the Install Python3.5 section I skipped step 1 because the new image provided me with a newer verion of 3.5.3 and I only ran step 2 as the following: “sudo pip3 install –upgrade pip” –> Requirement already up-to-date: pip in /usr/lib/python3/dist-packages
    Third, I jumped to the Install mitmproxy section and followed step 1 to install the dependencies and it was a success.
    Fourth, running step 2 of Install mitmproxy “sudo pip3 install mitmproxy” –> after a series of downloading stuffs I got some kind of errors that I have no clue what they mean (please see the 2 pictures):
    1- https://i.imgur.com/lniqvwi.png
    2- https://i.imgur.com/wFENv1h.png
    Fifth, I moved on to step 3. Since Adafruit recommended to save the iptables rules in “/etc/iptables/rules.v4” instead of “/etc/iptables.rules” so I decided to go for the “/etc/iptables/rules.v4”. Also, I was not sure of step 3 (Change the rules in iptables to enable a transparent proxy) especially it looks like step 3 and 4 are two parts of one big step. In the end, I edited my “/etc/iptables/rules.v4” by adding in 2 lines to make it look like this:
    https://i.imgur.com/AmpPgzk.png
    Sixth, reload the rules as suggested “sudo iptables-restore < /etc/iptables/rules.v4".
    Finally, when I tried to run "mitmproxy -T –host" I got a response "command not found". It looks like the installation did not go through. I don't know what to do next. Could you drop me some hints? Thank you very much.

Leave a Reply

Your email address will not be published. Required fields are marked *