From ea9646bfd92774188e3685135347ff316e4c468b Mon Sep 17 00:00:00 2001 From: Peter Boraros Date: Wed, 9 Nov 2011 04:41:42 +0100 Subject: [PATCH] Import brute-force cracker. --- bin/cracker.sh | 3 + src/cz/cvut/keyczar/homework/Cracker.java | 73 +++++++ src/cz/cvut/keyczar/homework/CrackerCore.java | 31 +++ src/cz/cvut/keyczar/homework/HmacCracker.java | 195 ++++++++++++++++++ src/cz/cvut/keyczar/homework/Stats.java | 99 +++++++++ 5 files changed, 401 insertions(+) create mode 100644 bin/cracker.sh create mode 100644 src/cz/cvut/keyczar/homework/Cracker.java create mode 100644 src/cz/cvut/keyczar/homework/CrackerCore.java create mode 100644 src/cz/cvut/keyczar/homework/HmacCracker.java create mode 100644 src/cz/cvut/keyczar/homework/Stats.java diff --git a/bin/cracker.sh b/bin/cracker.sh new file mode 100644 index 0000000..c5e75d1 --- /dev/null +++ b/bin/cracker.sh @@ -0,0 +1,3 @@ +#!/bin/bash +. libs.sh +java -cp $CP cz.cvut.keyczar.homework.Cracker $@ \ No newline at end of file diff --git a/src/cz/cvut/keyczar/homework/Cracker.java b/src/cz/cvut/keyczar/homework/Cracker.java new file mode 100644 index 0000000..79ed1e5 --- /dev/null +++ b/src/cz/cvut/keyczar/homework/Cracker.java @@ -0,0 +1,73 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package cz.cvut.keyczar.homework; + + +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; + +/** + * + * @author pborky + */ +public class Cracker { + + public static final String MESSAGE = "Hello world!"; + + /** + * @param args the command line arguments + */ + public static void main(String[] args) { + + Runnable messageVerifier; + if (args.length < 4) { + System.out.println("Usage:"); + System.out.println("cracker [ [ [ ... ]]]"); + System.out.println("\t, - u know"); + System.out.println("\t - what to send"); + System.out.println("\t - max. number of iterations per one byte"); + System.out.println("\t - is hex of the signature`s byte"); + System.out.println("\tnote: you must provide at least 5 bytes of signature"); + System.exit(-1); + } + String host = args[0]; // + int port = Integer.parseInt(args[1]); // + String msg = args[2]; // message + int iMax = Integer.parseInt(args[3]); // max. iterations + + byte[] sig = null; + + if (args.length>3) { + sig = new byte[args.length-4]; + for (int i = 4; i < args.length; i++) { + sig[i - 4] = (byte)Integer.parseInt(args[i],16); + } + } + char[] m = msg.isEmpty()?MESSAGE.toCharArray():msg.toCharArray(); + messageVerifier = createMessageGenerator(host, port, iMax, sig, m); + messageVerifier.run(); + } + + + private static Runnable createMessageGenerator(String host, int port, int iMax, byte[] signature, char[] msg) { + try { + Socket sock; + sock = new Socket(host, port); + System.out.println("Connected"); + + InputStream is = sock.getInputStream(); + OutputStream os = sock.getOutputStream(); + + return new HmacCracker(os, is, iMax, signature, msg); + } + catch (Throwable t) { + System.err.println("Can't load Generator: " + t.getMessage()); + throw new RuntimeException(t); + } + } + +} diff --git a/src/cz/cvut/keyczar/homework/CrackerCore.java b/src/cz/cvut/keyczar/homework/CrackerCore.java new file mode 100644 index 0000000..da7d865 --- /dev/null +++ b/src/cz/cvut/keyczar/homework/CrackerCore.java @@ -0,0 +1,31 @@ +package cz.cvut.keyczar.homework; + + +import java.util.ArrayList; +import java.util.List; + +public class CrackerCore { + public static byte[] select(List stats) { + // each item of the stats must have length exactly Byte.MAX_VALUE + double[] means = Stats.mean(stats); + + if (means.length >= Byte.MAX_VALUE) { + throw new RuntimeException("Something gone wrong. Expecting exactly "+ Byte.MAX_VALUE+ " items."); + } + + ArrayList idx = new ArrayList(); + // TODO: implement your code here ************************** + // for each byte test the condition + for (byte i = 0; i< means.length; i++) { + idx.add(i); + } + // ********************************************************* + + if (idx.isEmpty() || idx.size() > 6) return null; + + byte[] result = new byte[idx.size()]; + int i = 0; for (byte b : idx) result[i++] = b; + + return result; + } +} diff --git a/src/cz/cvut/keyczar/homework/HmacCracker.java b/src/cz/cvut/keyczar/homework/HmacCracker.java new file mode 100644 index 0000000..6740c8e --- /dev/null +++ b/src/cz/cvut/keyczar/homework/HmacCracker.java @@ -0,0 +1,195 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package cz.cvut.keyczar.homework; + +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * + * @author pborky + */ +public class HmacCracker implements Runnable { + + private final OutputStream outputStream; + private final InputStream inputStream; + byte[] message; + int hmacPtr = 0; + byte[] hmac; + int maxIterations; + int totalIterations = 0; + + public HmacCracker(OutputStream outputStream, InputStream inputStream, int iMax, byte[] signature, char[] msg) { + this.outputStream = outputStream; + this.inputStream = inputStream; + try { + for (int r=this.inputStream.read(); r!='\n'; r=this.inputStream.read()) { } + } catch (IOException e) { + throw new RuntimeException(e); + } + this.message = new byte[msg.length]; + for (int i=0; i 25) { + throw new IllegalArgumentException("You may give up to 25 HMAC digits."); + } + System.arraycopy(signature, 0, this.hmac, 1, signature.length); + hmacPtr += signature.length; + if (hmacPtr > this.hmac.length) { + hmacPtr = this.hmac.length - 1; + } + } + } + + public void run() { + try { + dfs(hmac, hmacPtr); + } catch (Success s) { + System.out.println("\nSuccess in "+totalIterations+" iterations!"); + System.out.print("HMAC: "); + System.out.println(bytesToHexStr(s.getHMAC())); + return; + } + System.out.println("\nFailed to find HMAC! Try raise iteration limit."); + } + + private boolean dfs(byte[] hmac, int ptr) { + byte[] guessed = null; + if (ptr <= this.hmac.length) { + guessed = guessNext(message, hmac, ptr, maxIterations, inputStream, outputStream); + if (guessed==null) { + System.out.println("\nDead end!"); + return false; + } + System.out.print("\nPossible choices: "); + System.out.println(bytesToHexStr(guessed)); + for (int g: guessed) { + System.out.print("\nGuessing: "); + System.out.println(Integer.toHexString((0xff & g))); + byte[] hm = Arrays.copyOf(hmac, hmac.length); + hm[ptr] = (byte) (0xff & g); + if (dfs(hm,ptr+1)) { + return true; + } + } + } + return false; + } + + private byte[] guessNext(byte[] msg, byte[] hmac, int ptr, int maxIt, InputStream is, OutputStream os) { + + List statsPool = new ArrayList(); + + System.out.print("\nHMAC: "); + System.out.println(bytesToHexStr(hmac)); + System.out.print("Cracking"); + int bin = 4; + + while (maxIt>0) { + for (int j = 0 ; j < bin; j++ ) { + long[] stats = new long[256]; + + for (int b = 0; b<256; b++) { + if (ptr < hmac.length) { + hmac[ptr] = (byte)(0xff&b); + } + + int resp = sendData(b, is, os, msg, hmac, stats); + if (resp == 'N') { + // + } else if (resp == 'O') { + throw new Success(hmac); + } else { + throw new UnexpectedContent(); + } + totalIterations++; + } + System.out.write('.');System.out.flush(); + statsPool.add(Arrays.copyOf(stats, stats.length)); + maxIt--; + } + byte[] bestM = CrackerCore.select(statsPool); + if (bestM == null) { + bin = bin*2; + System.out.print("#"); // we need to collect more stats + continue; + } + return bestM; + } + return null; + } + + private String bytesToHexStr(byte[] hmac) { + if (hmac==null) return ""; + StringBuilder sb = new StringBuilder(); + for (byte x:hmac) { + sb.append(Integer.toHexString(0xff&x)).append(' '); + } + return sb.toString(); + } + private String bytesToHexStr(int[] hmac) { + if (hmac==null) return ""; + StringBuilder sb = new StringBuilder(); + for (int x:hmac) { + sb.append(Integer.toHexString(0xff&x)).append(' '); + } + return sb.toString(); + } + + + private int sendData(int b, InputStream is, OutputStream os, byte[] msg, byte[] hmac, long[] stats) { + try { //[101, 99, 104, 111, 95, 97, 104, 111, 106, 0, 0, 215, 137, 187, 50, 234, 124, 87, 103, 149, 169, 195, 50, 10, 79, 183, 36, 166, 199, 0, 11, 157, 207, 34, 228] + os.write(msg); + os.write(hmac); + long start,stop; + start = System.nanoTime(); + os.flush(); + int s = is.read(); + stop = System.nanoTime(); + for (int r=is.read(); r!='\n'; r=is.read()) { } + if (stats != null) { + stats[b] = stop - start; + } + return s; + } catch (IOException ex) { + Logger.getLogger(HmacCracker.class.getName()).log(Level.SEVERE, null, ex); + throw new RuntimeException(ex); + } + } + + private class Success extends RuntimeException { + private byte [] hmac; + public Success(byte[] hmac) { + super(bytesToHexStr(hmac)); + this.hmac = hmac; + } + public byte[] getHMAC() { + return this.hmac; + } + } + + private class UnexpectedContent extends RuntimeException { + public UnexpectedContent() { + super(); + } + public UnexpectedContent(String msg) { + super(msg); + } + } +} diff --git a/src/cz/cvut/keyczar/homework/Stats.java b/src/cz/cvut/keyczar/homework/Stats.java new file mode 100644 index 0000000..e858b0f --- /dev/null +++ b/src/cz/cvut/keyczar/homework/Stats.java @@ -0,0 +1,99 @@ +package cz.cvut.keyczar.homework; + +import java.util.List; + +/** + * + * @author pborky + */ +public class Stats { + public static double[] mean(List series) { + int width = series.get(0).length; + int height = series.size(); + + double[] sums = new double[width]; + double[] means = new double[width]; + + for (long[] s: series) { + for (int i = 0; i series, double mean) { + int width = series.get(0).length; + int height = series.size(); + + double stD = 0; + double sumsQ = 0; + + for (long[] s: series) { + for (int i = 0; i series, double[] means) { + int width = series.get(0).length; + int height = series.size(); + + double[] stD = new double[width]; + double[] sumsQ = new double[width]; + + for (long[] s: series) { + for (int i = 0; i