Operatie Smart Kettle

Afgelopen zaterdag zag ik tijdens het boodschappen doen een wifi-gestuurde "Smart Kettle" bij de aanbiedingen. Dit deed me denken aan de HTTP-statuscode 418 "I'm a tea pot", die als 1 april-grap is geschreven, waarna ik hier een grapje over plaatste op Mastodon.

De nieuwsgierigheid won het uiteindelijk van het verstand en ik kocht een van deze hightech apparaten om water te koken. Omdat ik nog geen projecten had gedaan of had gehackt aan wifi-gestuurde IoT-apparaten, had ik geen idee hoe het werkte of wat ik kon verwachten. Mijn eerste gedachte was dat de smartphone-app rechtstreeks communiceert met de slimme waterkoker, waarop een soort server of API zou draaien waar men mee kon communiceren.

Eerste stappen en configuratie

Eerst heb ik de basis van de waterkoker aangesloten op de netstroom en op de wifi-knop gedrukt. Hij gaf een pieptoon, knipperde en — wie had dat kunnen raden — hij maakte zijn eigen open access point aan.

Ik kon hiermee verbinden, maar het apparaat verdeelde geen IP-adressen via DHCP. Voor de volgende poging installeerde ik de Lidl Smart Home App op mijn smartphone en doorliep ik de initiële installatie. Hier voerde ik mijn wifi-gegevens in; ik verbond met de eigen wifi van de waterkoker waarlangs de gegevens werden overgedragen. Na wat gepiep verbond de waterkoker met mijn wifi en was hij beschikbaar in de app.

In de app heb ik de fantastische opties om de watertemperatuur voor het koken in te stellen en een tijd voor het warmhouden. Ook worden er enkele vooraf gedefinieerde "programma's" of temperaturen voor verschillende soorten thee aangeboden. Daarnaast worden de status van de waterkoker en de watertemperatuur weergegeven. Er staat onderaan een kalendericoon, maar het is niet mogelijk om een kookbeurt in te plannen.

Netwerkanalyse

Dankzij de melding van mijn fritzbox over nieuwe apparaten op het netwerk had ik het IP-adres al in handen. Hiermee voerde ik een nmap-scan uit om te zien wat er op de waterkoker draaide.

Er was één poort open, TCP 6668, maar nmap kon niet identificeren wat hierop draaide. Ik probeerde een banner te grijpen via netcat:

nc 192.168.178.70 6668

De verbinding kon worden tot stand gebracht, maar ik kreeg geen banner terug die hints gaf over wat er draaide. Ook het bezoeken van http://192.168.178.70:6668 of https://192.168.178.70:6668 in de browser mislukte. Dat zou te makkelijk zijn.

Man-in-the-Middle aanval

Als volgende stap probeerde ik een nep-access point op te zetten voor een man-in-the-middle aanval, om te zien welk verkeer er tussen de smartphone en de waterkoker stroomt. Hiervoor gebruikte ik een Kali VM met een aangesloten Alpha USB wifi-dongle. De wifi van het host-OS is verbonden met de VM als bekabeld netwerk op eth0.

Ik schakelde de Network Manager service uit, aangezien deze de handmatig ingestelde IP-adressen op de interfaces overschrijft:

sudo systemctl stop NetworkManager.service

Vervolgens configureerde ik een vast IP op eth0 en stelde ik de standaardroute in naar de home-router (fritzbox):

sudo ifconfig eth0 192.168.66.129/24 up sudo route add default gw 192.168.66.2 eth0

Daarna stelde ik een vast IP in op wlan0:

sudo ifconfig wlan0 10.0.0.1/24 up

Ik stelde iptables-regels in om verkeer van wlan0 naar eth0 door te sturen:

sudo sysctl -w net.ipv4.ip_forward=1 sudo iptables -P FORWARD ACCEPT sudo iptables --table nat -A POSTROUTING -o eth0 -j MASQUERADE

Hierna configureerde en startte ik de DHCP-server.

dnsmasq.conf:

interface=wlan0
dhcp-range=10.0.0.10,10.0.0.250,12h
dhcp-option=3,10.0.0.1
dhcp-option=6,10.0.0.1
server=8.8.8.8
log-queries
log-dhcp

fakehosts.conf:

127.0.0.1 test.de

sudo dnsmasq -C dnsmasq.conf -H fakehosts.conf -d

Vervolgens configureerde en startte ik de AP-service.

hostapd.conf:

interface=wlan0
driver=nl80211
ssid=fake
channel=1

sudo hostapd ./hostapd.conf

Ten slotte startte ik Wireshark en begon ik te luisteren op wlan0. Met het nep-wifi netwerk ingesteld, resette ik de waterkoker en voerde ik de initiële installatie in de app opnieuw uit. Deze keer configureerde ik hem om de nep-wifi te gebruiken. En kijk aan: de installatie werkte en ik kon het verkeer van de app en de waterkoker zien.

Resultaten en ontdekkingen

Tot mijn teleurstelling kon ik geen direct verkeer zien tussen de app en de waterkoker. Er was alleen verkeer naar IP-adressen in de Azure-cloud. De waterkoker verbindt regelmatig met de cloud via een TLS 1.2-versleutelde verbinding, waarbij hij naar mijn vermoeden de status doorgeeft en probeert nieuwe commando's op te halen.

Mijn volgende gedachte was: hoe kunnen we de TLS-verbinding verbreken om te zien wat er gebeurt? Aangezien we de man-in-the-middle/access point zijn, zouden we de waterkoker een vals certificaat kunnen sturen, zodat we het verkeer kunnen ontsleutelen en vervolgens weer versleuteld met de publieke sleutel van de Azure-server naar de cloud kunnen doorsturen. Ettercap of Bettercap zou dat kunnen, maar dat heb ik uiteindelijk niet geprobeerd.

In plaats daarvan deed ik een snelle MAC-adres lookup om te zien wie de wifi-module had gebouwd: Tuya. Een nieuwe naam, dus ik vroeg het aan Google. Daar ontdekten we tuya.com, wat een grote "IoT-as-a-service" provider lijkt te zijn. Je kunt apparaten bouwen met hun modules of kant-en-klare producten, daar je eigen logo op plakken, een besturings-app samenstellen en de Tuya-cloudservers als backend gebruiken. Als je een wifi-IoT-apparaat in je hand hebt, is de kans vrij groot dat het van Tuya is.

Wat bleek? Er is een volledige ontwikkelaarsdocumentatie beschikbaar over de hardware, API en meer: https://developer.tuya.com/en. Het lijkt erop dat zij geen HTCPCP spreken.

Dankzij reacties op mijn bericht (bedankt Zach) leerde ik dat het mogelijk was om de wifi-controller via OTA-firmware te flashen om er een "bevrijde" firmware op te zetten, zodat hij zonder de Tuya-cloud kan werken. Maar het lijkt erop dat mijn apparaat te nieuw is hiervoor:

Conclusie

Dit kleine avontuur in IoT-hacking eindigt met een teleurstellende noot. Geen direct verkeer tussen app en waterkoker, geen webservice op de waterkoker om mee te communiceren, geen implementatie van HTCPCP en geen foutmelding 418.

Misschien kunnen we leuke dingen doen direct met de hardware? Maar dat is voor een volgend klein avontuur!