WiFi Hacking Week Pt. 4 — Evil Twin Attacks

DJ Nelson
InfoSec Write-ups
Published in
9 min readApr 18, 2022

--

but don’t actually…

If you are reading this that means you’ve either made it to the fourth post in this series on WiFi security, you accidentally clicked this link, or you’re simply curious about the practical ways in which one might create a malicious WiFi access point for the purpose of man-in-the-middling a wireless internet connection. If you haven’t read the previous articles and feel you need some background info feel free to start here. In this blog post we will be walking through exactly how an attacker could configure a rogue device as a malicious access point and surreptitiously implant it in a network in order to capture traffic and carry out malicious attacks.

The scenario we are outlining is one where a malicious actor has configured a Raspberry Pi ahead of time to connect to the real network and operate as an access point with a benign name that wouldn’t cause anyone to think twice about connecting to it in order to access the internet. A Raspberry Pi — or other single-board computer — is perfect for this scenario as they are cheap, easy to set up, and are small enough that they could be hidden from scrutiny by interested parties. Exactly how one would conceal a device like this is outside of the scope of this article. I’ll leave that up to you to think creatively when imagining this scenario taking place in the real world. If you don’t have a Raspberry Pi, no worries. You can follow along just as readily using your own Linux computer. It is important to note that for this to work, you will need a secondary wireless network interface. I’m using an Alfa AWUS036NEH, but feel free to use whatever you want as long as it’s firmware is Linux compatible and it supports monitor mode. If you don’t know what that means feel free to see a previous article I wrote on some more basic concepts.

Going fishing

The first thing we are going to tackle is getting our device set up to act as an access point. None of this is magic. All we are doing is turning a Linux-based computer into a router. I chose to connect my Raspberry Pi to the local testing lab (my living room) WiFi network with it’s built in wireless card in order to make it feel more realistic. If you want to get this up and running quickly feel free to plug into your home router, just know that in a real attack scenario the attacker would likely be connecting the implant to the internet via WiFi, or 4G using an external 4G dongle.

Ok, let’s cover some basic definitions so it’s not confusing to follow along. These are the interfaces we will be working with.

wlp4s0 — connected to the real access point, and thus the internet
alfa — the interface the evil twin will broadcast it's network on
mon0 - a virtual interface we put into monitor mode (optional)

I’ll start by connecting the Raspberry Pi — let’s call it EvilAP — to the real access point. If you just plugged in directly to your router you can skip this part.

# sudo wpa_supplicant -i wlp4s0 -c /etc/wpa_supplicant/demo.conf
# sudo dhclient wlp4s0

Now, this step is optional, but if at some point later you want to be able to actively deauth local clients in hopes of getting them to reconnect to your EvilAP, then you will need an additional interface that you can set into monitor mode. Seeing as our alfa interface will be operating in master mode, we can spawn a virtual interface off of the alfa interface and set it to monitor mode.

# iw alfa interface add mon0 type monitor

Now we have an interface named mon0 which will behave just like a physical dongle. If necessary, you could use this one to sniff packets and deauth clients while the other interfaces are tied up in their affairs. Ok, now let’s do some routing configuration for our external WiFi adapter.

# sudo ip link set alfa up
# sudo ifconfig alfa 192.168.88.1 netmask 255.255.255.0
# sudo route add -net 192.168.88.0 netmask 255.255.255.0 gw 192.168.88.1

All we did here is configure the default route and gateway for our EvilAP network. I chose the subnet 192.168.88.0/24, but you could chose whatever private subnet range you’d like as long as it’s not the same as the subnet range your EvilAP is currently connected to.

We will also need to make sure traffic can flow freely between the EvilAP network and the regular network by configuring some IPtables firewall rules.

# iptables -F
# iptables -X
# iptables -A FORWARD -i alfa -o wlp4s0 -j ACCEPT
# iptables -A FORWARD -i wlp4s0 -o alfa -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
# iptables -t nat -A POSTROUTING -o wlp4s0 -j MASQUERADE

and if it isn’t already configured…

# sudo -s 
# echo 1 > /proc/sys/net/ipv4/ip_forward

All we did there is allow forwarding of traffic between alfa and wlp4s0, as well as allow NAT routing so that all packets leaving the alfa interface for the wlp4s0 and out will be “masqueraded” as packets originating from wlp4s0. Then, if it wasn’t previously configured, we allowed packet forwarding at the kernel level, otherwise nothing would actually pass through. At this point your EvilAP is configured to act as a basic router — allowing traffic to pass freely in between the evil access point interface, and the interface which is connected to the real network.

Configuring the necessary services

Next we will be utilizing the services of two utilities: dnsmasq and hostapd. Both of these services have default configuration files, but you can just as readily create brand new ones and store them wherever you like, as long as you call them appropriately when we start these services

dnsmasq.conf

interface=alfa
dhcp-range=192.168.88.10,192.168.88.100,255.255.255.0,12h
dhcp-option=3,192.168.88.1
dhcp-option=6,192.168.88.1
server=1.1.1.1
server=64.6.64.6
log-queries
log-dhcp
listen-address=127.0.0.1

hostapd.conf

interface=alfa
country_code=US
driver=nl80211
ssid=EvilAP
hw_mode=g
channel=6
macaddr_acl=0
auth_algs=1
ignore_broadcast_ssid=0
wpa=2
wpa_passphrase=eviltwinpass
wpa_key_mgmt=WPA-PSK
rsn_pairwise=CCMP
ieee80211n=1
wmm_enabled=1

Just remember to adapt the interfaces and DHCP options if yours differ from mine. Note that the ssid line is the name of the access point that your EvilAP will broadcast. So… if for some strange reason my article is the one you chose to learn from for your wifi pentesting gig, I encourage you to change the name to something less conspicuous.

Let’s start ’em up.

# hostapd -B ./hostapd.conf
# dnsmasq -C ./dnsmasq.conf

At this point everything should be up and running. Congratulations! You’ve successfully turned your Linux box or single-board computer into a functioning access point. Feel free to open up the Wi-Fi settings on your phone and see the EvilAp access point broadcasting it’s not-so-secret presence.

Better Bettercap Usage

Why do I say better? Initially I had follow a certain resource which told me to install a version which turned out to be rather useless and out of date, so be sure to follow the official docs when installing this handy tool.

Our evil access point isn’t very evil if all it does is allow clients to connect to it. That’s where Bettercap comes in. Bettercap is an extremely versatile and easy-to-use tool which enables security enthusiasts, professionals and reverse engineers (and some other folks) to perform various wireless reconnaissance and offensive attacks against WiFi and bluetooth networks.

To get started, we attach Bettercap to our EvilAP’s broadcasting interface so we can see the activity that takes place there.

# bettercap -iface alfa
> net.sniff on
> net.show
Have fun with OSINT, kids

We start Bettercap on our EvilAP interface, turn on network sniffing capabilities, and then we take a look at what’s currently on the network. Your output may vary depending on what’s running in your own lab, but it’s likely that you will see a handful of devices that you recognize. If you haven’t yet, feel free to pick up your phone and connect to EvilAP or whatever you decided to call the network.

Once you do, you’ll see some traffic come through as the new device connects. Exciting right?

By the way, if you want to simplify your Bettercap usage a bit, create a file called eviltwin.cap with these contents:

net.sniff on
net.probe on
net.show
set net.sniff.output output.pcap

That last one just directs bettercap to dump all captured traffic to a file called output.pcap. Then you can just run it with one command.

# sudo bettercap -iface alfa -caplet eviltwin.cap

Fishing with dynamite

Ok, this is cool and all, but not every is just going to willingly connect to your network. There are a few ways to handle this, and a couple of them are effective, but rather loud. We’ve covered one in previous posts. This is the reason we set up the mon0 interface earlier. If you were so inclined and you wanted to catch a few fish (or a ton, depending on certain factors), you could essentially blast them off the network they’re connected to currently. Provided that your network name is the same as the one they were just on, and you are closer to them or have some other way of providing a stronger signal then the network they were on before, they may automatically reconnect to your evil twin network.

# aireplay-ng --deauth 50 -a <GoodAPMAC> -c <GoodAPChannel> mon0

Obviously replace <GoodAPMAC> and <GoodAPChannel> with the actual access point and channel of the network you’re throwing dynamite into. You effectively spam the network with deauth packets kicking everything off that you can come in contact with.

This. Is. LOUD. More then likely you wouldn’t do this in a real engagement. If you are trying this at the local bar, then do look forward to being embarrassed when the WiFi-connected jukebox indiscreetly announces to everyone who was enjoying those country tunes that it has been disconnected from the internet. Hopefully your Alfa card with the big antenna wasn’t flashing too much. Instead of throwing dynamite into the river, you could just shoot an arrow.

#  aireplay-ng -0 1 -a <ap_MAC> -c <client_MAC> alfa

It’s much less noisy and there’s a possibility that they won’t notice, but there’s a chance the client will be miffed that they were mysteriously disconnected from the internet for a second. In some cases the client might catch on that something is amiss.

While we are talking about noise, the net.probe entry you added into eviltwin.cap tells Bettercap to constantly probe the network looking for connected hosts. It’s not the same as deauthing them, but it’s not stealthy either. So choose when to use that behavior wisely.

So I can haz passwords?

Nope. Not yet, silly. We haven’t even started a proxy for the HTTPS traffic yet. Go ahead and do that now at your Bettercap prompt.

> https.proxy on

You can see that Bettercap is using a default TLS certificate for it’s proxy. I’m not going to go into a long explanation of what TLS certificates are or how they work as there are plenty of publicly available resources that would do a much better job then me of explaining them. Basically, your browser has a store of verified authorities which tell it which certificates are good to trust with the encryption of the user’s traffic as it flies over the network. So the second your unwitting client tries to visit a website enabled with HTTPS (almost all of them), they will see a glaring warning issued by their browser that looks something like this.

You can simply hope they’ll go the brave traveler route and click the little Show Details button so they can visit the site anyway, dashing caution to the wind, but it’s unlikely. The only way to bypass this is to get them to install the illegitimate Bettercap certificate in their browser’s trust. Or is it?

Wrapping Up

That’s all for now. In upcoming posts we will go over captive portals as well as some modern ways that attackers steal credentials, session tokens, and even bypass 2FA.

When testing all of this I ended up starting, restarting, and reconfiguring multiple times in order to verify that things worked, as well as fix things that I borked. There ends up being a lot of typing and repetition so to make it easier I wrote a little bash script which wraps many of these steps into easy to run commands

https://github.com/djislucid/wiTk

It’s not perfect (it’s bash after all), but it’s usage is pretty straightforward and allows you to go from nothing to a completely functional evil twin setup in a matters of seconds, save for some initial configuration. I also hope it serves as a learner tool as you can inspect the code and see which commands facilitate which step of the process. Feel free to fork, clone, or do whatever you want with it. Stay safe out there.

--

--

Sharing my passion for the world of hacking and bug bounty hunting, and their relation to my unique adventures and experiences.