After showing some pretty serious security fails in the Wi-Fi iKettle from Smarter recently (e.g. PSK extraction over Wi-Fi in plain text) we have been eagerly awaiting delivery of their latest products; the Wi-Fi Coffee Machine and iKettle 2.0. The mobile app has had a significant update and the ridiculous static/short PIN bug doesn’t appear to be present. That’s the good news.

Now for some bad news

This post is about attacking the coffee machine in its unconfigured state, so out of the box, powered on, but not hooked up to a mobile app yet. We found in multiple iKettles on wigle.net this state.

The Coffee Machine works as a Wi-Fi access point in unconfigured state, unlike the iKettle which operates as an ad-hoc Wi-Fi device. This makes life a little easier:

DHCP is enabled, the default gateway address is 192.168.4.1. The SSID will be easy to geo-locate on wigle too, once a few have got in to the market.

The iKettle communicates on TCP ports 23 and 2000.

No joy there, so potentially a different Wi-Fi module, not the VSD03 as found in the iKettle.

Turns out it talks on TCP & UDP port 2081, using what appears to be a simple binary protocol. You can detect the port from either a port scan, wiresharking the phone->coffee machine connection or from decompiling the am.smarter.smarterandroid.utils.UDPSocket class in the Android mobile app.

There appears to be a heartbeat or status message broadcast every 5 seconds. (Later investigation showed that this contained details about the status, including the fill level on the water reservoir, number of cups and coffee strength.)

So we had a play around with TCP traffic, using the mobile app code for clues.

It’s a straightforward protocol to work with.

A message is composed of:

<action>[parameters]<tail> <tail> = 0x7e

[parameters] is one or more bytes, depending on <action>

For example: we send the machine 0x64 0x7e, it will respond with 0x65 0x02 0x0d 0x7e.

0x65 is effectively a message reply.

0x02 is the type of the machine (we think the iKettle is version 01, coffee machine is version 02).

0x0d is decimal 13, which correlates with the SDK version of 1.3.0 (see below).

0x7e is likely to be a packet terminator.

Next, we attempt to fuzz the protocol a bit. Sending 0x6A (or the letter ‘j’ if you’re punching your keyboard) generates a response:

BOOM! ‘AT+GMR’ tells us a lot; first that the Wi-Fi module in use is the ESP8266, from the command set. This module is one of the most popular IoT Wi-Fi modules available (probably because it is so cheap). AT+GMR is the command to disclose the firmware version.

The complete command set is available online, here’s an example:

It’s easy to find the messages being constructed in the APK. Here’s a message with decimal 13 being created, sending 0x0d -> AT+CWLAP on the ESP8266, starting a scan for access points.

So, now we know what we’re dealing with, what else can we do?

Here’s the output from the previous message. Hence, we can use the coffee machine to discover Wi-Fi networks. No particular security issue there, but amusing nonetheless! Wi-Fi stumbling by coffee machine?

However, what I want to know is if I can make a cup of coffee unauthenticated. Can I drive past a user’s house and take control of their coffee machine?

Sadly, it’s just too easy:

0x37 or hit number 7 at your terminal and it starts brewing:

Yep, so whilst the user is out, if they haven’t configured the Wi-Fi on their coffee machine, we can have it brew to order. Nasty stale coffee anyone? Empty water container? All the coffee grounds used?

Firmware and DoS attacks

From the AT command set, we also see the ‘Firmware Upgrade’ command: AT+CIUPDATE.

So, we’ll need to intercept / MITM the upgrade process, but it’s trivial to trigger it. Just send it 0x6e or simply hit ‘m’ on your keyboard.

We’re investigating the firmware upgrade mechanism right now (looks like a new socket is created on TCP port 6000 for the purpose), but in the meantime, triggering a firmware upgrade has the lovely effect of factory resetting the Wi-Fi module!

Without a hard reset (user holds down ‘start’ button for 10 secs) the Wi-Fi module won’t operate.

Nice!

We have lots more to do on this project. Here’s a rough list:

#1 fully reverse the protocol, so we have a complete command set. This is easiest by simply reading the APK and figuring out the binary commands for each coffee machine instruction.

More involved is to fully fuzz the command set, as it’s likely that there will be functionality available that’s not used in the mobile app. The AT+GMR command is potentially a case of this, as we can’t locate a request in the mobile app that calls this currently.

Ideally, we’re looking for a way to call AT+CWSAP, which will divulge the users Wi-Fi PSK from the ESP8266

We’ve already found AT+CWSAP being called to set the SSID [0x07] and PSK [0x05], and query the SSID [0x0d] but we haven’t found a way to recover the PSK yet.

#2 read the ESP8266 code and fully understand how it works. Here’s an image of the main board on the coffee machine, complete with the ESP8266 module and two very interesting ports on the left hand side. We struggled to get a read from these, but suspicion is that they’re UART interfaces, or possibly I2C/SPI. Time will tell.

#3 man in the middle the firmware update connection and attempt to grab the new firmware as it’s downloaded, and/or serve rogue firmware to it. It’ll be interesting to see if the firmware has been signed, which may make a big difference to the ease of this attack.

#4 then see if we can carry out the same attack against a configured coffee machine, just like the PSK extraction we showed with the iKettle.

Is there a chance that the coffee machine is secure once configured? Maybe, but based on the iKettle 1.0, I’ll place money on it not being.