vendredi 27 janvier 2017

Reverse engineering the Eken Android App: Part 1: the overview

So, I just got that awesome H8R.

After a couple tests to confirm everything was fine, I went to try the android "Ez iCam" app that would allow me to control the cam remotely.

Slight disappointment here, as the app was marked "Not compatible with your device" on all phones and tablets I tried it with.
Weird, especially since my phone is neither that old nor uncommon.

But that wouldn't be a problem.
I decided to reverse engineer the app to see what it was actually doing, so I can reimplement all its functions in my own python scripts or cli tools, so I could remotely operate my cam in any setup I'd see fit.

In this first post, I'll show you a basic overview of what I discovered, what the various communication blocs and protocols are,  and what it means for us, wishing to make our own/better tools to interact with the H8.

Part 1: Accessing the camera

This is the easy part.
We already know the camera app operates over WiFi, so let's just press the corresponding button on it to enable WiFi connectivity.

The camera operation mode, is that it becomes a wifi access point itself, rather than joining an existing network.
This makes sense for in the field operation, as you most likely won't have your home AP with you in the wild.

First surprise here, however: the wifi network doesn't seem to use any encryption.
But this also makes sense for ease of use in considered use cases.
Just remember that because of that, and the lack of any additional pairing procedure, anybody around you will be able to access all the camera data trivially while you operate its wifi. (Read on to discover how easy it will be).

Part 2: Studying the app's communications : acquiring the data.

So, how do we proceed now to study the actual app ?
As always with reverse engineering, you want to maximise the bang for the buck in your approach.
So let's first try whatever is simple and might give the best reward/effort ratio.

For this initial approach, we will simply run the app and use every function once, while recording all exchanged data with a packet sniffer.

Since the communications are unencrypted, we could potentially sniff over the air from any other third device other than the phone or the camera itself (obviously).
But sniffing wifi over the air is always error prone, even in controlled test environments. Packet loss is a real issue in a third party sniffing setup.

Given the tools at hand, I chose to rather use a Nexus tablet, with Nethunter installed on it.
(Nethunter is a mobile phone/tablet port of the Kali Linux penetration testing operating system to Android.)
That way, I can run the App on the tablet, and intercept all its communications locally in a reliable manner.

Once the sniffer is up and running, we simply fire up the application, follow the setup instructions, and use it a bit, trying to use most options at least once (obtain steaming, start and stop a recording, take a picture, change settings, show and download files...)

After we are confident we probably got all we needed, we stop the capture.

Thanks to the magic and power of python, recovering the capture file from the tablet to our main pc is a simple matter of running "python -m SimpleHTTPServer" on the tablet , and then pointing a browser to tablet_ip_addr:8000 from our studying PC.

We can now load the baby into Wireshark, to have a more visual representation of what happened there.

Looks way better doesn't it? Come on, bear with me, it's not as frightening as it looks.


Part 3: Studying the app's communications : acquiring birdeye view.

So what do we learn from this capture ?
A quick review easily sets the ground for most of the things we will need to know.
But let's not get ahead of ourselves here, and just study the communications bit by bit and see what we got.

What we see first is a pretty common sequence of joining a network:

Packets 87 to 94, show a familiar sequence where the tablet asks for an IP address (packet 87) once it has joined the network.
The camera seems to also behave as a DHCP server to provide said IP (which is also what one would expect from a regular access point).
After verifying that the IP address is not in use on the network(packets 88 to 91), the camera offers IP to the tablet (packet 92), which in turn accepts it (packet 93).

At this point we've learned that:
- The camera acts as an access point.
- The camera acts as the DHCP server, providing network addresses to hosts.
- The cameras' own IP seems to always be (see packets 92 & 94)

Great. At this point both devices have performed basic network setup and can start exchanging data.

What happens here is more interesting.
We can see that the app then initialises a TCP connection to cameras IP, on port 15740 (packets 101,104 and 105 show the classic TCP 3-way handshake initialisation sequence.)

As both target port number and Wireshark protocol analysis suggest, this corresponds to the PTP/IP protocol.

PTP is the "Picture transfer protocol", which is a standard protocol used to control cameras over USB.
PTP/IP is the transposition of this protocol to the IP world, allowing to use it over simple TCP/IP connections.
Incidently TCP port for this protocol is 15740, which happens to be the same as the ISO standard number for PTP. How convenient.

This is great news. Knowing we will have to deal with a known protocol will considerably shorten reversing and interoperability development times, as we will be more likely to find libraries and tools already made for that.

At this point the vast majority of the capture is PTP communications, where the app and cam seem to exchange configuration options, orders, and notifications. The Wirshark dissector for the protocol is quite spartan in its current state but that's enough to globally understand what's going on. (As you'll find out, Wireshark really isn't to blame for the relatively poor  PTP decoding support.The various manufacturers are free to implement part of the messages as they see fit, leading to a a big mess of unstandardised messages that are rarely documented. Wireshark already provides detailed dissectors for many of the main manufacturers, it just turns out nobody submitted a detailled one for this specific camera yet.)

But we will keep detailed interpretation and exploration of this protocol for later, because for now, other very interesting things start to pop up in the capture.

By scrolling further down, the following snippet catches the eye:

Packets 378 to 399 (and further) shows how the application opens a new connection to camera TCP port 554.
This port corresponds to RTSP, the RealTime Streaming Protocol.
This protocol is as its name implies, commonly used for streaming applications.It's often seen in security cameras, drone FPV setups etc...
It's pretty obvious at this point that this is what the app will use to request the realtime image feedback that goes to the applications' viewfinder.

Great! That seems like another easy to interpret and interface with part.
We can see how in packets 381 389 and 396, the app requests information, sets up a streaming "track" and starts to receive corresponding information.
After a never-ending stream of "JPEG MESSAGE"s  which correspond to the actual data (we will prove that later) , we can see how the app properly closes the stream in the following screenshot:

Common tools and libraries also exist to interface with this protocol.Meaning that the realtime image acquisition part of talking with the H8 will most likely be trivial.

Is there anything juicy left in this capture ?

After more and more of scrolling through a shitton (that's a metric measuring unit for all of you free people of America) of "JPEG MESSAGE"s, we land on this little gem:

What does it say ?
Pretty much what it written on it.
Those few packets show how the Application opens a simple good old FTP connection to the camera, and starts retrieving a picture. (And indeed, "download"-ing a picture was one of the last things I tested on the app.)
That's another trivial way for us to interface with the camera, since recovering, and deleting pictures and videos from the device will be as simple as opening an FTP connection to it.

At this point you can also notice that through the magic of old unsecure cleartext protocols, we can easily intercept the username and password that the application uses to connect to the camera FTP server.

How cute.
A hardcoded, user=password combination, sent over cleartext.
I wonder why even bother at this point.An anonymous connection would have had the exact same level of security against eavesdroppers, since all of this is sent over an unencrypted wifi connection in every direction anyway.
Remember how I warned you against potential media theft at the start of the article ?
This is the meat of it.
Anybody within wifi range while you are operating the camera could simply fire up FileZilla and connect to your cam with those hardcoded, static, unchangeable and now publicly documented credentials and steal or erase your media files.

So be sure to remove (or massively add) your dickpics from there before using the wifi option in unknown places. For a source of fun pics to add to your cam, and share with potential thieves, why not try the wikipedia's hostfile example ?

But I digress.

Part 4:The takeaway

So what have we learned from this easy but informative reversing session?

- Interaction with the camera seems to be based on mostly known protocols, for which common tools exist that will allow us to write custom controlling apps or scripts.
- Camera control/configuration/information seems done through the PTP/IP protocol.
- Realtime streaming from the camera to the app's viewfinder is done through the RTSP protocol
- Plain old FTP is used to retrieve media files from the camera.Meaning that backups, or other such tools will most likely be trivial to implement. 

In the next article, we will explore each of those aspects in more detail just to be sure no unexpected shortcomings pop up.

I'll catch you there!

Bonus / teaser :

The camera app offers configuration options that are not available from the camera menus .

The app offers an "Automatic White Balance" setting.That is not available from the camera interface.

This means that the cameras might have other undocumented features that could be available and useable through PTP/IP.
We will have to investigate those further in an upcoming article.

5 commentaires:

  1. Great info! But I have a different Eken camera, so how can we do this on a H8 Plus (ambarella a12) camera?

    1. Hi,

      I haven't worked on making the third party tool for rtsp streaming yet.
      Indeed, just accessing the RTSP stream straight on in VLC crashes the camera on my side.

      Your capture looks slightly different from mine.
      Playback on my device happens at rtsp://IP/MJPG?W=720&H=400&Q=50&BR=5000000/

      Also other articles I've found on streaming those cameras through VNC all instruct to first start and close the android app, and THEN start streaming through VNC.
      Maybe some kind of setup happens out of band in the previous steps with the other protocols (Or maybe the simplistic state machine in those embedded devices just gets confused by streaming requests incoming without all other "proper" setup steps the app takes.)
      Some people also have reported steraming to work directly using the above URL instead of the "/live" one , even without running the app first. So you might want to try that as well.

      Making it actually work is supposed to be my next article, but I really did not have time to work on it since the original post yet.

      As a starting point I'll probably try to spot the differences in parameters between the app traffic and that generated by VLC.

    2. Hey man! This is such an awesome guide. Would love to email and ask you a few questions, even if you haven't written a follow up blog post yet.

      Have you figured out any way to trigger the camera via command line or yet.

      I got the stream working. I got Ftp working. I know that GOPRO basically uses an URL link with specific parameters that allow you to take photos.

      It must be the same here too, I just need to find out what those are.

      Would love any additional advice. Your replies will go straight to my email! Thanks again man!

  2. Hello there, very good article! Just bought a H9R because of the live streaming feature and wanted to reverse-engineer the EZ iCam app for making a decent desktop streaming app for cams like this (it seems the current build has the facebook/youtube streaming feature broken).

    For this model at least, the app tells the camera to connect to a tethered internet access point whose access credentials are provided by the app. I used a very primitive packet sniffer and detected (aside from what you just described in this great article) some binary-like form of communication between the camera and the app, including a single packet with the access point credentials in plain text.

    I'm writing this because I can't recognize those strange binary tcp communication the app is having with the cam, I guess it could be made with that PTP/IP protocol thing. Any advice on this will be greatly appreciated. Thank you very much!

  3. Hello,i wonder have you figured out how to connect to RTSP stream via vlc on eken h8 cam?