Monday, August 28, 2017

Quick Solstice Pod analysis

Introduction:
My school has started using Solstice Pods (https://www2.mersive.com/land/solstice-pod/) in some classrooms. First thing I thought about is how I could troll people in classrooms by playing Rick Roll. Doing this would require me to have 4 char. access code.
In my post about Crestron Airmedia  (http://www.boredhackerblog.info/2016/04/bruteforcing-crestron-airmedia.html), which is a similar product, I was able to get access code by brute forcing the code and looking for a specific reply. In that case, the access code was made up of just numbers. Access code for Solstice Pod has numbers and uppercase alphabetic chars. Also, the channel for sending access code for Airmedia was in cleartext and easier. I can’t figure out how exactly Solstice client sends the access code. I know it’s not cleartext. I didn’t do enough reversing to answer this question. I think I would have had to use Frida at some point if I was able to do better reversing.

Anyways, I brought one of the Solstice Pod boxes home so I could play with it and see if I could find other ways to mess with it or find potential security issues. I spent less than 8 hours researching this and probably won’t continue researching it because school will start again.

Some students from last years Risk assessment class did do an assessment of Solstice, however, they were not able to find anything major. Also, they were evaluating an older version (I think version 2).

Device information:
Username: admin
Password: anything you set the password to be, in my case i set it to be password
Version:

Solstice Pod runs Android and Solstice Server runs on top. The hardware has USB input, HDMI output, Ethernet, and Wireless. It has same specs as Razer Forge since it’s actually Razer Forge with Solstice software.

There are two ways to connect to the device. One is by using ethernet and the second is by using wireless. You can connect using clients for Windows, Mac, Android, and iPhone.

Nmap scan of the device from wireless connection:
PORT     STATE SERVICE
53/tcp   open  domain
80/tcp   open  http
443/tcp  open  https
7100/tcp open  font-service
8080/tcp open  http-proxy
8443/tcp open  https-alt

Nmap scan of the device from ethernet connection:
PORT     STATE SERVICE
80/tcp   open  http
443/tcp  open  https
7100/tcp open  font-service
8080/tcp open  http-proxy
8443/tcp open  https-alt

Other ports that are open:

Solstice documentation has information about the ports.

Findings:
Wireless:
If you have wireless enabled, Solstice can create an AP for you to connect to so you can broadcast your screen. If the client is connected via wireless, then they can also access the internet using the ethernet connection. There is a setting option that allows you to disable this! It’s would be an issue if you deployed bunch of these and forgot to disable wireless or routing via ethernet. Not really a big issue though.

Screen access code bruteforce:
As mentioned in the introduction, I was not able to figure out how to brute force the access code by doing the analysis I did. There is a way to do brute force, however, it requires Look-in option to be abled. Look-in option allows people to view whatever is on Solstice display remotely via browser.
If it’s enabled, you should see a link:
When you click on the link, it asks you to input the screen key (I’ve been calling it access code…):

I was using Burp suite to intercept the requests.
I tried the key AAAA:
First a POST request is sent with screenKey AAAA.

After that a GET request is sent with the screenKey AAAA

The response to GET request shows that the screen key did not work.

Next I performed the GET request with the correct key and here’s the response:

You’ll quickly notice that the response is an actual JPG image. (JFIF header)

If you didn’t know the screenKey and wanted to find out remotely, here’s how you could go about doing that.
1) Look-in feature has to be enabled. I don’t think it’s enabled by default.
2) You need to generate possible keys. You can do this easily in Python by using the following script:

import string, itertools
pass_length = 4
chars = string.ascii_uppercase + strings.digits
for guess in itertools.product(chars,repeat=pass_length):
   print ‘’.join(guess)

(found an example on stackoverflow, I forgot to bookmark it :()

3) You would brute force http://IP/lookin/thedisplay.jpg?screenKey=SCREENKEY and look for a reply bigger than 38 bytes(if key is invalid we get screenKeyValidationRequire response, which is 38 chars).
4) Be patient. Brute forcing all the possible keys would take a long time.

This again is not a very big issue. You would notice someone brute forcing the box. It’s really not worth doing, even if you’re trying to Rick Roll someone.

DoS attack:
I moved to examining Configuration page. Screen key lets you share your screen or view via Look-in feature. Configuration has a separate login. The username is admin and the password is whatever you set it to be.
On configuration page, you’ll get a login prompt:

As mentioned before, I had Burp Suite running. In previous versions, when you tried to login, the application would pass the password in cleartext in a GET request. The newer version does not do this. The newest version hashes the password with SHA-1 then sends that via GET request just like the older version.
9d4e1e23bd5b727046a9e3b4b7db57bd8d6ee684 is SHA-1 Hash for pass.

I decided to just pass bunch of data in the password parameter just to see what would happen. It actually crashed the Solstice server and restarted it. Screen went blank and restart takes about 20-30 seconds.

This is how you can trigger the service to crash: (I didn’t have word wrap enabled so I just added new lines. It should all be one line. :D) Finally, this is something that’s useful. You can setup a script to trigger the crash and keep causing DoS for the instructor or other students utilizing Solstice Pod.
Undocumented Paths:

I wasn’t able to find any documentation on some of the paths I found using just strings. As mentioned before, Solstice software runs on top of Android. After logging into Configuration page, I noticed JSON response:
"canUpgradeToVersion":"3.0.1","canUpgradeToBuild":"6923","canUpgradeToBuildDate":"","canUpgradeToBuildTime":"","canUpgradeToDate":"7/11/2017","canUpgradeToRelNotes":"http://www.mersive.com/Support/Releases/SolsticeServer/SGE/Android/3.0.1/ReleaseNotes.html","canUpgradeToDownload":"http://www.mersive.com/Support/Releases/SolsticeServer/SGE/Android/3.0.1/Solstice.apk","latestReleaseVersion":"3.0.1","latestReleaseBuild":"6923","latestReleaseBuildDate":"","latestReleaseBuildTime":"","latestReleaseDate":"7/11/2017","latestReleaseRelNotes":"http://www.mersive.com/Support/Releases/SolsticeServer/SGE/Android/3.0.1/ReleaseNotes.html","latestReleaseDownload":"http://www.mersive.com/Support/Releases/SolsticeServer/SGE/Android/3.0.1/Solstice.apk","installedReleaseEdition":"Unlimited","installedReleaseVersion":"3.0.1","installedReleaseBuild":"6923","installedReleaseBuildDate":"","installedReleaseBuildTime":"","installedReleaseDate":"7/11/2017","installedReleaseRelNotes":"http://www.mersive.com/Support/Releases/SolsticeServer/SGE/Android/3.0.1/ReleaseNotes.html","installedReleaseDownload":"http://www.mersive.com/Support/Releases/SolsticeServer/SGE/Android/3.0.1/Solstice.apk", It included a link to an APK file. I downloaded the APK file and just unzipped it. There is a web folder with all the HTML/JS stuff that you see on the webpage. There is also a lib folder. I searched for “Look-in” to see which binary contained that string. I loaded up the binary file in IDA so I could look at strings. I started looking for common Linux commands to see if they were based on any user input. If they were I could try to inject something but I didn’t find anything that was based on user input. I came across something interesting while doing searches: There is /diag, which you don’t see when running Burp. Accessing anything under /diag does require you to authenticate. The username is admin and the password is whatever password you have set for configuration. Loglevel shows you the loglevel settings. Logs.zip gets you a zip file with logs. Clearlogs probably clears the logs, I didn’t test it. Log prints out the logs (screenshot below). I didn’t get logcat either. Tcpdump gives you an option to run tcpdump and download pcap files (screenshot below).
I started looking for more potential paths that I didn’t come across before. I found /test. Accessing /test does not require authentication. You just get system and performance information. Conclusion: I hope that someone finds this post useful or gets ideas from it. There wasn’t much of a methodology I followed. I did use automated tools such as OWASP ZAP and Subgraph Vega (found nothing)  before doing manual work. Vendor response: I reported DoS bug on Aug 4, 2017 Vendor responded on Aug 7, 2017 saying that it will be fixed in the next update Vendor released an update fixing the DoS bug on Aug 27, 2017. Version with DoS fix is 3.0.3.
Resources for this project were provided by the Living Lab at IUPUI. https://livlab.org