Good afternoon all,
After getting frustrated with the lag of the adb binding, and the lack of wanting to build an IPtoIR setup, I opted to see what I could find out about the Nvidia shield tv android app. I was able to successfully setup a TLS MITM with openssl and extract out the protocol exchange between the app and the device. I was also able to successfully intercept the PIN process and determine the authentication process as well as decode what the specific button clicks are for the remote. What I need, is some help building a binding around this. I’m not proficient enough at writing java anymore to do this anywhere in a timely or elegant manner.
As a primer, this is what I’ve determined:
- App connects to the shield on port 8987. This is a basic tls connection and was done using openssl s_connect in my testing. This is not an http connection like some of the android tv’s use.
- App sends an ID packet to the sheild (presumably to use as some sort of ID)
- Shield replies with it’s device name (the app uses this to populate the device name)
- The app and the shield exchange a 2 packet back and forth. This seems to stimulate the PIN request to pop up on the TV
- The app sends the PIN back embedded in some other data (I have no idea what that other data means yet)
- The shield replies with a 3 byte packet, not sure what this is yet.
- The shield replies with a 4204 byte payload (after tls decryption). This is broken up with a 50 byte block of data (unknown yet what this is, but it’s been almost identical on every attempt I’ve made so far), then a base64 encoded 2048 bit private rsa key (2442 bytes long), then a certificate (1708 bytes long), and finally a footer of 4 bytes. This certificate is 10 years long, starting on that day, and looks to be generated by the shield itself.
At this point, the PIN process has completed and you disconnect the current tls session. Using the data from that last packet, create a pem encoded key file and pem encoded certificate file. You will need to make sure that the data is base64 encoded. Going forward, it’s imperative that connections to the shield always use this key and certificate. It’s effectively a login for the client. If you miss once, it restarts the PIN process and invalidates the cert/key.
Once you’re here, you basically replay many of the same packets as above minus the key request packets. At this point, key presses are as simple as some basic 17 byte messages sent to the shield (I’ve recorded many). I’ve been able to store logs of the tls keys during the process and run PCAP to expose all of this. Full disclosure, I have not even attempted to decode the entire protocol, this is basically a replay of decrypted tls packets to achieve the effect. I have found one additional request where the app asks for the list of installed apps and the shield replies with a rather extensive set of URLs and metadata on the apps (and you can one button launch them). Further research may uncover things like device status.
So, does anyone want to sign up to work with me to develop a binding for the Nvidia Shield?
EDIT: I forgot to divide by 2 on all the bytes. Numbers above are hex digit lengths, not bytes.