Tuesday, 22 May 2012

How I brute-forced my own keystore password


How I brute-forced my own keystore password


If, like me, you've been in the unfortunate siutation where you have forgotten your own keystore (or certificate key) password then help may be at hand. After some fruitless searching I decide to write my own piece of software to brute force my keystore certificate.  As I am/have been a Java programmer I decided to write it in the language I knew best, and this is how I did it.

I have made the source code available for anyone who wants it

Loading the keystore


The Java API already has code for loading a keystore, java.security.KeyStore.  The keystore needs to be placed on the classpath (I just stuck it in the root on my Eclipse project)

// Load the keystore in the user's home directory
File file = new File(keystoreName);
is = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, keystorePassword.toCharArray());
return keystore;

The above code simply attempts to load a keystore with the given keystoreName (filename) and keystorePassword.  If the password is incorrect an exception will be thrown.  As I was in a hacky mood, I went with catching the exception and returning null if the password was at fault.  The full method looks like:

public KeyStore loadKeystore(String keystoreName, String keystorePassword) {
FileInputStream is = null;
try {
// Load the keystore in the user's home directory
File file = new File(keystoreName);
is = new FileInputStream(file);
KeyStore keystore = KeyStore.getInstance(KeyStore.getDefaultType());
keystore.load(is, keystorePassword.toCharArray());
return keystore;
} catch (java.security.cert.CertificateException e) {
throw new KeystoreException(e);
} catch (NoSuchAlgorithmException e) {
throw new KeystoreException(e);
} catch (FileNotFoundException e) {
// Keystore does not exist
throw new KeystoreException(e);
} catch (KeyStoreException e) {
throw new KeystoreException(e);
} catch (IOException e) {
if (e.getCause().getMessage().contains("Password verification failed")) {
return null;
}
throw new KeystoreException(e);
} finally {
try {
is.close();
} catch (IOException e) {
// at least we tried
e.printStackTrace();
}
}
}

To check a keystore password this just needs to be called a LOT of times with different configurations of password.  However we will come back to that shortly as, on this occasion, I knew my keystore password but not the password for the certificate it contained.

Loading a keystore key

So I now needed to load the certificate.  Java also has an API for this in the java.security.Key class.  In a similar vein to before, we can wrap this call so it returns null if unsuccessful

public Key loadKey(KeyStore keystore, String keyAlias, String password) {
try {
// get my private key
Key key = keystore.getKey(keyAlias, password.toCharArray());
return key;
} catch (NoSuchAlgorithmException e) {
// let it return null
} catch (KeyStoreException e) {
// let it return null
} catch (UnrecoverableKeyException e) {
// let it return null
}
return null;
}

Assuming we could load the keystore, we can use that to try and load the key.  Either way, we now have methods for attempting to load a keystore of key.  Null will be returned if we are unsuccessful

Brute forcing


Next we need to be able to call one of these methods but alter the password attempt each time.  Firstly I defined the possible characters it might comprise:

// possible characters used
char[] charset = { 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k',
'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w',
'x', 'y', 'z' };

You can add, or take away, any that you want.  We will also need to store the current guess so we can increment it on the next iteration. I've stored them like this

private char[] cs; // Character Set
private char[] cg; // Current Guess
public BruteForce(char[] characterSet, int guessLength) {
cs = characterSet;
cg = new char[guessLength];
Arrays.fill(cg, cs[0]);
}

Next we need to increment the current guess each time so we are trying a different password, making sure we try every combination

protected void increment() {
int index = cg.length - 1;
while (index >= 0) {
if (cg[index] == cs[cs.length - 1]) {
if (index == 0) {
cg = new char[cg.length + 1];
Arrays.fill(cg, cs[0]);
break;
} else {
cg[index] = cs[0];
index--;
}
} else {
cg[index] = cs[Arrays.binarySearch(cs, cg[index]) + 1];
break;
}
}
}

The above method increments the currentGuess array each time it is called, making it 1 larger if necessary.  This means we try every combination of every character in the array eg
aa
ab
ac
ad

and so on

The current guess can then be used to attempt to load the keystore, or key.  If null is returned the password was wrong and the next guess can be attempted eg

public synchronized String getNextAttempt() {
increment();
return String.valueOf(cg);
}
String attempt = attack.getNextAttempt();
boolean found = source.attempt(attempt);

Notice the use of the synchronized key word - I added this as I ran it in a multithreaded environment.  Making the method synchronized means that the incrementing and getting the next guess are atomic, so no other thread can access the next guess at the same time.  This ensures that none are missed

Putting this all together I managed to brute force a 7 character password in about 5 hours (using 100 threads on an i7 PC)

I built a mini-framework around it that I've put on sourceforge.  I also added an heuristic brute force attack (using keywords I might use in a password) until I fouind that it wasn't any of those, leaving me to have to brute force it. Feel free to use it.  If anyone wants to take on developing it further let me know and I'll give you access to the repository


Thursday, 10 May 2012

Installing and using mobilize.js to transform a desktop site to a mobile site


Installing and using mobilize.js to transform a desktop site to a mobile site

mobilize.js offers a neat and simple method of creating a mobile optimised website with very little change to the main desktop site. With a few lines of javascript and some css you can create a mobile optimised site without having to maintain 2 different sets of content.

However the instructions on the official site aren't the best. So with some digging I managed to transform -

From this (Firefox on my laptop):



To this (Android browser on my Samsung Galaxy Nexus):



with no html changes other than adding some <script> tags to the <head> element.  Plus automatic browser detection to display either site depending on the browser used - mobile, or desktop

Here are some step-by-step instructions on getting it working.

Why would you want to?

So going back to the beginning, these were my requirements:  I wanted to create a mobile optimised site but, as I already had a main desktop site, I didn't really want to maintain 2 sites and duplicate the content.  I also needed mobile browser detection so that the correctly optimised site would be served.

The problem, however, is that my site was static (ie was all html based, not dynamic in terms of PHP or Java etc) so I couldn't just create a new set of basic pages and pull in my content.  A google search led me to mobilize.js (http://mobilizejs.com/). This looked ideal. Although my site wasn't built with WordPress or Sphinx (for which mobilize have plugins) it offered a method for using it with custom web sites. Ideal I thought

As it turns out however, it wasn't as ideal as I thought because the official documentation is quite confusing. A google search didn't help as everyone else was confused too.  So I did what any geek would do, I downloaded the source from github and set to work.

Firstly, I discovered a couple of things that are not very clear in the official documentation:

i. The official documentation pretty much expects that you will use the official cloud hosted solution.  Most of the instructions assume you know this and want to do this.  Therefore there is very little documentation on installing it, only on integrating it into your site
ii. If you don't want to use the official cloud hosted solution because you want to host it yourself, you are more-or-less on your own.  There are a few instructions (http://cdn.mobilizejs.com/docs/trunk/manual/hosting.html) but these are not comprehensive enough to get you started

So, if you're trying to use mobilize.js and are wondering where the 'download' button is, the following should help you

How-To

1. Cloud hosting

mobilize.js is installed on a server that mobilize provide.  If you are happy using their cloud hosted service (which is free) then you can skip step 2 and move onto step 3
However, if, like me, you don't want to use someone else's hosted solution and would rather host it yourself then step 2 will tell you how to do that

2. Self-hosting

As mobilize.js is a javascript-based solution you don't need a special server to host it. I am hosting it on a standard Apache server along with my web content. The work of transforming the site is done on the client using javascript, so there are no specific requirements for the server other than the ability to host javascript (which you likely have anyway if you are serving a website).  This was a plus for me as it meant I didn't have to pay any extra for serving it

As mobilize don't provide a distribution as such, it has to be compiled from source, which they provide on github.  As I already had to do these steps (after I'd worked it out!),  I have added the mobilize.js library for download from my google drive here

If you just want to download the library, do that, extract it then go to step d.  Otherwise steps a-c show you how I created the library from the mobilize.js source

a. Download the source

First thing you need to do is download the source from the official github repository (you can just download the .zip if you don't have a git client)

b. extract source if necessary

If you downloaded the zip file, extract the zip file if necessary.  You will also need Python installed on your machine. My Ubuntu machine already had it installed, but you may need to install it: http://www.python.org/getit/

c. Build the mobilize.js library

Create the library using the release.py python script in the folder you extracted from the zip file, setting the localdeploy option (if neither of these work, hopefully you can work out the exact command, just make sure you run the right script with the localdeploy option set to true):
on linux: ./release.py localdeploy=true
on windows: python release.py localdeploy.true
This will create a folder in the <extracted zip folder>/releases folder called (oddly) 'localdeploy=true'.  This is your mobilize.js library. I suggest renaming it to something sensible! I've called mine 'mobilize'

d. Copy the library to your source code

Copy the mobilise.js library to your website source.  Mine is under 'js'



e. Link to the library

You will need to tell the library where the source is located by setting a baseURL option using javascript
mobilize.cdnOptions.baseURL="http://localhost/js/mobilize";
 When you deploy this, the URL will need to be the path to your website, so you will have to change it.  However it needs to be placed on each page, so you would have to change it on every page. So I've put mine in a separate javascript file (called mobilize.post.call.js) so I only have to change it in one place

 Then I have placed a reference to that file on my html page in the <head> tag, ie:
<head>
<script type="text/javascript" src="/js/mobilize.post.call.js"></script>
</head>
 Now I only have 1 place where I need to change between localhost and my final URL

You are now ready to start integrating your hosted mobilize.js code into your website.  The following applies whether you are hosting it yourself or not, there is no difference from here onwards other than the URLs used

3. Minimum integration steps

a. Add the mobilize.js script tag

Add a script tag to each page to tell it to use mobilize.js
For self-hosting:
<script type="text/javascript" src="/js/mobilize/js/mobilize.core.min.js"></script> 
               (or wherever you placed it)

For mobilize hosting:
<script type="text/javascript" src="http://cdn.mobilizejs.com/releases/0.1/js/mobilize.core.min.js"></script>

b. Tell mobilize how to construct the mobile page

Create a javascript file to tell mobilize how to construct the mobile page.  I have called mine mobilize.weblore.js

Either way, the basic structure is something along the lines of:
mobilize.extend(mobilize, {
constructBody : function() {
// Map content elements to jQuery Mobile
// div[data-role=content] here
// Map different elements to jQuery Mobile theme
this.constructHeader();
this.constructContent();
this.constructFooter();
},
constructHeader : function() {
var mobileHeader = $("#mobile-body div[data-role=header]");
},
/**
* Move content area from web site to mobile site
*/
constructContent : function() {
var mobileContent = $("#mobile-body div[data-role=content]");
},
constructFooter : function() {
var mobileFooter = $("#mobile-body div[data-role=footer]");
}
});

This tells mobilize how to construct a mobile page using jquery mobile. The default template provided my mobilize looks like:
<div id="mobile-body">
<!-- http://jquerymobile.com/demos/1.0a3/#docs/pages/docs-pages.html -->
<div data-role="page">
<div data-role="header"></div>
<div data-role="content"></div>
<div data-role="footer"></div>
</div>
</div>
So the javascript above maps the divs from the template. You can override the template with a local one using the mobilize.cdnOptions.template option, but I have just gone with the default

We will come back to how to utilise the above template and javascript to display the site

c. Tell mobilize where the construction script is

Create a mobilizeCustomInit() javascript function to tell mobilize where your javascript file is that constructs the page (from step b).  You could place this in a <script> tag on each page, but using a separate .js file means you can reuse it on each page and just link it with a <script> call to that file. I have called mine mobilize.pre.call.js
function mobilizeCustomInit() {
mobilize.cdnOptions.javascriptBundles.push("http://<your website>/js/mobilize.weblore.js");
mobilize.cdnOptions.cssBundles.push("http://<your website>/mobile.css");
}
Simply replace the <your website> with the URL of your site (and change the path if necessary depending on where you put the .js file)

You will also see that I have added a custom .css file here. As mobilize removes any .css from the original page, you need to specify your .css here, even if it is the same as the desktop site css file. I have created a mobile-specific one I've called mobile.css

d. Link javascript and HTML

Link the above javascript to the html pages. If you have used separate files, it will look something like this:
<!-- the mobilizeCustomInit() from step c -->
<script type="text/javascript" src="/js/mobilize.pre.call.js"></script>
<!-- the call to mobilize from step a -->
<script type="text/javascript" src="/js/mobilize/js/mobilize.core.min.js"></script>
<!-- the call to set the baseURL if self-hosting -->
<script type="text/javascript" src="/js/mobilize.post.call.js"></script>

2 things to note here:
- they must be in this order
- mobilize.post.call.js only applies if you are self-hosting

e. Check it works

From this point you can try your new mobile page. To test locally you need a local mobile browser. One way is to use firefox and the User Agent Switcher plugin (http://chrispederick.com/work/user-agent-switcher/). You can then set firefox to act like an iPhone browser. mobilize will detect the user agent and display the mobile site instead of the desktop site

By default the page rendered displays nothing in the <body> tag, so you will currently have a blank page

f. Add html elements to the mobile page

Now all you need to do is use jquery mobile to set elements from your pages into the structure using the script in b. This will enable the content you want available on the mobile site

jquery selectors (http://www.w3schools.com/jquery/jquery_ref_selectors.asp) are used to select elements from the html page and display them on the mobile page

For example:
constructHeader : function() {
// heading
var heading = $('#Top');
// get a handle on the header
var mobileHeader = $("#mobile-body div[data-role=header]");
// Set heading
mobileHeader.append(heading);
},
takes the <div id="top"> element from my html page and adds it to the top section of the mobile page (as per the template in b)

You just need to keep doing this for any elements you want displayed, adding them to the section you require, in the order you require

This uses standard jquery, so any help you need in obtaining elements to display can be found on the jquery pages (you don't need to add jquery to your site, it is pulled in by mobilize.js).  You can just style the existing elements differently using a different css if required

It works!

Once you've followed these steps, you should now have an operational mobile site that automatically detects mobile browsers and displays the relevant site.  Once I had figured out how (which I've now shared with you) it was very easy

Now I have a dekstop site and a mobile site, both using the same content. So any updates I make are immediately available on both sites. Pretty neat

I have hopefully made this as easy to follow as possible. Both jquery and mobilize have additional features that I haven't mentioned, but this should at least get you going with a working mobile site transformation.  Any error or comments etc, just let me know