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

terminal

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:

methods

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 )

flashing the firmware