Advisory

Yorick Koster, March 2014

NSS 2014 affected by remote code execution & insecure certificate validation

Abstract

NSS 2014 for Android exposes several insecure Javascript bridges. The app also misses crucial SSL/TLS certificate checks, making the app susceptible to man in the middle attacks. Combining these issues renders NSS 2014 vulnerable to remote code execution.

Exploiting the Nuclear Security Summit 2014 Android app - a demo from Securify BV on Vimeo.

Fix

Certificate validation was restored in version 2.0.0 of NSS 2014 for Android (released on March 19, 2014). Version 2.0.3 opens insecure (HTTP) links in an external browser, which prevents attackers from exploiting the affected Javascript bridges via man in the middle attacks (released on March 21, 2014).

Introduction

On March 17, 2014 a news item was posted on the popular Dutch news site nu.nl. This item covered the availability of an iOS & Android app for the Nuclear Security Summit held on March 24 & 25, 2014. The news item also noted that no benefit would be gained from hacking the app as the app would not store/display very sensitive information. Of course we regarded this as an open invitation to take a closer look at the app.

Spending only 5 minutes with the Android app quickly revealed some serious security issues in the app. First of all the SSL/TLS implementation used by the app offers no security at all. Server certificates are not properly validated by the app rendering the app vulnerable to man in the middle attacks. In addition, the app is build with Appcelerator Titanium, which makes extensive use of WebViews. Titanium registers multiple Javascript bridges by default, which are potentially affected by remote code execution as is the case in NSS 2014. Consequently, an man in the middle can inject & run arbitrary code in the app, resulting in at least a compromise of the app's data and likely also data stored on the SD card.

The target group for this app are attendees of the summit. Some three letter agencies may be very interested in running arbitrary code on their devices.

Appcelerator Titanium

"Titanium is an open-source framework that allows the creation of mobile apps on platforms including iOS, Android, Windows Phone, BlackBerry OS, and Tizen from a single JavaScript codebase". Titanium apps make extensive use of WebViews. The TiWebViewBinding class registers the following Javascript bridges:

- TiApp
- TiAPI
- _TiReturn

public TiWebViewBinding(WebView webView)
{
   codeSnippets = new Stack<String>();

   apiBinding = new ApiBinding();
   appBinding = new AppBinding();
   webView.addJavascriptInterface(appBinding, "TiApp");
   webView.addJavascriptInterface(apiBinding, "TiAPI");
   webView.addJavascriptInterface(new TiReturn(), "_TiReturn");
}

If these apps are targeted for Android API Level 16 or earlier, these Javascript bindings can be leveraged to execute arbitrary code. A detailed description about this issue can be found at the following URL:
https://labs.mwrinfosecurity.com/blog/2013/09/24/webview-addjavascriptinterface-remote-code-execution/

Most apps are targeted for an older Android API as app makers want to allow their app to run on old(er) devices. This is also the case for NSS 2014. Consequently, NSS 2014 is vulnerable to remote code execution provided that an attacker can inject malicious Javascript code into an affected WebView.

SSL/TLS handling in NSS 2014

There are several ways an attacker might inject malicious script in a WebView. The easiest method is probably using a persistent Cross-Site Scripting vulnerability (in the backend). Code execution is also possible by performing a man in the middle attack against insecure (HTTP) connections. It appears that some articles in NSS 2014 contain such insecure links that are opened in a vulnerable WebView. Version 2.x also contains a button that opens Holland.com in a WebView over HTTP.

Further testing reveals that NSS 2014 does not perform any validation on the server's certificate. Due to this, it is possible for attackers to perform man in the middle attacks against the app. A man in the middle can alter the HTML returned by the backend, inject malicious Javascript in this HTML and as a result run arbitrary code on the devices of the victim.

As it seems, there are various situations in which Titanium will use insecure connections. For example, the method validatesSecureCertificate() of the TiHTTPClient fails open (insecure) in case the property validatesSecureCertificate does not exist and the deployment type is not set to production.

public boolean validatesSecureCertificate()
{
   if (proxy.hasProperty("validatesSecureCertificate")) {
      return TiConvert.toBoolean(proxy.getProperty("validatesSecureCertificate"));

   } else {
      if (TiApplication.getInstance().getDeployType().equals(
         TiApplication.DEPLOY_TYPE_PRODUCTION)) {
         return true;
      }
   }
   return false;
}

Also the TiHTTPClient constructor disable SSL/TLS validation by default:

public TiHTTPClient(KrollProxy proxy)
{
   this.proxy = proxy;
   this.client = getClient(false);

[...]
}

protected DefaultHttpClient getClient(boolean validating)
{

[...]
   else if (!validating) {
      TrustManager trustManagerArray[] = new TrustManager[] { new NonValidatingTrustManager() };
      try {
         sslSocketFactory = new TiSocketFactory(null, trustManagerArray);
      } catch(Exception e) {
      Log.e(TAG, "Error creating SSLSocketFactory: " + e.getMessage());
      sslSocketFactory = null;
   }
[...]
}

Due to this, it is more likely for developers to create an insecure app than one that does validate server certificates - which is also the case for NSS 2014. Combined with code execution in the WebView makes NSS 2014 a very interesting hacking target, regardless of what was stated earlier in the media.

Proof of concept

This issue can be exploited via a man in the middle attack. Injecting the following HTML code into a HTML page & opening the modified page in a vulnerable WebView will create a file on the SD card.

<script>
function execute(cmd){
   return window.TiApp.getClass().forName('java.lang.Runtime')
      .getMethod('getRuntime',null).invoke(null,null).exec(cmd);
}
execute(['/system/bin/sh','-c','echo \"Lorem ipsum\" > /mnt/sdcard/nss2014.poc.txt']);
</script>

Latest News & Research

Work with us →