Wednesday 28 November 2007

Basic IO & Dictionary Attack

Hey guys,

Now that you have known enough Java to write simple programs that do the calculation for you, let's get to know some basic input/output. Today I'll show you how to read data from text files to write a simple dictionary attack program.

In Java every input/output task is handled using streams. In the previous programs, actually I have used 2 streams: System.in, which is an InputStream, and System.out, an OutputStream.

To read/write from streams it is easiest to use a reader/writer. When you are working with text streams it's even more convenient to use BufferedReader and BufferedWriter. These classes allow you to read/write the data on a line-by-line basis.

Here's how you read a text file:
// You need to import this package for the IO classes
import java.io.*;
...
// Most IO methods throw IOExceptions,
// you don't need to worry about them for now,
// so just use this throws clause
public static void main(String[] args) throws IOException {
// Create a FileReader to read the file
FileReader fr = new FileReader("path/to/file");
// Use a BufferedReader for the convenient readLine() method
BufferedReader br = new BufferedReader(fr);
// Declare a string to store every line read from the file
String s;
// Read the file until the end of file is reached
// i.e. until the readLine() method returns null
while ((s = br.readLine()) != null) {
// Do something with the string
System.out.println(s);
}
// Close the reader to release the system resource
br.close();
}
Now let's get some practice!

In the last post I have shown you how to write a brute-force program. However, that method only works when the password is brute-forcable, probably no more than 8 characters. When the password is longer, brute-forcing will take days, or even months, or years :P Another common technique is dictionary attack.

Most passwords are based on common words to be easily memorized. Therefore instead of trying all character combination, you can use a wordlist, manipulate the words, and check them. This method is generally more effective than brute-forcing, and takes less time.

If you Google for wordlist, you can find many of them. I myself prefer the argon wordlists at http://www.theargon.com/achilles/wordlists. For quick cracking, you can use english.txt. Or you can use the huge wordlists in theargonlists/, which are 245 megs and 2 gigs when uncompressed.

Now let's pwnzor this little crackme.

If you decompile it, you'll get something like this:
// 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: CrackMe2.java

import java.io.PrintStream;
import java.util.Scanner;

public class CrackMe2
{

public CrackMe2()
{
}

public static int crc(String s)
{
byte bytes[] = s.getBytes();
int crc = 0;
byte abyte0[];
int j = (abyte0 = bytes).length;
for(int i = 0; i < j; i++)
{
byte b = abyte0[i];
crc = crc >>> 8 ^ table[(crc ^ b) & 0xff];
}

return crc;
}

public static void main(String args[])
{
System.out.print("Enter password: ");
Scanner scanner = new Scanner(System.in);
String s = scanner.next();
if(crc(s) == 38983)
System.out.println("Good job!");
else
System.out.println("Go to hell!");
}

private static final int table[] = {
0, 49345, 49537, 320, 49921, 960, 640, 49729, 50689, 1728,
1920, 51009, 1280, 50625, 50305, 1088, 52225, 3264, 3456, 52545,
3840, 53185, 52865, 3648, 2560, 51905, 52097, 2880, 51457, 2496,
2176, 51265, 55297, 6336, 6528, 55617, 6912, 56257, 55937, 6720,
7680, 57025, 57217, 8000, 56577, 7616, 7296, 56385, 5120, 54465,
54657, 5440, 55041, 6080, 5760, 54849, 53761, 4800, 4992, 54081,
4352, 53697, 53377, 4160, 61441, 12480, 12672, 61761, 13056, 62401,
62081, 12864, 13824, 63169, 63361, 14144, 62721, 13760, 13440, 62529,
15360, 64705, 64897, 15680, 65281, 16320, 16000, 65089, 64001, 15040,
15232, 64321, 14592, 63937, 63617, 14400, 10240, 59585, 59777, 10560,
60161, 11200, 10880, 59969, 60929, 11968, 12160, 61249, 11520, 60865,
60545, 11328, 58369, 9408, 9600, 58689, 9984, 59329, 59009, 9792,
8704, 58049, 58241, 9024, 57601, 8640, 8320, 57409, 40961, 24768,
24960, 41281, 25344, 41921, 41601, 25152, 26112, 42689, 42881, 26432,
42241, 26048, 25728, 42049, 27648, 44225, 44417, 27968, 44801, 28608,
28288, 44609, 43521, 27328, 27520, 43841, 26880, 43457, 43137, 26688,
30720, 47297, 47489, 31040, 47873, 31680, 31360, 47681, 48641, 32448,
32640, 48961, 32000, 48577, 48257, 31808, 46081, 29888, 30080, 46401,
30464, 47041, 46721, 30272, 29184, 45761, 45953, 29504, 45313, 29120,
28800, 45121, 20480, 37057, 37249, 20800, 37633, 21440, 21120, 37441,
38401, 22208, 22400, 38721, 21760, 38337, 38017, 21568, 39937, 23744,
23936, 40257, 24320, 40897, 40577, 24128, 23040, 39617, 39809, 23360,
39169, 22976, 22656, 38977, 34817, 18624, 18816, 35137, 19200, 35777,
35457, 19008, 19968, 36545, 36737, 20288, 36097, 19904, 19584, 35905,
17408, 33985, 34177, 17728, 34561, 18368, 18048, 34369, 33281, 17088,
17280, 33601, 16640, 33217, 32897, 16448
};

}
The crackme checks the password using the CRC16 algorithm, which is a pretty weak one. Let's crack it using dictionary attack. For simplicity you can skip the string manipulation for now and use it as is. With everything you have learned, hopefully you'll end up with the following code:
import java.io.*;

public class CrackMe2Solver {

public static void main(String[] args) throws IOException {

BufferedReader reader = new BufferedReader(new FileReader("path/to/english.txt"));
String s;
while ((s = reader.readLine()) != null)
if (CrackMe2.crc(s) == 38983) System.out.println(s);
reader.close();

}

}
I guess that's good enough for now. Maybe you can try and crack some TBS challs and get the smiley now :)

Friday 23 November 2007

BF it!

Hey guys,

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);
}
}

}

Tuesday 20 November 2007

Java control structures

Hey guys, today's lesson will be about Java control structures.

Just like other languages, Java has support for if-then-else, switch case, for loop and while loop.

Here is an example of an if-then-else:
if (x <= 1336) {
System.out.println("Too low!");
} else if (x >= 1338) {
System.out.println("Too high!");
} else {
System.out.println("You got it!");
}
Can you interpret the example? Every number less than or equal to 1336 is considered too low, and every number greater than or equal to 1338 is considered too high. A number between 1336 and 1338 (probably 1337 :P) is the right solution.

A few things you should remember:
- The if expression must be enclosed within round brackets () and it must return a boolean value.
- The curly brackets {} are optional if there is only 1 statements inside. However it is a good practice to always use them.

When you are comparing a variable against many values you can use a switch case instead of multiple if-then-else. Here's an example of switch case:
switch (x) {
case 1336:
System.out.println("A little too low!");
break;
case 1338:
System.out.println("A little too high!");
break;
case 1337:
System.out.println("You got it!");
break;
default:
System.out.println("So far :P");
break;
}
Note that the break is important. Without it the control flow will fall through to the next case.

Most of the time when working on a challenge you will need loops to do something repeatedly. In Java you can use 2 types of loop: for loop and while loop.

The for loop is usually used when counting is involved. For example, the following code prints all the numbers from 0 to 1337:
for (int i = 0; i <= 1337; i++)
System.out.println(i);
The for loop consists of 3 parts:
  • The first part (int i = 0) is the initialization. It initializes the value at the beginning of the loop.
  • The second part (i <= 1337) is the termination condition. When its value is false the loop will terminate.
  • The last part (i++) is the increment. After each iteration of the loop is done this statement will be executed once.
You can omit any part of the loop, as long as it won't lead to infinite loop :P If you want the loop to terminate under another condition you can use the break statement. The above example can be rewritten like this:
int i = 0;
for (;;) {
System.out.println(i);
if (i > 1337) break;
i++;
}
Basically you can do everything with just the for loop. But for convenience you might want to use the while loop too:
int i = 0;
while (i <= 1377) {
System.out.println(i);
i++;
}
Here is another variation of the while loop, with the condition checked at the end of each iteration:
int i = 0;
do {
System.out.println(i);
i++;
} while (i <= 1337);
You can use break inside while loops too:
int i = 0;
while(true) {
System.out.println(i);
i++;
if (i > 1337) break;
}

Saturday 17 November 2007

Java basics: data types and operators

Hey guys, today I'll give you a quick view of Java data types and operators.

In Java, there are 3 main data types: primitive, object and array.
  • Primitive: byte, short, int, long, float, double, char and boolean. You can declare a primitive variable like this:
    int a = 1337;
    double b = 13.37;
    char c = '$';
    boolean d = true;
  • Object: Java is object-oriented, therefore you can see objects everywhere. Even string is a special type of object. You can declare an object with the keyword new:
    Object o = new Object();
    Applet a = new Applet();
    String s = new String("Hello world!");
    String t = "Hello world!"; // String is special, after all ;)
  • Array: Just like in other languages, you can use arrays in Java too. An array is declared with the keyword new, and you can use an index to access an array's member:
    int[] a = new int[2];
    a[0] = 13; // note that array indexes start at 0
    a[1] = 37;
    Object[] o = new Object[2]; // array of objects
    o[1] = "Hello worrd!";
    o[2] = new Integer(1);
    int[][] b = new int[2][2]; // multidimensional array
    b[0][0] = 1;
    b[0][1] = 3;
    b[1][0] = 3;
    b[1][1] = 7;
Here are some common operators that you can use on them:

+ (addition, also string concatenation), - (subtraction), * (multiplication).
/ division, note that it returns the integral quotient if applied between integral values.
% (modulo) returns the remainder in division.
= (assignment) assigns a value to a variable.
++ (increment) increments a variable by 1.
-- (decrement) decrements a variable by 1.
== (equal), != (not equal), < (less than), > (greater than), <= (less than or equal), >= (greater than or equal)
! (not operator for boolean)
&& (conditional and), || (conditional or)
bitwise operators: ~ (not), & (and), | (or), ^ (xor), << (shift left), >> (shift right), >>> (unsigned shift), you can see an explanation about them here.

Confused? Try using them in your program and see how they work. You can use the HelloWorld template in the previous lesson :)

Thursday 15 November 2007

Hello world!

Hey guys,

Today I will teach you how to write your first program in Java, compile it, and then decompile with jad.

Open your favourite text editor, and type (or copy&paste) the following code:
public class Hello {

public static void main(String[] args) {

System.out.println("Hello world!");

}

}
Save the code as Hello.java, and open a console window. Navigate to the directory where you saved the file and execute the following command to compile the program:
javac Hello.java
Hopefully the program will be compiled without any errors. You'll notice that another file named Hello.class will be created in the same directory. To run it, type the following command:
java Hello
Of course, the program will run and output "Hello world!" :)

Congratulations, you have successfully written, compiled and executed your first Java program. It is very simple, but probably you can use it as a template for other programs in the future.

Now it's time to decompile it and see how the code looks like. From the console, type
jad Hello.class
A new file named Hello.jad will be created. Have a look at it
// Decompiled by Jad v1.5.8f. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://www.kpdus.com/jad.html
// Decompiler options: packimports(3)
// Source File Name: Hello.java

import java.io.PrintStream;

public class Hello
{

public Hello()
{
}

public static void main(String args[])
{
System.out.println("Hello world!");
}
}
Almost the same as the original code. Cool huh? :)

Wednesday 14 November 2007

Welcome

Hey guys,

As you all know, I have always wanted to write a Java applet tutorial, and many people have been waiting for it. But the tut has been delayed for so long. Simply because I didn't really know what I should include in the tutorial.

Basically an applet is just a Java application. So to solve it you just need to know Java. Therefore instead of a tutorial I decided to create a blog for it. Hopefully you'll find everything you need about Java here :)

In this first post I would like to equip you with all the tools and resources needed for solving Java applets.

Firstly to run Java applets you will need the Java Runtime Environment (JRE). It might have been shipped with your browser but it's always good to have the latest version. You can check your current version by typing this from a console:
java -version
But probably you will not just want to run Java applets, but to compile Java programs as well, to understand what the applets actually do. For this you will need the Java Development Kit (JDK), which also includes the JRE.

You can get the JDK from here: http://java.sun.com/javase/downloads/index.jsp. At the moment JDK 6 is what you need.

Java programs are compiled into Java bytecode, and you will need a decompiler to decompile the code back to Java language. There are many Java decompilers out there but jad is probably the best one. Most others decompilers use jad as the backend. The jad homepage is at http://www.kpdus.com/jad.html. You can also find the graphical frontends for jad and plugins for IDEs there too.

Talking about IDEs.. basically you can write Java programs using any text editor but a good IDE will make things easier. Here are the IDEs that I recommend:
  • JCreator: http://www.jcreator.com - an excellent lightweight IDE, get this if you are learning Java. Unfortunately it only runs on the Windows platform.
  • Eclipse: http://www.eclipse.org - an excellent heavyweight IDE, but probably you should not use it as a beginner, because it hides you from many essential things.
  • Netbeans: http://www.netbeans.org - also a heavyweight IDE offering similar features to Eclipse, but I prefer Eclipse because it's faster.
OK, now you basically have all the necessary things. It's time to start learning Java. Of course I'll help you but here are some resources that you'll probably find useful along the way: