Lately, I bought some random, noname spy camera from usual Chinese sources. Just after unboxing, one detail seemed a bit suspicious to me: together with the camera there comes a link to Android app, that is meant to control the camera. What is worse, the link leads to some Chinese app shop, obviously with only one language available (notice the version – 1.0.33, as it is not the only one in the wild):
http://m.app.so.com/detail/index?pname=com.hbwy.fan.iminicams&id=3646142
As I’ve already seen apps that i.e. calls home, despite having no need to open a single socket and then sending data like IMEI, IMSI, MAC addresses and so on, red lamp turned on and I said to myself: stop. Let’s reverse engineer the thing first!
OSINT
Before I begun my reverse engineering, I attempted to ask uncle Google (and his friends 🙂 ) to gain some knowledge. Usual virustotal gives me this:
Not bad for such a simple application. Searching other shops for the same name leaded to exactly the same application (shared objects included matches), but older version (1.0.25) and in their case virustotal stopped complaining. For me there are two possible reason for that:
- Google Play app is not supported by vendor anymore
- There is special edition for Chinese, with few surprises
In favor of the second option is the fact that Java code of only the China edition is heavily bloated and usual decompilers cannot reverse the code properly, so somebody tried to make reverse engineer’s life harder. In apk downloaded from downloadapk.net and apkplz.com, everything seem to be fine.
Below are the links, I’ve used in comparison:
- Google Play: https://play.google.com/store/apps/details?id=com.hbwy.fan.iminicams (1.0.25)
- downloadapk.net: https://downloadapk.net/down_IPLiveCam.html (1.0.25)
- apkplz.com: https://apkplz.com/android-apps/iplivecam-apk-download (1.0.25)
Just for completeness, below is the name and webpage of suspected vendor of the stuff, I found accidentally: Albert Technology Co., Ltd. Shenzhenshihong Bo
, and their webpage is here: http://www.honest-tech.com/en/
Let’s reverse then
First thing,I’ve noticed after decompilation of APK’s Java classes is:
public static String a(String paramString) { if (paramString == null) return ""; if (paramString.length() == 0) return ""; paramString = new BigInteger(paramString.getBytes()); return new BigInteger("0933910847463829232312312").xor(paramString).toString(16); } public static String b(String paramString) { if (paramString == null) return ""; if (paramString.length() == 0) return ""; BigInteger localBigInteger = new BigInteger("0933910847463829232312312"); try { paramString = new String(new BigInteger(paramString, 16).xor(localBigInteger).toByteArray()); return paramString; } catch (Exception paramString) { } return ""; }
So, it’s gonna be interesting… As it turns out this one seem to be unused. But, after going a bit further and searching for all hardcoded strings I found this:
cfans/ufo/sdk/d/a.java:37: PPPP_APIs.PPPP_Initialize("EBGDEIBIKEJOGCJNEBGBFDEOHJNDHANKGEFCBNCJAPJILDLIDEABCLOKGMLNJBKDALMNLKDOONMGAFCJJKNHJN".getBytes());
PPPP is shared object linked to the app via NDK, so I started reversing this libPPPP_API.so
. Not so long time later, I was able to see decoded string by running the library and connecting gdb to it:
(gdb) p (char*)$sp+0xc $16 = 0xbefff78c "121.40.184.33,120.25.151.105,120.25.157.75,"
I’ve check the addresses in whois database and all of them leads to Hangzhou, Zhejiang, China.
Next to decoding of these addresses, there is UDP socket opening routine and at least two ports are used: 32100 and 32108, where first one is used to connect to these services (all three of them) and port 32108 seem to be the port of camera.
What is my IP address?
So far, I identified at least one request that for sure goes to the hardcoded server, so in fact it is used to call home. This is the so called hello request. It sends nothing at all, as can be seen below:
00000000 f1 00 00 00 |....| 00000004 [len] [magic] [typ]
And in response it gets packet like that:
00000000 f1 01 00 10 00 02 7b 3d xx xx xx xx 00 00 00 00 |......{=........| 00000010 00 00 00 00 |....| 00000014 [len] [magic] [sockaddr_in] [typ]
Content of this packet is then cast to sockaddr_in
packet and experimentally, I was able to tell that it contains WAN address of requesting side (this is the censored part). I haven’t noticed the original sockaddr_in
, that was used to send this hello message in memory, so chances are this is the only purpose of that server.
However, there are a lot of other datagrams crafted from same function as this one (including so called P2P requests), so I cannot guarantee I haven’t missed anything. In my opinion, further dynamic analysis is required. And I want to do one either way.
Other indicators?
Beside these suspicious addresses, I noticed some ioctl usage, but this seem to be quite legit. It just checks configuration of network interfaces (the worst that can happen out of this is sending somewhere MAC address of all interfaces available, that is both WiFi and cellular).
I focused my analysis on libPPPP_API, but beside that, there exists also UFO SDK and Adpcm codec. While Adpcm can be considered safe, as it does not import anything weird, UFO SDK is suspicious, just like PPPP API. Maybe little less, as it does not seem to obfuscate any strings. Nevertheless, it opens some sockets,probably only for RTP, but still.
Conclusion
The most important recommendation is to never trust any source of APKs beside official shops, most notably Google Play, as in it there exist some administration staff, that can react in case of obvious malware (how often and in which cases they do is another story). As can be seen in this case, either app vendor, or a shop is attaching some stuff, which is recognized as malware. In case of Google Play variant (and other Play-cloning shops), things are much better and no alert is raised by VirusTotal.
Second point is how to treat the fact of calling home, especially in situation where app vendor tries to hide the fact by obfuscating the string that contains the addresses. In my opinion, it is enough to not let that app do anything outside some closed network (with no means of sending packet to the internet), at least to be able to check the behavior in practice. And this is probably what I am going to try next. However, I can imagine that I will be using the app, despite that, but after banning these three servers. I can also understand that most people will ignore that fact (or even more – will be unaware of that), as in today’s world there is such a huge amount of services that are gathering our data, that it is impossible to block them all.
To sum up, if you want to use it, download from Google Play and keep in mind, some data might leak somewhere on he Chinese coast.
PS: I am not planning to publish complete API, which I am in theory able to reverse engineer. However, expect some quick summary of what I already know about the protocl 🙂
Hi there I read with interest your investigation on the IPcamLivw App as I can no longer find in playstore and is only available as an APK from a variety of places all this you know I can see you know your stuff I have long suspected it may not be legit but now have a dilemma should I download from one of these or give up on my mini cams that use it thanks for your insight and contributing to persons that seek to steal our data
Hi. I think our camera uses protocol CS2 Network P2P or Shenzhen Yunni iLnkP2P (partly described at https://github.com/pmarrapese/iot/tree/master/p2p/lansearch . There are also used 32108 port for the hello message with magic number ‘F1’).
I bought similar p2p camera that works only throu its native APP. And I was tried found the way to get videostream from linux machine. Network analyze with airodump an wireshark shows the following conversation between APP (192.168.88.100) an Cams AP (192.168.88.1):
broadcasting message ‘2cba5f5d’: 192.168.88.100:18587>>192.168.88.255:32108 data:2cba5f5d
the camera responds (from random port 10730) to the same IP and port from where the message was received 192.168.88.1:10730>>192.168.88.100:18587 data:2c:cb:62:93:b3:d9:35:8d:c2:90:c3:55:61:36:bf:15:b0:34:ae:ad:46:27:88:63
the app echoes message to the same port 10730: 192.168.88.100:18587>>192.168.88.1:10730 data:2c:cb:62:93:b3:d9:35:8d:c2:90:c3:55:61:36:bf:15:b0:34:ae:ad:46:27:88:63
Then the camera sends 4 identical MSGs: 192.168.88.1:10730>>192.168.88.100:18587 data:2c:c8:72:e4:37:40:dc:b5:20:73:69:7c:cf:31:d6:bf:2f:0a:99:7d:77:12:d0:fe
And before camera will send videostream there would be about another 10 series of messages between APP and camera.
If anybody of the readers have seen a similar network exchange and figured out how it works, share your results, please.
Great findings! Thanks for the information.
Can we somehow get the stremURL for this type of cameras?