A Simple Home IoT Lab

In 2019, I’m planning on poking at a lot of IoT devices. Seeing as this was the first weekend of the year, I spent some time setting up a flexible analysis environment. The plan was to get as much configuration out of the way as possible for common attack patterns.

Architecture

Going in, I had a few high level goals:

  1. I’m working at home, but I don’t trust the devices. They shouldn’t impact the rest of my home network.
  2. The analysis environment shouldn’t contain any of my personal data, like my Google Account.
  3. I need the ability to capture packets between a smartphone and an IoT device.
  4. I need the ability to Man-in-the-Middle DNS, HTTP and HTTPS for both the smartphone and the device.
  5. It should be made using spare parts I already own, so I have a better chance of understanding the whole stack and can save a bit of cash.

To satisfy these goals, I came up with the following architecture:

  • A SOHO router, running a separate WiFi network, a firewall, and DHCP+NAT for a new subnet that can also capture packets.
  • An unused android tablet that can have new random crapware installed on it.
  • An unused laptop that can can run DNS/HTTP/HTTPS servers and other analysis tools.

Router

The router I chose was a an old Linksys WRT54Gv.3 from 2004. It runs a full Linux install on its 16MB of RAM and 4MB of flash. This series of routers is the namesake for the OpenWRT project because they were some of the first SOHO routers that could be flashed with custom Linux firmware. I’ve used a handful of them over the years for various projects - the one I’m using for this I acquired at MIT Swapfest for $5. I think it used to be used for something similar, because the WAN port is labeled “internet” in quotes.

The OpenWRT wiki has a page about the WRT54G series that is quite detailed. The version I have is limited to an OpenWRT release from 2010, but that’s mostly a non-issue for this task. I was able to flash OpenWRT version 10.03.1 “Backfire” with minimal fuss using the TFTP method.

root@kali:~# ssh root@192.168.2.1


BusyBox v1.15.3 (2011-11-24 04:30:44 CET) built-in shell (ash)
Enter 'help' for a list of built-in commands.

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 Backfire (10.03.1, r29592) ------------------------
  * 1/3 shot Kahlua    In a shot glass, layer Kahlua 
  * 1/3 shot Bailey's  on the bottom, then Bailey's, 
  * 1/3 shot Vodka     then Vodka.
 ---------------------------------------------------
root@OpenWrt:~# 

My main home network resides in 192.168.1.0/24, so for this endeavor I decided to allocate 192.168.2.0/24. The “WAN” port of the lab router is plugged into one of the switch ports of my primary router, and receives an IP address via DHCP in the 192.168.1.0/24 range for the WAN interface (this is the default). On the LAN side, I assigned a static IP address 192.168.2.1 to the router, and let it assign addresses in the 192.168.2.100-192.168.2.150 range via DHCP.

The default configuration for OpenWRT is to bridge the LAN Ethernet ports and the WiFi interface, which is what I want here too. I configured the WiFi to run a WPA2 network with a passphrase, so that random people can’t join it!

The router runs a DNS server by default, but in this setup it is only used by the router itself. For DHCP assignments, the router hands out a DNS server of 192.168.2.2 which is one of the IP addresses of the laptop (described later).

One of my goals (#1) is that the analysis subnet should be isolated by a firewall. Because NAT is the greatest firewall ever invented, I only have to worry about outbound packets from the lab network.

The easy way to do this would be to for the lab router to drop incoming LAN packets that were destined for 192.168.1.0/24. Unfortunately, the OpenWRT build I’m using is so old that it doesn’t support this. Specifically, you can’t set net.bridge.bridge-nf-call-iptables=1 because the sysctl doesn’t exist (it’s compiled out for performance reasons). This prevents using iptables rules on bridged interfaces. I’m not really interested in compiling OpenWRT myself and the only sensible configuration for the LAN is to bridge the Ethernet switch and WiFi interfaces, so I have to find an alternative. Until I do, I’ll just have to live with the inbound filtering only.

OpenWRT has a full suite of packages available via it’s opkg tool. The only package I needed to install was tcpdump, so that I could monitor traffic as it flows through the router. Because this version of OpenWRT is no longer supported, to get the repositories to work, I had to modify the opkg config to change downloads.openwrt.org to archive.openwrt.org, but after that opkg update and opkg install tcpdump did the trick.

With that in place, I can Wireshark the wireless traffic from the router using the remote Wireshark trick:

ssh 192.168.2.1 /usr/sbin/tcpdump -w - -i wlan0 -B 16 | Wireshark -k -i -

Interestingly, it also seems possible to dump raw WiFi (802.11b/g) beacons by doing:

ssh 192.168.2.1 /usr/sbin/tcpdump -w - -i mon.wlan0 -B 16 | Wireshark -k -i -

Laptop

The Laptop I’m using is an HP 250 G5 Notebook with an i3-6006U CPU @ 2.00GHz processor and 8GB of RAM. I picked it up on sale at Microcenter a year or so ago for a different project, and it’s pretty nice for the price point. I installed the most recent version of Kali Linux, which comes with all the goodies you need for pentesting.

The laptop thankfully has a proper Ethernet port, and is plugged directly into a LAN port on the router. The laptop is assigned two static IP addresses - 192.168.2.2 and 192.168.2.3. The first is used for running a DNS server, and the second is used for HTTP/HTTPS. Because the laptop doesn’t connect to the lab network via WiFi, capturing on the wlan0 interface won’t include the laptop’s traffic.

As mentioned above, the laptop runs the DNS server for DHCP clients. Importantly, the laptop doesn’t get it’s DNS server configuration via DHCP, and instead uses 8.8.8.8, which prevents it from intercepting it’s own queries! For the DNS server, I’m using dnschef which is a DNS proxy server built into Kali. It has a simple configuration file format, which lets you override specific records for domains. The upstream DNS server for this is also 8.8.8.8 for any records it doesn’t override.

[A]
example.com=192.168.2.3
*.example.com=192.168.2.3

This redirects A record results for example.com and subdomains to 192.168.2.3, which is the secondary IP address of the laptop, and is listening on port 80 with Apache and PHP (which are installed by default in Kali). This provides an incredibly easy mechanism to Man-in-the-Middle HTTP traffic.

I haven’t 100% gotten the HTTPS interception working yet, but I have all the pieces in place. The right tool for the job is Daniel Roethlisberger’s sslsplit, which is a bit like Moxie’s sslstrip on steroids. I can also generate a CA that I can load as trustable on the Android device, so that it will fully trust the HTTPS proxy.

Tablet

The tablet I had lying around was a spare Samsung Galaxy Tab 4 (M-T230NU). Unfortunately, it can only run Android 4.4.2 (KitKat, from 2013) so in the future if I have to use a newer version of android I’ll need to scrounge up a newer device or use AVD.

I factory reset the device, which I had previously rooted using the these instructions. The important part is that it has TeamWin Recovery Project (TWRP) installed on it, so it’s relatively easy to factory-reset it and/or flash new firmware. The Android rooting community is a bit strange - debugging some of this ends up being a lot of trial and error. When I was just doing the factory reset process I got stuck in a few bootloops until I found the right key combos to break out.

The tablet is connected to the testnet WiFi network and gets it’s IP address via DHCP. Because of this, it’s DNS queries go through the laptop’s DNS server, and can be redirected by the laptop. The tablet’s traffic is also included in any pcaps taken over the router’s wlan0 interface.

I connected the table to the laptop via USB for android debugging via ADB. This gives the laptop full shell and debugging access to the device, including the ability to read and write files, so it’s pretty convenient for passing data back and forth.

I also made a separate Google account on the tablet so I could access the Play Store and google services without it being attached to my personal info. Google still seems to support the registration workflow on this tablet from 2013 which I was pleasantly surprised about.

Conclusion

The final lab in its native habitat

The biggest things I have left to do are outbound packet filtering and HTTPS MITM setup I mentioned before. Both are relative generic things, so I want to do them sooner rather than later.

I think my best shot at the filtering is just to bite the bullet and recompile the OpenWRT kernel with CONFIG_BRIDGE_NETFILTER=y. Hopefully this won’t be too bad because the install is so minimal anyway.

For the HTTPS MITM setup, I just need to go through the process of generating the certs and setting up port forwards. This will also be easier if I can use iptables rules on the router for transparently intercepting all port 443 traffic, so that’s another argument for recompiling OpenWRT.

I’d like to get something working for doing Bluetooth stuff, but I don’t know much about it. The laptop and the tablet both have Bluetooth interfaces, so I expect I have all the hardware to do sniffing/spoofing but I need to figure out how to configure it. At the very least, I’d like to know how to capture a pcap of the session between the Android device and an IoT device.

For now though, this setup should be sufficient to start understanding the attack surface of a few devices at the very least. I’m pretty happy with what I was able to get set up in just one weekend!