MITM Tutorial

I see many people asking to add some random device to homeassistant. It can be a lot of fun to add your own device and give back to the community. It takes a few hours of learning, but if you are smart enough to run homeassistant, you can definitely do it! First, you learn how to control the device and second you make a homeassistant integration. This guide will cover the first step. I am not expert, I learned trying to make an integration. Maybe an integration developer could add a tutorial to build a simple integration (the much harder step IMHO). Except for the AwesomeLight integration, I have not found many basic examples to learn from.

It is always best to have local control over the device, but if you have some random WiFi device and it has an iOS or Android App, it probably has a cloud API. This guide covers how to figure out a cloud API. Many manufacturers do not publish their API, but you can figure it out by inspecting traffic from their android app. You could use a real android device, but this tutorial uses the official android emulator.

Here are some directions for Windows. I assume if you use linux, you can figure out how to modify directions. Please edit this post to improve the directions.

Get and Android studio: https://developer.android.com/studio
Get and install mitmproxy: https://mitmproxy.org/
Get Windows Subsystem For Linux: https://learn.microsoft.com/en-us/windows/wsl/install
Get Windows Terminal: https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701?hl=en-us&gl=us

Make a new folder on your desktop. type “wsl” (no quotes) in the address bar and it will start a shell in this directory

type mitmproxy.exe so it sets everything up. Press q , then y to quit

Install apk-mitm: https://github.com/shroudedcode/apk-mitm
npm install -g apk-mitm
May need to sudo apt install openjdk-11-jdk nodejs and a few other things to allow the install to work. People who try a fresh install, please edit for other packages that are required.

copy “C:\Users\YOUR_USER_NAME.mitmproxy\mitmproxy-ca-cert.pem” to this directory on your desktop
Download whatever Android app you want to play with. Get from apkpure.com or any other place you like and download into this directory.

Inject your mitmproxy certificate into the APK. This keeps the app from knowing we are intercepting the traffic. It will take a few minutes to run and rebuild a “AppName-patched.apk” app.
apk-mitm --certificate mitmproxy-ca-cert.pem AppName.apk

If it says you an error about a bundle, then you may need to edit the system certificate.

Start to Android Studio, click “More Actions”, Click Virtual Device Manager
Click Create Device
Click any device you want that DOES NOT have the playstore icon.
Click next and select a system image. Pick a recent one, x86_64 images will work the best
start your image

click back in your WSL terminal and start mitmproxy and save the flows to a file “test.mitm”
mitmproxy -w test.mitm

Once the android emulator is loaded
Click the 3 dot menu in android studio toolbar
Click settings on bottom left
Click the proxy tab at the top of window pane
Select manual proxy, enter the IP address of your computer running mitmproxy (your IP address, port 8080) and click apply. You should see it say success. If not, try again.

Drag the “Appname-patched.apk” right into the phone simulator window and it should install. I suggest you create an account previously on a real app.
Swipe up on the emulated phone home screen to see all the apps, click the app and login and play around.

You should see the mitmproxy windows fill up. Only data from the app should be readable by mitm proxy. If the data is not readable, you need to do a much more complicated procedure to inject your mitmproxy certificate into the system store.

**** If patching the App does not work ***
If you do not see flows and/or get connection errors, patching the app did not work or the app relies on the built-in browser to make a connection. This means you need to make the Android system accept your mitm certificate. This is a pain! The below work for Android API above 28. Based on these directions: https://docs.mitmproxy.org/stable/howto-install-system-trusted-ca-android/

This step you do once:
Open wsl in the directory with your mitmproxy-ca-cert.pem

hashed_name=openssl x509 -inform PEM -subject_hash_old -in mitmproxy-ca-cert.cer | head -1 && cp mitmproxy-ca-cert.cer $hashed_name.0

this should make a file named xxxxxxxx.0 where x are numbers and letters. Replace with name in below steps.

These next steps you need to do each time you do a hard reset of the emulator:
start a cmd shell (not a wsl shell)
C:\Users\YOUR_USER_NAME\AppData\Local\Android\Sdk\emulator\emulator -list-avds
it should list some name of your emulator, like “Pixel_2_XL_API_31”
start the emulator in writable mode:
C:\Users\YOUR_USER_NAME\AppData\Local\Android\Sdk\emulator\emulator -avd Pixel_2_XL_API_31 -writable-system

start a new cmd shell (not a wsl shell)

adb root
adb shell avbctl disable-verification
adb reboot

(wait a moment for emulator to reboot)

adb root
adb remount
adb reboot  (if asked to reboot)

(wait a moment for emulator to reboot)

adb root
adb remount
adb push xxxxxx.0 /system/etc/security/cacerts
adb shell chmod 664 /system/etc/security/cacerts/xxxxxx.0
adb reboot

Now, you should see the flows from all the apps.

If you close the emulator, you can easily restart it and not have to repeat the above process:
C:\Users\YOUR_USER_NAME\AppData\Local\Android\Sdk\emulator\emulator -avd Pixel_2_XL_API_31 -writable-system

If you start it via the GUI or do a hard reboot, you have to repeat all the commands. Like I said, a pain!
**** End if patching the App Does not work ***

Click around in mitmproxy and you should see what is sent and what the responses are from the cloud. You should be able to trace whatever functions you need, starting the login all the way to turning off/on the lights, etc. You can click on a line in mitmproxy and hit “e” to export each step to a “curl” file, enter a filename to save it. After you capture all the data, quit mitmproxy and the android emulator. You can always review the data by running “mitmproxy.exe -r test.mitm”

If you are not a professional with python requests: Take the curl file you exported and load it into something that makes a python code for you, like https://curlconverter.com/

Learn (eg. google!) python and how to manipulate json to print the response out and string together input/output multiple calls to achieve what you want. Next, turn this python code into a homeassistant integration!

Note, if chrome does not load in the emulator, put a file called:
C:\Users\YOUR_USER_NAME\.android\advancedFeatures.ini
with the following contents:

Vulkan = off
GLDirectMem = on
7 Likes

The above may still work, but I now find Frida to work more reliably. No need to push the certificate to the android store, no need to patch the apk.

This link will give you the basics: https://www.bomberbot.com/proxy/unlocking-android-app-traffic-a-practical-guide-with-mitmproxy-and-frida/

A reliable pinning script is: akabe1/frida-multiple-unpinning
use line:
frida --codeshare akabe1/frida-multiple-unpinning -U -f com.microsoft.bing