Vulnerability Research, Public Disclosure

TinyCheck Vulnerability Research Report

Three high-severity vulnerabilities in Kaspersky’s TinyCheck, chained into remote code execution. Responsibly disclosed and published.

Vulnerability research3 HighChained to RCEPublic disclosure

Sayfer

Here at Sayfer, we specialize in vulnerability research and malware analysis in desktop, mobile, web, IoT, and hardware fields.

Over time we formed in-house tooling to identify and hunt cyber threats, these tools provide us with a thorough understanding of malware behavior, and allow us to perform better static and dynamic analysis in different testing environments.

Executive Summary

We found 3 different vulnerabilities in the TinyCheck product. Each vulnerability has a high severity by itself, but once combined into a chain, a remote attacker could exploit them to get a RCE (remote code execution) on the remote server.

We added as much technical information for every vulnerability, explained why it is exploitable and proposed a mitigation strategy.

In a nutshell, we used the default credentials of TinyCheck to get a token which allowed us to edit a configuration file. We edited 2 sections in the configuration file:

  • A section that allows us to use malicious code that will be executed later
  • A URL that will be called, and trigger the malicious code from the first section

We wanted to make sure that everything is clear to your team, so we created a PoC script that is attached to this document.

Appendix B describes more findings that might be relevant but we weren't using them in our chain of vulnerabilities.

Product Details

NameTinyCheck
Version1.0 (sourced by the install script, there is no public version). Tested on commit 9d13030aba08cc4075b44c6cce75610e2d1391b4
SummaryTinyCheck allows you to easily capture network communications from a smartphone or any device, which can be associated to a Wi-Fi access point, in order to quickly analyze them.
Source CodeAvailable on GitHub under the organization "KasperskyLab" and the repository "TinyCheck": github.com/KasperskyLab/TinyCheck

The Vulnerabilities

1. Use of Hard-coded Credentials

High severity

Definition

The software contains hard-coded credentials, which it uses for its own inbound authentication or for outbound communication to external components. Any remote actor could access the system using the same username and password "tinycheck". More information can be found at CWE-798.

Description

The "backend" service is listening on all interfaces (0.0.0.0), which opens it to the whole network. By using the default credentials a malicious actor could access a protected endpoint within the Flask application.

The most important endpoint is /api/get-token which generates a JWT token to access other protected endpoints.

Mitigation

Prompt the user for their custom strong credentials during the installation phase or before the first use.

2. Command Injection

High severity

Definition

The software constructs all or part of a command by using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralize special elements that could modify the intended command. For more information please read about CWE-77.

Description

The application code in the "frontend" service is vulnerable to command injections in several areas, the full list is in appendix A.

For instance, by looking at the function start_capture we could see that the code concatenates a string variable to the shell command and uses shell=True rather than a list of arguments.

If a malicious actor could control the iface variable, he could run arbitrary code on the server. A value with a payload that exploits this vulnerability would be:

`whoami>/tmp/exploit.out`

Since start_capture is called when the user captures network activities, the next time the user will do so, the malicious payload will be executed on the remote machine.

Mitigation

Convert the command into a list to better serialize each argument and prevent injection:

sp.Popen(["tshark", "-i", self.iface, "-w", self.pcap, "-f", "\"tcp or udp\""]) (pseudo code, untested)

3. Server Side Request Forgery (SSRF)

High severity

Definition

By providing URLs to unexpected hosts or ports, attackers can make it appear to look as the server is sending the request, while possibly bypassing access controls such as firewalls that prevent the attackers from accessing the URLs directly. For more information please read about CWE-918.

Description

The "watchers" service reads the configuration file under the path of "watchers/iocs". Which is a list of URLs that later the service uses to make an HTTP GET request.

A malicious actor, that could control that list, can create an HTTP request from the server, while bypassing firewalls or reaching local servers, specifically, the "frontend" server, that is configured by default to run on localhost and is not open to the world.

Since this list is available in the configuration file which can be changed remotely by using api/config/edit endpoint, this payload will trigger a request to the local "frontend" service:

https://raspberrypi/api/config/edit/watchers/iocs/http://localhost/api/network/ap/start|DummyPlaceHolder

Once the watchers are restarted the new IOC, "http://localhost/api/network/ap/start", will be called via HTTP GET request, an endpoint the malicious actor didn't have access to before.

Mitigation

To prevent SSRF there is a need to fully understand the architecture deeply, we can not give a one-size-fits-all solution, but we highly recommend reading the Server-Side Request Forgery Prevention Cheat Sheet by OWASP, Available Protections section.

Exploit: Chaining the Vulnerabilities

There are different ways to get RCE (remote code execution) on the host machine, the way we chose to chain all of these vulnerabilities is:

  • Grab the JWT token by using the default credentials (vulnerability #1)
  • Edit the configuration file and add command injection code to the network/in section, that code will be executed later (vulnerability #2)
  • Edit the configuration file and add our custom IOC URL to the IOCs list, with the local URL "frontend" server at http://localhost/api/capture/start|DummyPlaceHolder

Once the user captures network traffic or the "watchers" services are restarted, our custom command injection will run on the remote machine.

Appendix A: Command Injections

Below is a list of all the source code we could find on the application that is vulnerable to command injection:

  • analysis/classes/suricataengine.py:32
  • analysis/classes/zeekengine.py:352
  • analysis/classes/zeekengine.py:354
  • analysis/classes/zeekengine.py:356
  • server/frontend/app/classes/analysis.py:27
  • server/frontend/app/classes/capture.py:49
  • server/frontend/app/classes/network.py:145
  • server/frontend/app/classes/network.py:238
  • server/frontend/app/classes/network.py:240
  • server/frontend/app/classes/network.py:297
  • server/frontend/app/classes/network.py:308
  • server/frontend/app/classes/network.py:316

The application also has safe OS command calls, but these are still being called with shell=True and might be vulnerable in the future:

  • server/frontend/app/blueprints/misc.py:16
  • server/frontend/app/classes/network.py:277
  • server/frontend/app/classes/network.py:279
  • server/frontend/app/classes/network.py:280
  • server/frontend/app/classes/network.py:281
  • server/frontend/app/classes/network.py:295

Appendix B: More Findings

While conducting the research we found a few findings that we believe can be improved:

  • The application runs as the root user, any exploit for the web application will give high privilege access to the malicious actor.
  • The application runs in debug mode, which isn't suitable for a production environment.
  • The endpoint /api/config/list lists all the configuration data and is not protected by any authentication system, while it is not showing the password field, in the future, more configurations might be added and will be automatically shown in this endpoint.