How to hack an app enabled device to make it truly internet enabled
I’ve sort of had this semi-article for a while, but not really got around to writing it up; as I couldn’t equate it to a real world risk.
So, what am I hacking today? This thing, purchased from eBay for a grand total of £50, that my eldest son won’t stop pestering me to play with.
It’s a remote control tank, with an embedded camera that you can control and view from a wireless device.
The major problem with the device is that the camera only rises up and down and, at maximum elevation points roughly at a height of about 3 foot.
To use the device, you download the app from your device’s app store, run the app, watch as it crashes, run the app, watch as it crashes, run the app again and finally connect to the device as a wireless access point.
Its SSID is helpfully printed on the bottom:
So, let’s connect first, by turning it on and connecting to the Wireless SSID it creates:
We’re given an IP address via DHCP:
Configuration for interface “Wireless Network Connection”
DHCP enabled: Yes
IP Address: 10.10.1.100
Subnet Prefix: 10.10.1.0/24 (mask 255.255.255.0)
Default Gateway: 10.10.1.1
Gateway Metric: 0
This is what we normally expect to see on joining a wireless network. We can make an educated guess that the DHCP assigned default gateway is the actual “spy tank”. A quick port scan to show up which ports are open shows some weird and unexpected stuff:
Starting Nmap 6.40 ( http://nmap.org ) at 2015-07-10 16:58 GMT Daylight Time
Nmap scan report for 10.10.1.1
Host is up (0.021s latency).
Not shown: 65528 closed ports
PORT STATE SERVICE
21/tcp open ftp
80/tcp open http
139/tcp open netbios-ssn
445/tcp open microsoft-ds
8150/tcp open unknown
8196/tcp open unknown
52881/tcp open unknown
MAC Address: 80:07:A2:02:54:2A (Esson Technology)
Nmap done: 1 IP address (1 host up) scanned in 104.76 seconds
What? Windows networking ports on a remote control tank? This is strange; it’s time for some basic reconnaissance, by trying to connect to each of the ports.
The first thing to try on an FTP server is normally the anonymous user, which is either “anonymous” or “ftp” and it looks like anonymous FTP is enabled and has access to the whole file system:
Connected to 10.10.1.1.
220 Welcome to blah FTP service.
User (10.10.1.1:(none)): ftp
331 Please specify the password.
230 Login successful.
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
226 Directory send OK.
ftp: 68 bytes received in 0.01Seconds 6.80Kbytes/sec.
This is useful and we’ll come back to this later.
Web servers are the prime targets for trying to abuse IoT devices, as they normally allow a simple interface into the configuration of the device and generally do not require authentication. Let’s have a look:
Oh, botheration (as my 4 year old would say); me and my big mouth!
But, the mobile app talks to the device and allows status information from it, including the firmware details, so it’s likely that it may have the password. If you’ve kept up with my previous articles, you’ll know that Android apps are usually written in Java and compiled for the Dalvik virtual machine (or ART in Lollipop – but its binary compatible). This means that we can convert the app to a Java jar file and then decompile it.
A quick download of the app on to a rooted device, then we can copy the apk from where it lives (/data/app/com.leo.wifitoys.Controler.jgremoter-1/base.apk), notice that they can’t spell “controller” and convert it to a jar:
dex2jar com.leo.wifitoys.Controler.jgremoter-1.apk -> com.leo.wifitoys.Controler.jgremoter-1-dex
Then we load up jd-gui.exe and have a quick search through the code:
Oh look, credentials of HAPPYCOW:HAPPYCOW (I’ve deliberately left more in the screenshot than we need at the moment – you may be able to guess why).
Let’s try them out:
And… we’re in. And this is an important lesson on why you never hardcode credentials into your app.
Follow the settings link and we’re in, well, a wireless router set up web page:
So, this tank is basically a wireless AP with some connectors to its motors to drive the tank forwards, backwards, left, right and to raise and lower the camera. We can actually change the mode in here so it could connect to my wireless network (although the app wouldn’t work).
Now, scroll up a bit to the screenshot of the decompiled app and cast your beady eyes over those URLs. Can you notice something interesting in them: the word “syscmd”.
So what happens if we go there?:
Yep, we have a web enabled root shell built in to the device. This is going to be easier that I thought!
If we “cat /proc/cpuinfo” we can see what the CPU is:
Basically an RTL819xD SoC. I have a toolchain for that. So do you think we can put nmap on there? Maybe, but that’s a story for a different day.
If we look through Windows networking we see 3 shares, one of which (mnt) is empty and the others we get strange errors for.
Though, through nbtscan we discover that the hostname is RLX-LINUX:
10.10.1.1 WORKGROUPRLX-LINUX SHARING
Interesting, but nothing useful.
Video Streaming Port
The port 8196/tcp when connected to returns a stream of data. Now what we’re missing from the facilities of the device is the video camera. So, we can make a simple assumption that it is a video feed.
Checking a “ps” listing from the syscmd.htm command shell shows us this too:
997 root 1840 S uart_bridge 1 192.168.1.188 8150
999 root 8024 S uvc_stream -r “640×480 -f 25 -p 8196 -l 3 -m MJPG -d
1000 root 8024 S uvc_stream -r “640×480 -f 25 -p 8196 -l 3 -m MJPG –d
Note that 8150 appears to be uart_bridge – we’ll look at this later.
The quickest way of testing this is to load it as a http video stream in VLC, and here you have it being quite meta by showing my laptop’s monitor and this very document that I’m writing:
Simple Config Port
Port 52881/tcp confused me for a while, until I had a sniff around the system files through the ftp link and found the simplecfg daemon, which shows that it’s a UPnP port:
And we can see some of the functions that it allows by browsing to
http://10.10.1.1:52881/simpecfgservice.xml – which are all standard Wireless AP functions:
So we’ll leave the best ‘til last, port 8150/tcp, which if you remember was tied down to a process called “uart_bridge”, with parameters of: “192.168.1.188 8150”.
Which is interesting as that’s not the IP address it has. A download of the executable (/bin/uart_bridge) shows that it appears to be a custom executable which bridges the TCP to /dev/ttyS0. No help there really.
So, we connect to it with a raw PuTTY session to 10.10.1.1:8150 and get a raw session. After a bit of messing around, I discovered the following commands can be entered (all need following with return):
|10||Left track stop|
|11||Left track forward|
|12||Left track backward|
|20||Right track stop|
|21||Right track forward|
|22||Right track backward|
If you enter multiple commands on the same line, then they all operate at the same time, so 112131 will move left and right tracks forwards and raise the camera.
This doesn’t quite give us all the functionality of the app, as the camera can be raised in increments, we can mirror this by starting a raise (31) and then quickly issuing a stop (30).
We can confirm this by looking at the app’s decompiled code:
So we now have enough information that we could make a custom client, and then use the wireless interface and attach it to a wireless AP and make it truly Internet enabled!