package no.ntnu.item.bruteforce; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOException; import java.security.Security; import java.util.Stack; import no.ntnu.item.threads.BruteForceThread; import no.ntnu.item.threads.DictionaryThread; public class BruteForce { public static int THREADS; public static int MAX_WORD_LENGTH; public static boolean found = false; public static FileReader fr; public static BufferedReader buf; public static long start; public static double time; public static long words_read; public static byte[] salt; public static byte[] cipher; public static Stack<String> words; private char[] current_word; private BruteForceThread[] bf_threads; public BruteForce(String[] args) throws IOException { File tmp = new File(args[0]); if (!tmp.exists()) { System.out.println("ERROR: Target file does not exist!"); printHelp(); } FileInputStream in = new FileInputStream(tmp); byte[] b = new byte[(int) tmp.length()]; in.read(b); in.close(); salt = new byte[16]; cipher = new byte[b.length - salt.length]; System.arraycopy(b, 0, salt, 0, salt.length); System.arraycopy(b, salt.length, cipher, 0, cipher.length); words_read = 0; start = 0; } public void bruteForceAttack(String[] input) { System.out.println("************************************************"); System.out.println("\tRunning brute force attack"); System.out.println("************************************************"); current_word = new char[1]; words = new Stack<String>(); THREADS = Integer.parseInt(input[2]); bf_threads = new BruteForceThread[THREADS]; MAX_WORD_LENGTH = Integer.parseInt(input[1]); for (int i = 0; i < bf_threads.length; i++) { bf_threads[i] = new BruteForceThread("bf" + i); } waitForBFThreads(); while (!found) { if (current_word.length > MAX_WORD_LENGTH) break; pushWord(current_word.length - 1); char[] tmp = new char[current_word.length + 1]; tmp[tmp.length - 1] = ' '; System.arraycopy(current_word, 0, tmp, 0, current_word.length); current_word = tmp; } } public void dictionaryAttack(String[] input) { System.out.println("************************************************"); System.out.println("\tRunning dictionary attack"); System.out.println("************************************************"); File dict = new File(input[1]); THREADS = Integer.parseInt(input[2]); if (dict.exists()) { try { fr = new FileReader(dict); buf = new BufferedReader(fr); start = System.currentTimeMillis(); for (int i = 0; i < THREADS; i++) { new DictionaryThread("dict" + i); } } catch (FileNotFoundException e) { e.printStackTrace(); } } else { System.out.println("ERROR: Dictionary file does not exist!"); printHelp(); System.exit(0); } } public boolean pushWord(int pos) { // Iterating over a chosen space of characters for (int i = 32; i < 127; i++) { current_word[pos] = ((char) i); if (pos == 0) { synchronized (words) { words.push(new String(current_word)); if (words.size() == THREADS && start == 0) { start = System.currentTimeMillis(); words.notifyAll(); } } } if (pos > 0) { if (pushWord(pos - 1)) return true; } } return false; } private void waitForBFThreads() { while (true) { int done = 0; for (BruteForceThread bft : bf_threads) { if (bft.thread.getState() == Thread.State.WAITING) { done++; } if (done == bf_threads.length) { return; } } } } public static boolean isInteger(String str) { try { Integer.parseInt(str); return true; } catch (NumberFormatException e) { return false; } } public static void printHelp() { System.out.println("************************************************"); System.out.println("\t\tHELP"); System.out.println("************************************************"); System.out.println("o Manual brute force attack"); System.out.println("\t [1 arg]: Path to target file"); System.out.println("\t [2 arg]: Maximum word length"); System.out.println("\t [3 arg]: Number of threads"); System.out.println("o Dictionary attack"); System.out.println("\t [1 arg]: Path to target file"); System.out.println("\t [2 arg]: Path to dictionary file"); System.out.println("\t [3 arg]: Number of threads"); System.out .println("\nNOTE: Make sure you have installed the Java(TM) \nCryptography Extension (JCE) Jurisdiction Policy \nFiles and that you are using Bouncy Castle as \nprimary JCE provider prior to execution. Check \nout [0] for more information.\n\n[0] http://znjp.com/mcdaniel/BC.html"); } public static void printSuccess(String word) { System.out.println("SUCCESS! Password is { " + new String(word) + " }"); System.out.println("Read " + words_read + " passwords in " + time + " seconds"); System.out.println("Average speed: " + words_read / time + " passwords/second"); } public static void printFail() { time = (System.currentTimeMillis() - start) / 1000.0; System.out.println("Did not find password"); System.out.println("Read " + words_read + " passwords in " + time + " seconds"); System.out.println("Average speed: " + words_read / time + " passwords/second"); } public static void main(String[] args) throws IOException { Security.insertProviderAt( new org.bouncycastle.jce.provider.BouncyCastleProvider(), 1); if (args.length == 3 && !isInteger(args[0])) { BruteForce bf = new BruteForce(args); if (isInteger(args[1])) { bf.bruteForceAttack(args); } else { bf.dictionaryAttack(args); } } else { printHelp(); } } }