While on a recent penetration test, I discovered a digital signage system made by Tightrope Media Systems (TRMS). The client was using this software on an appliance provided by TRMS which was essentially an x86 Windows 10 PC. I was able to gain access into the web-interface of this system due to an unchanged default administrator password. I found references online to a vulnerability in the version of this system that allows for an arbitrary file read (LFI) on the system via the RenderingFetch API function (CVE-2018-14573). By reading the CVE and the API documentation, I was able to successfully read files on the system.

Local File Inclusion (LFI) via the RenderingFetch API

I attempted to read protected files, such as the SQL database of the application itself (expecting it to fail, as even if the user account did have read permission to this file, the file would have been locked). Eventually though, I found that the system included a handy database backup function which included the ability to email the backed up file to an arbitrary address. I emailed a copy of the database to myself, but found that due to a bug in the system, it did not include the actual db I wanted, just the secondary db that did not include any user authentication details.

After this disappointing result, I set out to find other ways to compromise the system. I explored the Carousel webui and found something interesting. This interface allows for the uploading of “bulletins”, or in other words, items to display on the digital signage screen.

Carousel bulletin management page

I analyzed the bulletin import mechanism and found that it appeared to accept ZIP files for uploading. Upon attempting to upload a random file, however, it was rejected as not properly formatted. In order to identify the format of these files, I found that I could export an existing bulletin and then open this ZIP file up on my system to look at the structure. Inside of the file, there is a folder called “Pages”, with another folder within that named with a random GUID. I inserted two malicious .ASPX files and then attempted to upload the file.

Malicious ASPX files inside of exported bulletin ZIP file

After this, I was able to successfully upload the ZIP file to the system. I identified the GUID of the newly created (via import) bulletin by looking at the URL attached to the preview image on the webui. To clarify, the GUID inside of the ZIP file is not the GUID once it’s imported into the system. I then attempted to navigate to the URL of the malicious ASPX files I had inserted into the ZIP, but they were not found.

Frustrated, I analyzed the original ZIP file via unzip on Linux, along with 7-Zip on Windows. It appeared that when inserting files into this ZIP archive, the path separator for files and directories was being set to the forward-slash character (“/”) rather than the backslash character (“\”). This caused the files I added to be discarded by the server upon upload. I was eventually able to see this clearly by opening the file in a hex editor.

Bad ZIP file with improperly-formatted additional file

I decided to try to manually change the “/” to a “\” for the files I added to the archive with a hex editor. I just selected the wrong character, typed the right character, and then saved the file. “Surely this will not work”, I thought.

ZIP file after modifying the path-separator character of the newly added files with a hex editor

After modifying the ZIP file with the hex editing tool, I uploaded it to Carousel and found it listed in the main bulletin listing (as I had with my first attempt). I then selected the bulletin and inspected the URL of the preview image (to determine the GUID and full-path to the directory where my files had been imported).

Malicious bulletin archive successfully imported

After identifying the path to the imported files, I attempted to navigate to my malicious ASPX files in that directory. Sure enough, they loaded! I was able to successfully execute commands on the system via a web shell. I first attempted a standard directory listing of the C:\ drive, and then ran whoami .

Directory listing of C:\ drive

whoami showing application being run in context of IIS AppPool\Carousel

Running commands via the web shell became a bit tiresome, so I decided to upload a Powershell file that would connect a remote interactive shell back to my attacking system.

Downloading reverse shell to target system via Powershell

Reverse shell successfully downloaded to target system

I started a listener on my attacking machine and executed the reverse shell Powershell script via the web shell, which caused the targeted system to connect back to me and provide a fully-interactive command prompt.

With that, I had achieved arbitrary file upload and remote code execution on this system. This has been classified as CVE-2018-18930.

Despite having fully-interactive access to this system, I was still running in the context of a restricted account. I set out looking for a way to elevate my privileges. I noticed that the path that uploaded files are saved to was C:\TRMS\Web\Carousel\Media. This meant that the restricted IIS account had write-access to at least that folder. I navigated to the C:\TRMS directory and saw that it appeared an application (an installed application, as opposed to the web app) was running from another directory under the C:\TRMS folder. I issued a command to view the services running on the system and the user accounts they run under. I found two services with “Carousel” in the name running under the SYSTEM account.

Two Carousel services running as SYSTEM

After identifying these services, I issued another command to identify the path at which the executables these services used were located.

Paths of the Carousel services

I then executed a command to show the permissions (ACL) of service executables, trying to identify if we had the ability to modify these files. Sure enough, the “NT Authority\Authenticated Users” group had “Modify” permissions to the service exe file.

“NT Authority\Authenticated Users” with “Modify” permissions to Carousel.Service.exe

I built a small exe file in C# that would execute various commands I compiled into the application, such as a command to create a user account. I moved the original exe file and uploaded my malicious exe to the location the service exe resides.

Malicous exe (Carousel.Service.exe) uploaded, after renaming original

I now needed to restart the service. Unfortunately, the user account I was running under did not have permission to restart services on this system. I found that it did, however, have the ability to restart the server. I ran a command to reboot, knowing that this would achieve the same thing as restarting the service (albeit with slightly higher risk, as the entire system would go down temporarily). After the system came back up, I ran a command to view the local users and administrators on the system and found that my account had been created and was now a local admin!

Rebooting system to restart service

User account “gfsec” created an a member of the local admins group

Now armed with a local user account belonging to the admin group, I attempted to connect remotely directly to SMB. I found, however, that the configuration of this machine did not allow for connections to essentially anything except 80 and 443. Turning off the firewall didn’t seem to help. I ended up uploading Ngrok to the system. Ngrok is a free application/service that allows for bypassing NAT and firewalls, generally used for web development when developers do not have the ability to open up holes in their firewall and forward ports. The application runs on the target system and connects to a local port of your choosing that you wish to connect to from remotely. Then, you are given a randomly generated URL and port number for which you can connect to your target system from anywhere in the world. I ran this on the Carousel system and pointed it at the local SMB port of 445.

Ngrok running, attached to local port 445

After making the SMB port available to remote systems, I was able to authenticate via SMB with Metasploit and have full control over the system conveniently. This privilege-escalation vulnerability has been assigned CVE-2018-18931.

While exploring the system, I eventually uncovered the remnants of a system image deployment. When Windows systems are imaged, administrators can use an Unattend.xml file to control various settings on the new system. This includes local accounts and passwords. I found that the Unattend.xml file left on the system included the creation of a local admin account (along with the password). This default password has been assigned CVE-2018-18929.

Tightrope Media Systems was notified of these vulnerabilities on in early November 2018. They responded back on 11/13/2018 stating that they believed these bugs were fixed and requested the contact info of my client to ensure they were on the latest version. They have not followed-up with me to discuss with them the specifics of these vulnerabilities. Now that approximately 90 days have elapsed since original disclosure, this information is being made publicly available.

UPDATE (2/7/19): Tightrope Media Systems has reached out to me regarding this post and the vulnerabilities discussed. They apologized for the way that the situation was handled on their end and have stated their intention to review how they triage reported security issues. The CEO personally thanked me for my contribution to their security and committed to improving their internal processes. This is a lot better than being threatened with litigation, as has happened to me in the past from other vendors, so I applaud TRMS for their response after this came to their attention (again). If you are a customer, they have released a bulletin regarding the CVEs along with a workaround to mitigate some of the disclosed issues. They are planning to release a patch on 2/8/19.