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.
Going in, I had a few high level goals:
- I’m working at home, but I don’t trust the devices. They shouldn’t impact the rest of my home network.
- The analysis environment shouldn’t contain any of my personal data, like my Google Account.
- I need the ability to capture packets between a smartphone and an IoT device.
- I need the ability to Man-in-the-Middle DNS, HTTP and HTTPS for both the smartphone and the device.
- 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.
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 firstname.lastname@example.org 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
“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
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
opkg update and
opkg install tcpdump did
With that in place, I can Wireshark the wireless traffic from the router using the remote Wireshark trick:
Interestingly, it also seems possible to dump raw WiFi (802.11b/g) beacons by doing:
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.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
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
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
18.104.22.168 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
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.
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
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.
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!