Wi-Fi Mini Honeypot

Do you have an old, unused wireless router collecting dust? Have some fun and make a Wi-Fi honeypot with it!

Recently, I've been playing with some new wireless gear. It's nothing special: 200mW Atheros-based transceiver and 18dBi yagi antenna. I'm living in an apartment in a city of about 640,000 people. I've pointed the antenna to a window and passively received about 30 wireless ESSIDs, three of which were unsecured (open) and six secured with WEP (easily crackable). I haven't connected to any of them, of course, but that gave me some ideas.

What if I deployed a wireless access point deliberately open? Some people eventually will connect and try to use it for Internet access—some might be malicious, and some might think that it's a hotspot. And, what if I deployed a similar access point, but secured with easily crackable WEP this time? Well, in my humble opinion, it's not possible to unconsciously crack WEP. If somebody that I don't know connects to this AP, I've just been attacked. All I need to do is to monitor.

That's exactly a wireless honeypot: fake access point, deliberately unsecured or poorly secured and monitored, so you can get as much information about attackers as you want. Such honeypots are especially useful in large networks as early threat indicators, but you also can play with them on your home network, just for fun and research.

You can build a wireless honeypot with old hardware, some spare time and, of course, a Linux-based solution. OpenWrt and DD-WRT are the two most popular Linux-based firmware projects for routers. I use them and some old spare routers in this article to show you how to build three kinds of honeypots: a very basic one that logs only information about packets sent by users into its memory, a little more sophisticated one with USB storage that logs a few more details about malicious clients to the storage, and finally, a solution that redirects HTTP traffic through a proxy that not only can log, but also interfere with communication.

Basic Honeypot with DD-WRT

Building a very basic wireless honeypot shouldn't take you more than an hour or two. Just grab your old router and pick up the firmware. Be sure to look at supported routers for both DD-WRT and OpenWrt. In my case, it came up that the router is supported only by DD-WRT, as it has 32MB of RAM and 4MB of Flash memory. OpenWrt's hardware requirements are a little bigger.

Next, flash your router (that's the risky part). Basically, you need to download the firmware for your machine and upload it to the memory. On some routers, it's as easy as clicking a button on the Web interface. On others, you have to connect through a serial cable, for example. Remember, this step can be dangerous. Make a backup first and be sure to read the instructions carefully on the DD-WRT/OpenWrt sites.

After successfully flashing your router, you should see an enhanced (as compared to the original one) Web interface. Now, set up SSH access and wireless network parameters. If you don't know how, you can find detailed instructions on the DD-WRT home page. As it is going to be a honeypot, I would suggest WEP, which should attract potential attackers. At the same time, it won't be so vulnerable to false positives—people with devices automatically connecting to an open network.

If you can log in as root and see the prompt, you're ready for the next step: enabling system logging. You can do this using the Web interface: Services→Services→System Log and Security→Log Enable (Figure 1).

Figure 1. Enabling System Logging

You also can set a few ESSIDs instead of just one: Wireless→Basic Settings→Virtual Interfaces. After that, your honeypot will be seen as a few networks—at least at first glance. This increases the probability of attacks, especially when there are many other networks in your neighborhood.

Remember, you don't have to connect your honeypot to the Internet. In fact, you shouldn't, as you have no control of what potential users might do with the Internet access. After configuring it as described above, test whether it logs your connections. DD-WRT writes the log in /var/log/messages by default. You can check it using SSH. Here's an example fragment of such a log:

Jan  1 00:43:03 orange user.warn kernel: ACCEPT IN=br0 
 ↪OUT= MAC=00:26:5a:a1:bc:86:00:0c:f1:11:43:0e:08:00 
 ↪SRC= DST= LEN=84 TOS=0x00 PREC=0x00 
Jan  1 00:43:04 orange user.warn kernel: ACCEPT IN=br0 
 ↪OUT= MAC=00:26:5a:a1:bc:86:00:0c:f1:11:43:0e:08:00 
 ↪SRC= DST= LEN=84 TOS=0x00 PREC=0x00 

If you can see your packet info logged, just leave the router and wait, looking at the log from time to time.

Unfortunately, with such small resources, you can't do much more—at least within a few hours. This basic honeypot would log only packet headers, IPs and MAC addresses. You can see how a ping command is logged in the previous example. Generally, all the information you can collect is when somebody with a specified MAC and IP try to use your network—that's not much.

Logging Associations to USB Storage with OpenWrt

You can build a little more-advanced wireless honeypot with OpenWrt. Using it, you'll be able to log not only packets, MAC addresses and IP addresses, but also wireless associations, authentications, disassociations, deauthentications and timestamps. With a little effort, you also can expand your honeypot logging capabilities to use USB storage—that gives you a lot more space for logs.

My second router has 32MB of RAM, 8MB of Flash memory and USB support. On such hardware, you easily can install OpenWrt in a similar way as DD-WRT. Detailed instructions are available on the OpenWrt site. After installing it, setting up a wireless access point and logging in via SSH as root, you need to install a few more packages.

First, you'll need USB storage support:

opkg update
opkg install kmod-usb-ohci
opkg install kmod-usb2
insmod usb-ohci
insmod usbcore
insmod ehci-hcd

Now, after connecting a pendrive, dmesg should show it to you, for example, as /dev/sda. Make a directory for mounting your storage: mkdir /storage. Then mount it: mount /dev/sda1 /storage. You'll use it later for gathered data.

Next, you must decide what traffic to log. Let's assume you want to log all traffic forwarded by the router. To do this, use netfilter and iptables: iptables -I FORWARD -j LOG, just as you would do in a typical Linux distribution.

Listing 1 shows an example fragment of a log stored on the pendrive. It was generated by the user associating, authenticating, requesting IP through DHCP and connecting to google.pl:80.

Listing 1. Example Log Generated with OpenWrt and Stored on a Pendrive

Oct 15 10:17:01 white daemon.info hostapd: wlan0: 
 ↪STA 00:0c:f1:11:43:0e IEEE 802.11: authenticated
Oct 15 10:17:01 white daemon.info hostapd: wlan0: 
 ↪STA 00:0c:f1:11:43:0e IEEE 802.11: associated (aid 1)
Oct 15 10:17:01 white daemon.info hostapd: wlan0: 
 ↪STA 00:0c:f1:11:43:0e WPA: pairwise key handshake completed (RSN)
Oct 15 10:17:03 white daemon.info dnsmasq-dhcp[1106]: 
 ↪DHCPDISCOVER(br-lan) 00:0c:f1:11:43:0e
Oct 15 10:17:03 white daemon.info dnsmasq-dhcp[1106]: 
 ↪DHCPOFFER(br-lan) 00:0c:f1:11:43:0e
Oct 15 10:17:03 white daemon.info dnsmasq-dhcp[1106]: 
 ↪DHCPREQUEST(br-lan) 00:0c:f1:11:43:0e
Oct 15 10:17:03 white daemon.info dnsmasq-dhcp[1106]: 
 ↪DHCPACK(br-lan) 00:0c:f1:11:43:0e red
Oct 15 10:17:14 white user.warn kernel: IN=br-lan OUT=eth0.2 
 ↪SRC= DST= LEN=60 TOS=0x00 
 ↪PREC=0x00 TTL=63 ID=59445 DF PROTO=TCP
 ↪SPT=49958 DPT=80 WINDOW=14600 RES=0x00 SYN URGP=0
Oct 15 10:17:14 white user.warn kernel: IN=eth0.2 OUT=br-lan 
 ↪SRC= DST= LEN=60 TOS=0x00 
 ↪PREC=0x00 TTL=51 ID=6488 PROTO=TCP SPT=80 DPT=49958 
Oct 15 10:17:14 white user.warn kernel: IN=br-lan 
 ↪OUT=eth0.2 SRC= DST= LEN=52 
 ↪TOS=0x00 PREC=0x00 TTL=63 ID=59446 DF PROTO=TCP
 ↪SPT=49958 DPT=80 WINDOW=229 RES=0x00 ACK URGP=0
Oct 15 10:17:14 white user.warn kernel: IN=br-lan 
 ↪OUT=eth0.2 SRC= DST= 
 ↪LEN=200 TOS=0x00 PREC=0x00 TTL=63 ID=59447 DF PROTO=TCP
 ↪SPT=49958 DPT=80 WINDOW=229 RES=0x00 ACK PSH URGP=0
Oct 15 10:17:15 white user.warn kernel: IN=eth0.2 OUT=br-lan 
 ↪SRC= DST= LEN=52 TOS=0x00 
 ↪PREC=0x00 TTL=51 ID=6489 PROTO=TCP SPT=80
 ↪DPT=49958 WINDOW=106 RES=0x00 ACK URGP=0
Oct 15 10:17:15 white user.warn kernel: IN=eth0.2 OUT=br-lan 
 ↪SRC= DST= LEN=561 TOS=0x00 
 ↪PREC=0x00 TTL=51 ID=6490 PROTO=TCP SPT=80
 ↪DPT=49958 WINDOW=106 RES=0x00 ACK PSH URGP=0

This honeypot is a little more advanced, although you still don't have much control over user activity on the Internet. You either shouldn't connect the router to the Internet, filter the traffic with iptables and/or set up a proxy between your router and the Internet. Or, you can set up a proxy on your router!

OpenWrt and Tinyproxy

If your machine has enough resources, you can go one step further and use a proxy on your router. With this, you will be able to monitor, filter and modify HTTP traffic. Squid is an example of full-blown proxy solution. If you have a router that is capable of running it, go ahead. If you (like me) don't, you'll have to stick with a solution with fewer requirements. An example of such a solution is tinyproxy. To install tinyproxy in your OpenWrt, run:

opkg update
opkg install tinyproxy luci-app-tinyproxy

Then, configure and run it with:

uci set tinyproxy.@tinyproxy[0].enable=1
uci commit
/etc/init.d/tinyproxy enable
/etc/init.d/tinyproxy restart

From now on, your tinyproxy should listen by default on port 8888 on your localhost. You can check this with the netstat command. Since you want to accept connections not only from localhost, but also from LAN, you'll have to change the configuration a little bit. Also, in our case, it's better to run it in so-called stealth mode—that means no added headers in HTTP. You can find the tinyproxy configuration in the /etc/config/tinyproxy file. Listing 2 shows an example of such a configuration. Notice that logfile is specified to be in the /storage directory, which is our pendrive. Another important option is list 'Allow'. These are the IPs that are allowed to connect to the tinyproxy. You should specify your LAN network or a part of it.

Listing 2. Tinyproxy Configuration with Domain Filtering, Stealth Mode and Custom Log Localization

config 'tinyproxy'
        option 'User' 'nobody'
        option 'Group' 'nogroup'
        option 'Port' '8888'
        option 'Listen' ''
        option 'Timeout' '600'
        option 'DefaultErrorFile' '/usr/share/tinyproxy/default.html'
        option 'StatFile' '/usr/share/tinyproxy/stats.html'
        option 'Logfile' '/storage/tinyproxy.log'
        option 'LogLevel' 'Connect'
        option 'MaxClients' '100'
        option 'MinSpareServers' '5'
        option 'MaxSpareServers' '20'
        option 'StartServers' '10'
        option 'MaxRequestsPerChild' '0'
        list 'Allow' ''
        list 'Allow' ''
        option 'ViaProxyName' 'tinyproxy'
        option 'DisableViaHeader' '1'
        option 'FilterDefaultDeny' '1'
        option 'Filter' '/storage/filter'
        list 'ConnectPort' '443'
        list 'ConnectPort' '563'
        option 'enable' '1'

Tinyproxy also lets you filter requests by domain. You can specify a blacklist or a whitelist of domains in the Filter file. In our configuration, this is '/storage/filter' Also, here we notify tinyproxy to treat this file as a whitelist (FilterDefaultDeny 1), meaning that requests only for specified domains will be allowed. That way, you can forbid attackers from accessing the Internet with their browsers or let them access only specified domains. An example of a /storage/filter file could be:


That would let them visit only the Linux Journal Web site.

Keep in mind that this will block only HTTP requests; all the other traffic will be allowed if you haven't blocked it elsewhere.

Finally, you must tell your router to forward all HTTP traffic to your new proxy. As usual, you can do this with iptables, but first you need to install the iptables-mod-nat-extra package:

opkg install iptables-mod-nat-extra
iptables -A PREROUTING -t nat -p tcp --destination-port 80 
 ↪-j REDIRECT --to-port 8888

From now on, all HTTP requests should be forwarded through tinyproxy and logged to /storage/tinyproxy.log. Listing 3 shows a fragment of such a log. You can see what connections the user tried to make and what has been filtered by the proxy.

Listing 3. tinyproxy.log

CONNECT   Oct 22 16:17:59 [1242]: Connect (file descriptor 7): 
 ↪crimson.lan []
CONNECT   Oct 22 16:17:59 [1242]: Request (file descriptor 7): 
 ↪GET / HTTP/1.1
NOTICE    Oct 22 16:17:59 [1242]: Proxying refused on filtered 
 ↪domain "www.google.com"
CONNECT   Oct 22 16:18:05 [1243]: Connect (file descriptor 7): 
 ↪crimson.lan []
CONNECT   Oct 22 16:18:05 [1243]: Request (file descriptor 7): 
 ↪GET / HTTP/1.1
CONNECT   Oct 22 16:18:05 [1243]: Established connection to host
 ↪"www.linuxjournal.com" using file descriptor 8.
CONNECT   Oct 22 16:18:06 [1244]: Connect (file descriptor 7): 
 ↪crimson.lan []
CONNECT   Oct 22 16:18:06 [1244]: Request (file descriptor 7): 
 ↪GET /pixel/p-a3K3N6enFe9wA.gif HTTP/1.1
NOTICE    Oct 22 16:18:06 [1244]: Proxying refused on filtered 
 ↪domain "pixel.quantserve.com"
CONNECT   Oct 22 16:25:52 [1246]: Connect (file descriptor 7): 
 ↪crimson.lan []
CONNECT   Oct 22 16:25:52 [1246]: Request (file descriptor 7): 
 ↪GET / HTTP/1.1
NOTICE    Oct 22 16:25:52 [1246]: Proxying refused on filtered 
 ↪domain "www.google.com"

When tinyproxy filters a connection request, it displays an information page describing what happened. You also can make use of this to hide tinyproxy's presence or to inform or deceive your attackers (or make a joke). The Web site template is in /usr/share/tinyproxy/default.html. You can see a slightly modified version of this in Listing 4 and Figure 2. This doesn't tell users about tinyproxy and the reason for seeing this page; instead, it politely informs them that they shouldn't use this network for Internet access.

Figure 2. Web Site Template

Listing 4. tinyproxy.html

<?xml version="1.0" encoding="UTF-8" ?>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
{clienthost} <br /><br />
You shouldn't use this network for web access.

Go with the Evolution

The next step in the evolution would be a full-blown wireless honeypot. You can make one using a machine that can run a typical Linux distribution. Then install, for example, dionaea, use a wireless card configured to run as an access point and forward all traffic to your localhost, on which the attacker will see fake services.

Remember, if you want a really good honeypot, make sure that it looks as close as possible to reality. That means, for example, that you might use some dummy clients just to simulate traffic. Or, use WPA instead of WEP. It all depends on your environment.

Also, it is important to be familiar with your country's laws. Make sure it's not prohibited to sniff your attackers' data. Think about whether it's wise to make an Internet connection available for them. Maybe it would be better not to connect your router's WAN port to anything at all, connect it to your machine simulating the Internet or connect it to the Internet but filter the traffic with iptables?

Finally, don't be discouraged by the DD-WRT or OpenWrt systems. They are based on Linux and are very similar in use, but because of the small resources available, they're stripped down. There are no manual pages and slightly different utilities that you may know from you Linux distribution, even though they are named the same. And, the documentation isn't always accurate. If you have any problems, both projects' wikis are very helpful.

And, last but not least, have fun building your solution and (especially) with browsing the collected data!

Load Disqus comments

Community Events

Park City, UT, USA
New Orleans, LA, USA
Copenhagen, Denmark
Austin, TX, USA
Austin, TX, USA