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