Tuesday, December 15, 2015

Black-Box security assessment: check if SSL client has been implemented in a right way.

 During black-box security assessment of a mobile or a desktop application, there are three following possible MiTM attack scenarios/vulnerabilities we should check for:


  1. S1: The site or MiTM adversary presents an invalid, self-signed certificate;
  2. S2 – not an attack, but still incorrect implementation: The site or adversary presents an expired certificate.
  3. S3: The site or adversary presents a certificate with a wrong Common Name (CN) and/or SubjectAltName, signed by a root CA.


It is trivial to check case S1. Configure application to use Fiddler as a proxy, but do not trust Fiddler Root Certificate
Now open the application in test (let’s imagine it is a PayPal client for Android), get it to use Fiddler as a proxy and try to run it. 
If it works (highly improbable in our days), then SSL chain of trust is broken and the client does not check whether the certificate is signed by a trusted Certificate Authority.

S2 - Expired certificates case is slightly trickier.
Probably the simplest thing to do would be to use the app so that Fiddler creates the certificate, then, without closing the app, change the local system clock to three years in the future. 

Alternatively, if you're using the CertEnroll generator, you can type 
prefs set fiddler.certmaker.ValidDays -364
in the QuickExec box so that the certificates generated expire nearly a year before the current date.

If you do that, don't forget to remove the preference and use the "Remove Interception Certificates" Action in the HTTPS tab to remove the "bad" certificates after you're done testing (or everything else will break too!)

This is how the browser (Google Chrome) reacts on this type of SSL errors:


Make sure that our PayPal client does not work either!

And last, but not least, let’s check S3 case – how the application in test would react to a certificate with a wrong Common Name (CN)

To do that, open Fiddler.
Click Rules > Customize Rules. Scroll to OnBeforeRequest.
Inside that function, add the following:

   if (oSession.HTTPMethodIs("CONNECT") && 
       oSession.HostnameIs("paypal.com"))
   {
         oSession["X-OverrideCertCN"] = "badhostname.com";
   }

Save the file and restart the client if it had previously established any connections to https:// paypal.com.
It is recommended to ignore server certificate error in Fiddler – otherwise it will nag us with the SSL error, the script in the Fiddler itself caused:


Take a look how unhappy the browser is!






Now open the testing applications and see how it would behave! 

If it works correctly, there is a chance, that the developers found this brilliant piece of code in the Internet and put it in the program carelessly:

    static class myHostnameVerifier implements HostnameVerifier {
        public boolean verify(String hostname, SSLSession session) {
            return true;
        }
 }

If the application successfully passed these simple checks, rest safe and assured: only Kazakhstan government is able to sniff your traffic!

Friday, March 13, 2015

Java Null Byte Injection

Java Null Byte Injection is surprisingly overlooked by community. There are solid reasons for that: after all, Java does not use null byte as the End Of String symbol.

However, Java IO libraries hand off strings to the underlying OS, which in most cases uses ‘C’ engine for final processing.  And the ‘C’ processor always rejects anything beyond the null byte character.

Here is almost real-world piece of code:

String txtFileNameVariable = "application.log";
String dirVariable = "./";

if (request.getParameter("dir")!= null && request.getParameter("dir").length()>0)
   dirVariable = request.getParameter("dir")

String PathVariable = dirVariable + File.separator + txtFileNameVariable;
BufferedReader bufferedReader = new BufferedReader(new FileReader(PathVariable));
 


If we manage to assign to the dirVariable wickedly crafted string with null Byte inside it, everything that goes after the null byte will go straight to nowhere, and the first part will be used to open a file we want.

I like this example:
dirVariable = "/etc/passw\0x00";

Now Java will calculate PathVariable as "/etc/passwd\0x00/application.log".
But FileReader – viola - will open  "/etc/passw” file.

Another interesting point is how to pass null byte to Java using HTTP protocol.
To achieve that, an attacker can manipulate HTTP request and embed an HTTP ‘null byte’ equivalent:
So, dir in our example should be "/etc/passw%00", where '%00' is a URL-encoded null byte.

This obvious and well-known problem is confirmed to exist on almost every platform up to JDK 7 (exactly, Java 7u40)
Finally, in May 1013 Oracle fixed the issue: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8014846

If your production server uses Java 7u40 or later, only then you are safe and an exception will be thrown:
java.io.FileNotFoundException: Invalid file path

Thursday, October 9, 2014

How to patch CVE-2014-3500: quick fix of the latest Cordova vulnerability

A lot of mobile application publishers got this email from Google recently:

This is a notification that you have multiple apps, listed below, built on a version of Apache Cordova that contains security vulnerabilities. This includes a high severity cross-application scripting (XAS) vulnerability. Under certain circumstances, vulnerable apps could be remotely exploited to steal sensitive information, such as user login credentials. 
….
Please note, applications with vulnerabilities that expose users to risk of compromise may be considered “dangerous products” and subject to removal from Google Play.

Sure, after such a note from Big G, programmers, which use Apache Cordova (aka PhoneGap), are in a desperate need of upgrade to Cordova 3.5.1 or higher. For some, it might be a problem, as requires a lot of retesting.

Is there other way to mitigate or eliminate the problem? Let’s take a closer look on the issue. 

The vulnerabilities in Cordova, which moved Google to act, were discovered by IBM team and published in Jule, 2014: http://www.slideshare.net/ibmsecurity/remote-exploitation-of-the-cordova-framework

The paper describes 3 vulnerabilities, and the CVE identifiers are:
CVE-2014-3500: Cross-Application Scripting via Android Intents
CVE-2014-3501: Cordova whitelist bypass for non-HTTP URLs
CVE-2014-3502: Data Leak to Other Applications via Android Intent URIs

While all the vulnerabilities are dangerous and entertaining for every hackers or security analyst, it is CVE-2014-3500, which needs to be taken care of ASAP.

Here is the description of the problem:

The WebView object, provided by the Android Framework allows developers to embed a browser within their own apps. This functionality is great for developing portable apps and is the basis of Apache Cordova. The loaded web page of the WebView object is controlled by the WebView.loadUrl() API.

For example, in order to open a website, the developer can write the following code:

String url = "http://www.mysite.com";
webView.loadUrl(url);

When the application is first loaded, it calls the Cordova WebView activity’s loadUrl() function which looks as follows:


public void loadUrl (String url) {
if( url.equals(”about:blank”) || url.startsWith(”javascript:”)) {
  this.loadUrlNow(url);
} else {
String initUrl = this.getProperty (”url” , null);
 // If first page of app , then set URL to load to be the one passed in
  if (initUrl == null) {
this.loadUrlIntoView(url);
}
// Otherwise use the URL specified in the activity’s extras bundle
else {
   this.loadUrlIntoView (initUrl);
}
}
}

One can see that initUrl is populated from a call to getProperty("url", null) which consists of the following code:

public String getProperty (String name, String defaultValue) {
Bundle bundle = this.cordova. getActivity().getIntent().getExtras();
Bundle bundle = this.cordova.getActivity().getIntent().getExtras();
if (bundle == null) {
    return defaultValue ;
}            
Object p = bundle.get(name);
If (p == null ) {
    return defaultValue ;
}
return p.toString();
}

Just meditate here a little. As the url parameter is taken from getIntent().getExtras(), it can be provided externally. This presents a vulnerability which can be exploited whereby a malicious caller could launch the Activity with an Intent bundle that includes a url provided by the caller. The provided URL will then be loaded by Cordova and rendered in the WebView!

To fix it, find every exported Activity, that call WebView.loadUrl() API.

Locate the place where the Activity is instantiated and clean ‘url’ and ‘errorUrl’, provided by a caller. I skipped the part on errorUrl, but you can find it in the IBM paper, they are very similar.

You should add the following lines just before the first call of super.loadUrl():
super.setStringProperty("url", null); 
super.setStringProperty("errorUrl",null); 

=======================================================
Now you application is not vulnerable to CVE-2014-3500, and you won time to update to the latest Cordova version.

Monday, September 15, 2014

Capture and monitor http(s) traffic from Android device through Fiddler using Wi-Fi and ProxyDroid

Developing your own application or making a security assessment of 3rd party application – it is very important to know, what traffic flows from an Android application? There are several ways to do it. We may use different proxies, we may utilize a real device or an emulator, and we might intercept air traffic or direct it through USB cable.

It is often that we need to intercept and analyze traffic from a real device and want to use Wi-Fi for that.
Here is how we may do that using Fiddler.


For this method to work you need a rooted Android device and an infrastructure which allows you to perform socket connections from your phone to your PC – Wi-Fi connection and an ordinary laptop with Wi-Fi module with would do just fine.

2. FIDDLER

Download the free version of Fiddler from Telerik. When running it the first time, make sure you allow Fiddler to accept network connections from the intra- or internet, depending on your infrastructure setup.

Configure Fiddler for incoming connections by going to Tools - Fiddler options... - Connections.. Set the following properties:


  • Fiddler listens on port: 8888 or any other port not in use at your computer
  • Allow remote computers to connect: on


Hit OK and restart Fiddler. 

2. PROXY DROID

Download Proxy Droid to your Android phone. Run it and configure it to point at your Fiddler instance by entering the IP of your computer and its port (8888 by default). Note that you must use the local IP address (often starting with 192.168.* or 10.*).




To test if your PC is reachable from your phone, you may simply ping it using ADB, given that it is connected with USB and have developer mode enabled. Example:
adb shell ping 192.168.1.6
(You need to have enabled reply to ICMP pings in your firewall for this to work. Fiddler may still work even if you get no ping replies)

You can also ping your phone from your PC. Acquire its IP address through this command:
adb shell netcfg

Usually the device eth0 will have the IP address you need.

3. TESTING

Simply start your favorite Android browser and navigate to a random web page. You should get the page presented normally in the browser, and see the HTTP requests line up in Fiddler. All apps will use this proxy now – not only the web browser. 

Fiddler with HTTP traffic log from the device

Whether you’re using this for policing other apps, or for debugging your own applications or 3rd party APIs, this is a technique that should be in every Android developer’s toolbox.


4. TROUBLESHOOTING

And what if the traffic from the targeted Android Applicaion is SSL encrypted?
It might be a very serious problem, if it uses its own SSL infrastructure (i.e. SSL pinning).

However, it might also be an issue with Android HttpsUrlConnection pipeline implementation - and Fiddler, happily, may fix it!
See a recipe in my previous post: How to decrypt SSL traffic from an Android app

Wednesday, September 3, 2014

How to decrypt SSL traffic from an Android app using Fiddler

There are plenty of tutorials on how you can intercept HTTP(s) traffic from Android using Fiddler.
Try this one: http://docs.telerik.com/fiddler/configure-fiddler/tasks/configureforandroid 

 However, it will fail when you try to intercept and decrypt Android SSL traffic coming from an application, and not from a browser.

 It might be that the application uses a certificate pinning – and you are probably cannot decipher this connection. Lost cause!
But more probably, the reason is a bug in the HttpsUrlConnection pipeline implementation.

 To solve the issue, please proceed with the following steps:

1 In Fiddler click "Rules->Customize Rules";
2 Find function OnBeforeResponse in the script
3 Add following code to the function body:
if (oSession.oRequest["User-Agent"].indexOf("Dalvik") > -1 && oSession.HTTPMethodIs("CONNECT")) { oSession.oResponse.headers["Connection"] = "Keep-Alive"; }
4 Save the file and restart Fiddler.

Wednesday, May 8, 2013

How to use PHP in RAILS application

Sometimes it is necessary to integrate PHP code into existing rails application. Using open source and time-tested PHPBB3 is a good example.

To do that, simply disable Passenger for the directory of your PHP application.

      Alias /forum /var/.../forum
      <Location /forum>
        # This allows PHP.
        PassengerEnabled off
        DirectoryIndex index.php 
        allow from all
        Options +Indexes
      </Location>

Enjoy!



Thursday, February 7, 2013

WEBrick is so slow! why?

WEBrick is doing a reverse DNS lookup on connecting IPs by default. In other words, it's trying to see if your IP address is associated with a domain name. This is unnecessary and takes too long, so you can disable it.

Open the file "l/ruby/lib/ruby/1.9.1/webrick/config.rb" and locate the line with ":DoNotReverseLookup => nil".
Change nil to true.

Enjoy!