Reversing the Smarter Coffee IoT Machine Protocol to Make Coffee Using the Terminal.
I love coffee, that’s a fact, and I drink liters of it during the week … I also am a nerd and a hacker, so a few days ago I bought a Smarter Coffee machine on Amazon, basically a coffee machine that you can control over your home wifi network using a mobile application ( both for Android and iOS ).
The app is really nice: you can set the amount of cups you want, the strength of the coffee, etc, then you only need to press a button and wait for your delicious coffee to be brewed.
Since I work from home, most of the times I’m using the computer keyboard, not a smartphone, therefore I wanted/needed a console client for it, something that the vendor never released, so I started reversing the Android application in order to understand the communication protocol and write my own client implementation … guess what? :D
Yep, i can make coffee using the terminal now :D
Reversing the Protocol
I decided to reverse the Android application since it’s usualy way easier than reversing iOS ones ( java vs assembly :D ), once I downloaded the APK I started studying the various classes and methods.
So I fired up JADX ( with the --show-bad-code
argument ), I launched CTAGS inside the exported source code folder and VIM to navigate it.
A few hours later, I found the interesting part in the am.smarter.smarterandroid.models.a
class and noticed a few methods like the following:
Each of these “packets” is sent to tcp port 2081
of the machine, the protocol is very simple.
- First byte: the command number.
- Second byte to N: optional data ( depending on the command code ).
- Last byte: always
0x7e
which indicates the end of the packet.
Responses can vary, but for most of the commands they are:
- First byte: response size
- Second byte: status ( 0 = success otherwise error code )
- Last byte: always
0x7e
.
An example command and response, the one to keep the coffee warm for 5 minutes for instance, would be:
COMMAND : 0x3e 0x05 0x7e
RESPONSE : 0x03 0x00 0x7e
So I’ve mapped all the commands I needed in order to write a minimal console client and tested it … this is the result, it works like a charm! :D
You can download the client code here, you’ll need to specify the machine ip address the first time, then it will be saved in the ~/.smartercoffee
file and won’t be needed anymore.
coffee make -A 192.168.1.50
A few examples:
Just make one cup of coffee:
coffee make
Make two cups using the filter instead of the beans in the grinder:
coffee make --filter
Keep coffee warm for ten minutes:
coffee warm --keep-warm=10
Full usage
☕ ☕ ☕ SmarterCoffee Client ☕ ☕ ☕
by Simone 'evilsocket' Margaritelli
Usage: coffee [options] (make|warm)
Options:
-h, --help show this help message and exit
-A ADDRESS, --address=ADDRESS
IP address of the Smarter coffee machine.
-M, --make Make coffee.
-W, --warm Warm coffee.
-C CUPS, --cups=CUPS Set number of cups.
-S STRENGTH, --strength=STRENGTH
Set coffee strength ( 0-2 ).
-G, --grind Use grind.
-F, --filter Use filter.
-K TIME, --keep-warm=TIME
Keep the coffee warm for TIME minutes.
Security Considerations
Even if the mobile app requires you to register an account, access to port 2081 is completely unauthenticated ( in fact, I’ve found that the user account is only used for statistics using the Firebase API ), anyone on your network could access it and even flash a new firmware with no authentication required ( I reversed the UPDATE_FIRMWARE
packet as well but you won’t find it on the repo :P )