Hands On IoT MitM (Part 1)¶
This is the third article in the Hunter Hacking Project.
In How To Quickly Setup A Wireless MitM Proxy, I discussed how to setup a "Man In The Middle" (MitM) proxy using Kali Linux, but what is a man-in-the-middle proxy? What are they used for?
In this article we'll explore MitM proxies using Kali Linux and an Adafruit Feather M0 WiFi module.
The Basics¶
A man-in-the-middle (MITM) proxy is an application or device that intercepts communication between two parties and can eavesdrop, modify, or block data transmission.
In the early days of the internet, before the Let's Encrypt revolution, it was ridiculously easy to insert yourself in between one computer and another: Cain and Abel, ettercap, etherape...
Mainly for lulz, but probably for some nefarious stuff, as well.
Nowadays, unless you're "leet", it's basically impossible to "sniff" a random TLS-secured connection, unless... you have root on one of the devices.
To better understand things, we're going to examine a few scenarios.
Our intention is to understand what is required to intercept traffic between an ATWINC1500-based IoT device and an AWS IoT MQTT endpoint:
-
Basic SSL Connection
By establishing a basic SSL connection, we confirm that our network is configured correctly to allow the microcontroller (uC) to connect to google.com over port 443. We also confirm that the Root Cert Store on the uC contains a Root CA certificate which trusts Google's certificate****.
-
MitM'd SSL Connection
Establishing an SSL connection through
mitmproxy
allows us to understand what happens when an SSL connection is man-in-the-middle'd. Learning how to get things working helps us understand the role that the Root Cert Store plays in the ATWINC1500. -
Basic MQTTS Connection
This scenario allows us to understand how to get AWS IoT configured as an MQTT endpoint. In addition, we learn how how to write TLS certificates to the ATWINC1500.
-
MitM'd MQTTS Connection
This final scenario allows us to understand how insert a... ...
For all of these tests, we'll be using an Adafruit Feather M0 module.
1. Basic SSL Connection¶
The Arduino WiFi101 Library includes the WifiSSLClient
example, which simply connects to an access point and retrieves the google.com
homepages and prints it to the serial terminal.
We can use this example out-of-the-box, with one change. Add the following to your setup()
:
After uploading the sketch to you should see the following:
Troubleshooting¶
Didn't work?
Try adding the google.com
certificate to your ATWINC1500 by following the instructions here: ATWINC1500 IoT Module Deep-Dive (Part 1)#Uploading SSL Root Certificates.
2. MitM'd SSL Connection¶
Now let's run the same example through a transparent proxy, using mitmproxy
.
I'm going to setup my proxy, using the instructions here: How To Quickly Setup A Wireless MitM Proxy#Start Transparent MitM Proxy)
Upload Sketch¶
Update the WifiSSLClient
sketch so that it connects to your proxy and re-run the sketch:
Hrm...
Checking the mitmproxy
logs we see the following:
192.168.1.22:60689: client connect
192.168.1.22:60689: server connect 17.248.180.49:443
192.168.1.22:60689: Client TLS handshake failed. Client and mitmproxy cannot agree on a TLS version to use. You may need to adjust mitmproxy's tls_version_client_min option.
192.168.1.22:60689: client disconnect
192.168.1.22:60689: server disconnect 17.248.180.49:443
192.168.1.3:62014: client connect
192.168.1.3:62014: server connect 142.250.68.68:443
192.168.1.3:62014: Client TLS handshake failed. The client disconnected during the handshake. If this happens consistently for www.google.com, this may indicate that the client does not trust the proxy's certificate.
192.168.1.3:62014: client disconnect
192.168.1.3:62014: server disconnect 142.250.68.68:443
...
This line is of particular interest:
Client TLS handshake failed. The client disconnected during the handshake. If this happens consistently for www.google.com, this may indicate that the client does not trust the proxy's certificate.
mitmproxy
is hinting that something similar to this is happening within the microcontroller's network stack causing the connection to be aborted:
If you recall from How To Quickly Setup A Wireless MitM Proxy, the above error occurs when we haven't installed the mitmproxy
root certificate.
Let's test this hypothesis by installing the mitmproxy
root certificate.
Installing mitmproxy Root Certificate¶
1. Upload Serial Bridge¶
First, we need to install the peddamat/SerialBridge so atwinc1500_fwtool.exe
can talk directly to the ATWINC1500 module over USB.
2. Obtain Certificate¶
You'll need a copy of the mitmproxy
certificate, which you can grab by connecting to bumper_mitm
on your phone and downloading the cert in .cer
format.
Place the certificate in a directory named "certs".
$ tree
.
├── Interm
...
├── atwinc1500_fwtool.exe
├── atwinc1500_fwtool.pdb
└── certs
└── mitmproxy-ca-cert.cer
3. Write Certificate¶
To reduce any confounding variables, let's first erase both stores on our ATWINC1500.
$ atwinc1500_fwtool.exe erase --root
Erasing device...
Root Certificate Store Updated Successfully On: Flash
Confirming:
$ atwinc1500_fwtool.exe read
Dumping Root Cert Store contents...
Root Certificate Store Loaded Successfully From: Flash
- Found 0 entries!
...
Now we let's add the cert to the Root Cert Store:
$ atwinc1500_fwtool.exe update --root --ca_dir certs
Root Certificate Store Loaded Successfully From: Flash
>>>Found Certificate:
>>> mitmproxy
Root Certificate Store Updated Successfully On: Flash
Confirming:
$ atwinc1500_fwtool.exe read
Dumping Root Cert Store contents...
Root Certificate Store Loaded Successfully From: Flash
- Found 1 entries!
Name Hash (SHA1): 14 65 65 22 40 7A D1 30 64 06 9E 87 AD BB C5 31 7D 37 94 FF Certificate 1: RSA
<2023-03-19 20:00:22> to <2033-03-18 20:00:22>
Re-Upload Sketch¶
Re-uploading the Sketch and checking the serial monitor yields in:
Troubleshooting¶
Trouble connecting to your Adafruit Feather M0?
Check to make sure your VMWare Player isn't intercepting the USB device connection request:
3. Basic MQTTS Connection¶
Now that we have a handle of the basics, let's model something more realistic, a scenario where our Adafruit Feather M0 is an IoT device which communicates with an AWS IoT MQTT endpoint.
Before we get started, it's worth spending a moment talking about mutual TLS.
TODO: Tighten up verbiage
Mutual TLS (mTLS) differs from the TLS we've previously done, in that it's a protocol that allows a mutual exchange of keys during session initiation.
What this means is that the "IoT Device" has its own unique public/private key pair, which essentially serves as a username and password when it connects to AWS IoT.
This means...
AWS IoT Setup¶
First, you'll need to create an AWS account by heading over to: aws.amazon.com
Next, scroll down and click the "Connect an IoT device" link under "Build a solution".
This will bring up a "Prepare your device" wizard:
Scroll down and click Next:
Under "Thing properties" enter "feathermitm":
and click Next:
Select "Python" and click Next:
Click Download connection kit and click Next:
Finish by clicking View thing:
Testing¶
Connection Kit¶
Unzip connect_device_package.zip
:
$ tree
.
├── feathermitm-Policy
├── feathermitm.cert.pem
├── feathermitm.private.key
├── feathermitm.public.key
└── start.sh
and run start.sh
in a WSL terminal:
$ ./start.sh
...
Running pub/sub sample application...
Connecting to xxx.amazonaws.com with client ID 'basicPubSub'...
Connected!
Subscribing to topic 'sdk/test/python'...
Subscribed with QoS.AT_LEAST_ONCE
Sending messages until program killed
Publishing message to topic 'sdk/test/python': Hello World! [1]
Received message from topic 'sdk/test/python': b'"Hello World! [1]"'
We can see the messages show up in the "MQTT test client" section:
MQTT Explorer¶
Since we're going to be in MQTT-world for a while, it's worth getting a hang of MQTT Explorer, a tool which lets us pub and sub MQTT endpoints:
Grab the connection settings from start.sh
, populate the host name and port, and then click Advanced:
#!/usr/bin/env bash
...
# run pub/sub sample app using certificates downloaded in package
printf "\nRunning pub/sub sample application...\n"
python3 aws-iot-device-sdk-python-v2/samples/pubsub.py --endpoint xxx.iot.amazonaws.com --ca_file root-CA.crt --cert feathermitm.cert.pem --key feathermitm.private.key --client_id basicPubSub --topic sdk/test/python --count 0
Set the "MQTT Client ID" to "basicPubSub" and click Certificates:
Populate the entries with the contents of the connect_device_package
folder as shown, and click Back (twice):
NOW CLICK SAVE!!!
Then click on "MQTT test client" in the AWS IoT sidebar, enter sdk/test/python
in the Topic filter, and click Subscribe:
Back in MQTT Explorer, click "Connect", enter "sdk/test/python" in the Topic, add a message and click Publish:
Back in "MQTT test client", you should see your message!
IoT Device Setup¶
Now that we've setup and tested our AWS IoT gateway, let's prepare our "IoT device".
Unlike mitmproxy
, IOXY requires some certificate configuration work to get things working.
Write Certificates¶
For the mTLS handshake to work, we're going to need to upload the private key and cert to the ATWINC1500 TLS Server Store and Amazon's RootCA cert to its Root Cert Store.
Start by renaming root-CA.crt
to root-CA.cer
:
Then upload the device's private key and certificate to the TLS Server Store:
$ atwinc1500_fwtool.exe update \
--tls \
--key connect_device_package\feathermitm.private.key \
--cert connect_device_package\feathermitm.cert.pem
TLS Certificate Store Loaded Successfully From: Flash
TLS Certificate Store Updated Successfully On: Flash
Now upload the Amazon Root CA certificate to the Root Cert Store:
$ atwinc1500_fwtool.exe update --root --ca_dir connect_device_package
Root Certificate Store Loaded Successfully From: Flash
>>>Found Certificate:
>>> Amazon Root CA 1
Root Certificate Store Updated Successfully On: Flash
Verifying:
$ atwinc1500_fwtool.exe read
Dumping TLS Store contents...
TLS Certificate Store Loaded Successfully From: Flash
Found 3 entries...
- RSA Certificate Chain File List
NAME SIZE TYPE INFO
PRIV_62a1f32e421df7f65e2290155189f76dbd6953bd 1208 PRIVATE KEY
CERT_62a1f32e421df7f65e2290155189f76dbd6953bd 861 CERTIFICATE AWS IoT Certificate
- Private Key Details:
Modulus (N) :(00B7440C)(256)
A9 34 C5 DD 7F 50 C2 23 90 AA 85 5B DA EC 23 80
09 AB E7 B8 1E 1F 66 1C 37 9E 3A 28 BB 9D 07 6C
AE D9 50 5C 45 D8 F1 5A 09 4A 44 A1 56 1F A6 41
4C B4 20 2D D9 0F 78 68 E7 6E 11 61 94 54 70 13
DF A0 86 38 BC 0F 9E 09 B0 04 39 53 F2 29 35 BF
8E FA 19 97 86 40 74 3C 20 79 B9 0F 2A 1E 7A 01
F5 55 C2 BB CE F6 7A AA 14 48 BB 77 92 AB 0E 6D
C2 FE 6C 62 F6 DD 76 90 63 40 C8 58 2F 4F D6 B1
87 09 CF C7 40 34 24 E7 26 C1 BB 29 F5 45 C1 7D
75 4D 79 4A C0 F7 78 FA EA 7F 3F 44 DA F8 BE D0
17 3D 9E FF 0C BF F9 B6 C4 06 5F 12 88 7C C2 9F
B8 82 D3 E2 21 A9 73 72 AC 09 9B 2B 4F 91 8A 2D
E6 5F A0 83 73 82 56 5D 4E 6C 85 A9 43 87 74 81
2A B3 47 D5 E2 18 F8 39 FC 66 1A 5B D2 C4 06 24
CC 4C 0E BF 49 2A 90 3D 0F 47 12 16 52 F0 5E B7
4A 3E F4 76 02 6E 64 C0 16 0B 14 A7 93 90 58 99
- TLS Certificate Details:
Subject <AWS IoT Certificate>
Issuer < >
<2023-03-23 12:47:18> to <2049-12-31 23:59:59>
Dumping Root Cert Store contents...
Root Certificate Store Loaded Successfully From: Flash
Found 1 entries:
1) RSA Certificate: 5/26/2015 [00:00:00] to 1/17/2038 [00:00:00]
Name Hash (SHA1): A8 66 80 C4 56 27 2E AF E3 A7 CE 2E 49 D1 31 DC 65 BB B1 ED
Upload Sketch¶
The Arduino Cloud Provider Examples
Library includes the AWS_IoT_WiFi
sketch, which can be used to connect to the AWS IoT Gateway.
Install it by opening the Library Manager and search for "Arduino Cloud":
Now, open the AWS_IoT_WiFi
sketch:
Alternatively, use the PlatformIO code here: peddamat/AWS_IoT_WiFi
Compiling and uploading the sketch results in:
Voila!
You should see this in the "MQTT test client" console:
Next Steps¶
Ok, as usual, things have gone way longer than expected, so we'll leave the grand finale to the next part, here: Hands On IoT MitM (Part 2).
Troubleshooting¶
Having issues connecting to IOXY from MQTT Explorer?
You can check to see if your firewall is blocking connections between your machine and your WSL container by launching a Python web server on each port, and checking accessibility via a web browser.
Having issues with the atwinc1500_fwtool update command?
You can debug the atwinc1500_fwtool.exe binary by opening the solution in Visual Studio 2022 and:
Links¶
- Connecting a device to AWS IoT Core by using the AWS IoT Device SDK
- AWS IoT and Adafruit WICED Feather
- Building an AWS IoT Core device using AWS Serverless and an ESP32
- Securely Connecting an Arduino MKR WiFi 1010 to AWS IoT Core
- MicrochipTech/aws-iot-winc1500-secure-wifi-board-included-source-files
- https://github.com/peddamat/winc