Let try something new, #FridayAnecdote

First one will be a small fun story I had as developer is the time I wanted a cat feeder machine to help me with the gluttony of Newton, my cat.

This story is about #InternetOfThings, #Security and #ReverseEngineering.

A Thread.

The story begins early January 2018.
After month of Gluttony after I've had Newton neutralized; I decided to separate the Human/Food factor in the head of my cat.
He's cute, but having him craving for food all the time and only asking for it wasn't really fulfilling my dreams of petting him.
Plus, I was convinced that having him to have more small portions along the whole day instead of big meals two times a day.

That's why I bought a connected pet feeder machine : HoneyGuaridan S25

My experience with the machine is fairly good. I can now plan up to 10 meals a day, with reasonably small portions; and I can also trigger extra meal at any moment with an App.
This very same App is also used to configure the meal plan, and check the machine status.
But something is bothering me a bit: the #iOS App is bad designed, and totally bugged.

Biggest bug was a cell reuse bug on the feeding plan form. Come on guys!

But I'm like "Hey, it's a simple App, I can do that as long as I know how the Rest API works".
So I plugged a proxy to intercept the app requests…

First red flag: the Api domains:
fr.dev.alnpet.com and us1.dev.alnpet.com
What?
I'm communicating with dev servers … from a production app?
Does production servers exists?
And who is AlnPet? Since I buyed a HoneyGuardan machine!

Second red flag: Calls are being made over HTTP.
Why bother with TLS? Come on, it's 2018 already, like Let's Encrypt is 4 years old already.
My password, and anything like authentication token or session could leak or be intercepted by an attacker.

Then ... something else started bothering me…

Something very weird was occurring in the requests I was intercepting:
There was no sign whatsoever of an authentication token of any sort … or a session cookie…
That's right … there is NO authentication in my requests…
That cannot be right …
So I try to load a random profile by injecting a random ID.
It printed an email ; and a feeder ID.
I triggered a meal on that feeder ID.

It printed "OK". I guess a cat or a dog somewhere was happy with my gift 😜

At this moment, I kinda panicked.
I opened the app ; replaced my email by a dummy one ; made sure my password was unique (it was).
And right after, I unplugged my feeder machine.

I wasn't sure about how to remove the setting Wi-Fi of the machine yet.
Before plugging it again, I wanted to know a little bit more about how it worked ; and if possible, control the way it would behave with my network.
I needed to understand exactly what I had plugged to my Network.

As my network uses #PiHole it was easy enough to find what DNS the Feeder Machine was resolving in my logs.
It was requesting only one DNS at all, just one: alnpet.net and it was resolving to the 47.90.203.137.
It's the same domain than the app API was using.

So I took my first resolution to protect myself on my network: banning the IP:

Then I added a rule to resolve alnpet.net locally. It's time to find how my machine is communicating with the external world.
Because of course, if there is a button to trigger manual meals, I cannot trigger remote meal, or even update feeding plans since it's offline.
And cherry on the cake: as the day passes, the planned meals are shifting a few minutes on the original plan.
How could it be?
Scanning for TCP and UDP my machine was triggering ; I found out it was trying to do only one thing:
Open a websocket, on the IP 47.90.203.137 and port 9999.
Ok.
So I booted a very small node.js app, exposing a websocket server on port 9999 ; and resolved the alnpet.net domain with my mac IP.
And I got messages … every 10 seconds or so
Ok, nice.
I started another socket ; but a client this time, and I connected to the real live socket from alnpet.net, and sent them this message every 10 seconds just to try.
And I got an answer ; that was evolving every 6 messages. Wait, … would that … be the time? 🤔

I let the script run for a day, with timestamps in the logs.
And turns out it goes from 9da1060105a0 to 9da106010000.

5a0 converts to 1440 = 24 x 60.
So the websocket provide the time … every ten seconds … with a precision of a minute 😬

I connect a very simple NodeJS code to mimic this behavior ; and convert the hour to hexa.
And now my machine stopped shifting into time. OK, progress 😝

With more back and forth, and using the original app to trigger some orders to the machine,
I was able to identify all the message sent by the socket to the machine, and the responses the machine would send to specific orders.
Feeding, Setting plan, Meal button was pressed, etc…

I understood that the machine was sending identification message, with it's internal ID.
And the answer was the time, in Toronto Timezone.
When sending an order, the machine would answer back with its ID and a suffix.

And I started building a whole replacement API ; with my own endpoints on top of that knowledge.
The first version of that API was a poc on top of NodeJS. It was creepy code.
But last year, alnpet.net stopped working. I guess they stopped to pay for the bills.
Plus, turns out that Alnpet was a Canadian company that tried to create Pet feeding machines, but when bankrupt before commercialization.
My guess is that Alnpet tech was spoofed by a Chinese company, and then sold around the world.

I decided I would build something cleaner ; and for everyone.
At the time, I was learning #Symfony for my job at #DiliTrust.
Say Hi to https://github.com/Dean151/Aln-Symfony

By the way, #Symfony is really neat to work with, this new API in less than two weeks of free time worth to build.

GitHub - Dean151/Aln-Symfony: A pure PHP Symfony implementation to replace alnpet.com API

A pure PHP Symfony implementation to replace alnpet.com API - GitHub - Dean151/Aln-Symfony: A pure PHP Symfony implementation to replace alnpet.com API

GitHub

Open source, and with a lot of test coverage, Aln-Symfony is a good mockup, and secure API to communicate with existing machines around the world.
So people who would get locked out of their machine would start using it again.
It's hosted for convenience on my server, with a SwaggerUI to perform the requests: https://api.feedmypet.app

I'd love to use some of my free time to build a small webapp ; or an App on top of this Api.
But free time is precious, and I have a lot of other side projects 😜

Aln-Symfony - API Platform

Thanks for reading this first #FridayAnecdote and see you next week!
@deanatoire it was really interesting, thanks for sharing! Is the cat eats better with this machine?
@Pierrodu21 he’s still craving for more food, and might sometime try to make us press the manual meal button.
But at least it removes the « food based relationship ». 😝
@deanatoire Amazing story. As we are discovering with social networks, relying on companies which may go away or change direction or whatever is ... well your anecdote speaks both to the problem and maybe gives some idea of what open source can do and also that it doesn't just appear without someone(s) having the time/money to make it, host servers, etc.