If you have been following my guide until now, probably you have known enough to start working with basic challenges. Let's get to some cracking. Today, I'll show you how to code a brute-force program.
I created this little crackme so we can have something to play with: CrackMe1. For simplicity, it's just a simple console application. If you run it, it will ask for a password and check if the password is correct.
Download the file and decompile it with jad, you'll see the code:
// Decompiled by Jad v1.5.8e. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.geocities.com/kpdus/jad.html
// Decompiler options: packimports(3)
// Source File Name: CrackMe1.java
import java.io.*;
public class CrackMe1
{
public CrackMe1()
{
}
public static boolean check(String s)
{
if(s.length() != 4)
return false;
int n = 1;
for(int i = 0; i < s.length(); i++)
n *= s.charAt(i);
n ^= s.hashCode();
return n == 0x705a69c;
}
public static void main(String args[])
throws IOException
{
System.out.print("Enter password: ");
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String s = reader.readLine();
if(check(s))
System.out.println("Congrats!");
else
System.out.println("Go to hell!");
}
}
Good thing in Java all method names are meaningful. The code is self-explanation. The program reads a string from standard input, and check if it is the right password. The string must have a length of 4 characters. And if you take the product of the ASCII codes and xor with the hashCode of the string the result must be 0x705a69c (117810844).
Your first attempt to write a bf program should result in something like:
public class CrackMe1Solver {
public static boolean check(String s) {
// copy the decompiled code here
}
public static void main(String[] args) {
char[] c = new char[4];
// OK, let's assume the password is all lowercase
for (c[0] = 'a'; c[0] < 'z'; c[0]++)
for (c[1] = 'a'; c[1] < 'z'; c[1]++)
for (c[2] = 'a'; c[2] < 'z'; c[2]++)
for (c[3] = 'a'; c[3] < 'z'; c[3]++) {
// this is how you create a string from an array of characters
String s = new String(c);
if (check(s)) System.out.println(s);
}
}
}
This code works fine, try running it and you'll get the solution (a very famous word :P). However, that code is not the best. I'll show you how to make it better.
Firstly, it's kinda duplicate and inconvenient to use the same constants for bf range (a-z). A better practice is to declare them as constants so that you can change them easily. Thus:
// Constants are declared with the final keyword
// and conventionally written in uppercase
final char MIN = 'a';
final char MAX = 'z';
for (c[0] = MIN; c[0] < MAX; c[0]++)
...
One more thing, it's fortunate that the method check() is declared public and static. This means you can reuse it from another class instead of writing it again.
Here's the final code:
public class CrackMe1Solver {
public static void main(String[] args) {
char[] c = new char[4];
final char MIN = 'a';
final char MAX = 'z';
for (c[0] = MIN; c[0] < MAX; c[0]++)
for (c[1] = MIN; c[1] < MAX; c[1]++)
for (c[2] = MIN; c[2] < MAX; c[2]++)
for (c[3] = MIN; c[3] < MAX; c[3]++) {
String s = new String(c);
if (CrackMe1.check(s)) System.out.println(s);
}
}
}