Kogan Smart Tv Hacking

I recently purchased a Kogan 43" Smart TV (KALED43KU8000SZA), and I’m not entirely happy with it. Since the invention of the instant-on CRT in the 1960s, TVs have been able to switch on in mere seconds. Nearly 60 years on from that, I hit the power button, wait for Android to boot, and 30 seconds later, this:

It’s displaying input from my OSMC Vero 4k - and yes, then I have to use the menu controls to select the input, before it displays fullscreen - every time. It’s a small annoyance, but it’s a significant one - the TV has one job…

I wanted the “smart” features to play with, but it appears I’m being forced to. This just won’t do, so Michaela Wheeler and I took a look and we fixed it. Read on to find out how.

So, firstly we connect it to the network - but not the same network as anything else. It’s on the isolated wireless network, for “untrusted” things - internet access only, no access out to the rest of the LAN, but NAT into the subnet so everything else can poke it…

Let’s see what’s listening:

$ sudo nmap -sS 203.0.113.252 -p 1-65535 -sV --version-all

Starting Nmap 7.40 ( https://nmap.org ) at 2018-02-27 19:49 AEDT
Nmap scan report for 203.0.113.252
Host is up (0.0041s latency).
Not shown: 65533 closed ports
PORT     STATE SERVICE  VERSION
554/tcp  open  rtsp
5555/tcp open  freeciv?
1 service unrecognized despite returning data. If you know the service/version, please submit the following fingerprint at https://nmap.org/cgi-bin/submit.cgi?new-service :
SF-Port554-TCP:V=7.40%I=9%D=2/27%Time=5A951C50%P=x86_64-apple-darwin16.7.0
SF:%r(RTSPRequest,63,"RTSP/1\.0\x20200\x20OK\r\nCSeq:\x200\r\nPublic:\x20O
SF:PTIONS,\x20DESCRIBE,\x20SETUP,\x20TEARDOWN,\x20PLAY,\x20PAUSE,GET_PARAM
SF:ETER\r\n\r\n")%r(HTTPOptions,63,"RTSP/1\.0\x20200\x20OK\r\nCSeq:\x200\r
SF:\nPublic:\x20OPTIONS,\x20DESCRIBE,\x20SETUP,\x20TEARDOWN,\x20PLAY,\x20P
SF:AUSE,GET_PARAMETER\r\n\r\n")%r(SIPOptions,64,"RTSP/1\.0\x20200\x20OK\r\
SF:nCSeq:\x2042\r\nPublic:\x20OPTIONS,\x20DESCRIBE,\x20SETUP,\x20TEARDOWN,
SF:\x20PLAY,\x20PAUSE,GET_PARAMETER\r\n\r\n");

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 464.04 seconds

Yes, that address is not your usual RFC1918 - it’s RFC5735. RFC1918 is just soooo mainstream…

Port 554/tcp is interesting if it’s hosting a RTSP server - but that’s not what we’re here for.

Port 5555/tcp jumps out at me - but it most likely isn’t FreeCiv - it’s better. Could it be?

$ adb connect 203.0.113.252
connected to 203.0.113.252:5555
$ adb shell
shell@arbutus:/ $

Oh. ADB running out of the box. Nice.

shell@arbutus:/ $ su
shell@arbutus:/ #

Uhhh… well that saves me some time… I guess…

We poked around and found a few interesting activities - mstar.factorymenu.ui gives you a rather interesting service menu.

com.toptech.factorytools gives you an RGB test pattern which persists after a reboot, still persists after a hard reset and only after some trial and error we found the power button on the side of the TV gets rid of it. (that was annoying…)

Some poking around revealed which packages provided the launcher and main menu. Killing the main menu process - com.toptech.tvmenu - made the TV display the HDMI input fullscreen. Wouldn’t it be great if that thing was just never started in the first place? Let’s poke around at the launcher.

$ adb pull /system/app/NewTopLauncher/NewTopLauncher.apk ./Launcher.apk
/system/app/NewTopLauncher/NewTopLauncher.apk: 1 file pulled. 0.5 MB/s (2499659 bytes in 4.896s)
$ apk2gold Launcher.apk

We were looking through the decompiled source of MainActivity.java and something looked a little “interesting”…

protected void onCreate(Bundle paramBundle)
{
	// -snip-
	this.IR_TYPE = SystemProperties.get("mstar.toptech.remote", "0");
	// -snip-
	Intent localIntent;
	if ((!this.IR_TYPE.contains("ToHome")) && (isPowerOn() == true)) {
		// isPowerOn() returns true if launcher run for first time since boot
		ComponentName localComponentName = new ComponentName("com.toptech.tvmenu", "com.toptech.tvmenu.TVActivity");
		localIntent = new Intent("android.intent.action.MAIN");
		localIntent.setComponent(localComponentName);
		localIntent.setFlags(0x10200000); // FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_FORWARD_RESULT
	}
	// -snip-
}
(some irrelevant code removed, comments mine)

Interesting…. I wonder what’s in mstar.toptech.remote?

shell@arbutus:/ $ getprop mstar.toptech.remote                                 
IR_Y093FC_ToHome

I wonder if we can just remove the _ToHome - if it breaks anything we can always put it back. Using setprop doesn’t set it permanently - it’s set in Android’s system build.prop.

We’ve got root though so…

shell@arbutus:/ # mount -o remount,rw /system                                  

adb pull, edit, adb push, reboot.

#------------------------------------------------------------------------------
# toptech defined ro properties, this will override system props start with ro.
#we write only properties start with mstar.xxx
#these properties will overide the ones changed by script
#------------------------------------------
#default settings
mstar.toptech.remote=IR_Y093FC

Fullscreen HDMI, from the last source, on boot… or what I’d expect from any other TV?

Still to do:

  • investigate that RTSP server
  • there’s supposedly an app that can control the TV - see how it does so
  • HDMI-CEC can turn the TV on but not off - why?
  • See if there’s anything interesting in any of the other provided software
  • Patch the launcher to see if I can get it to boot faster (hello delayToScanUSB())…

Share