mirror of
https://github.com/brmlab/timingattack.git
synced 2025-06-08 17:14:10 +02:00
Import brute-force cracker.
This commit is contained in:
parent
604a8f36d9
commit
ea9646bfd9
5 changed files with 401 additions and 0 deletions
3
bin/cracker.sh
Normal file
3
bin/cracker.sh
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
#!/bin/bash
|
||||||
|
. libs.sh
|
||||||
|
java -cp $CP cz.cvut.keyczar.homework.Cracker $@
|
73
src/cz/cvut/keyczar/homework/Cracker.java
Normal file
73
src/cz/cvut/keyczar/homework/Cracker.java
Normal file
|
@ -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 <host> <port> <message> <limitIterations> [<signatureByte0> [<signatureByte1> [ ... <signatureByte24>]]]");
|
||||||
|
System.out.println("\t<host>, <port> - u know");
|
||||||
|
System.out.println("\t<message> - what to send");
|
||||||
|
System.out.println("\t<limitIterations> - max. number of iterations per one byte");
|
||||||
|
System.out.println("\t<signatureByteX> - 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
31
src/cz/cvut/keyczar/homework/CrackerCore.java
Normal file
31
src/cz/cvut/keyczar/homework/CrackerCore.java
Normal file
|
@ -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<long[]> 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<Byte> idx = new ArrayList<Byte>();
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
}
|
195
src/cz/cvut/keyczar/homework/HmacCracker.java
Normal file
195
src/cz/cvut/keyczar/homework/HmacCracker.java
Normal file
|
@ -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<msg.length; i++) {
|
||||||
|
this.message[i] = (byte)msg[i];
|
||||||
|
}
|
||||||
|
this.hmac = new byte[26];
|
||||||
|
Arrays.fill(this.hmac, (byte)0xff);
|
||||||
|
this.hmac[this.hmacPtr++] = 0; // separator
|
||||||
|
|
||||||
|
maxIterations = iMax;
|
||||||
|
if (null != signature) {
|
||||||
|
if (signature.length > 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<long[]> statsPool = new ArrayList<long[]>();
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
99
src/cz/cvut/keyczar/homework/Stats.java
Normal file
99
src/cz/cvut/keyczar/homework/Stats.java
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
package cz.cvut.keyczar.homework;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author pborky
|
||||||
|
*/
|
||||||
|
public class Stats {
|
||||||
|
public static double[] mean(List<long[]> 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<s.length; i++) {
|
||||||
|
sums[i] += s[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < width; i++) {
|
||||||
|
means[i] = sums[i]/height;
|
||||||
|
}
|
||||||
|
return means;
|
||||||
|
}
|
||||||
|
public static double mean(long[] series) {
|
||||||
|
double sum = 0;
|
||||||
|
for (long s: series) {
|
||||||
|
sum += s;
|
||||||
|
}
|
||||||
|
return sum/series.length;
|
||||||
|
}
|
||||||
|
public static double mean(double[] series) {
|
||||||
|
double sum = 0;
|
||||||
|
for (double s: series) {
|
||||||
|
sum += s;
|
||||||
|
}
|
||||||
|
return sum/series.length;
|
||||||
|
}
|
||||||
|
public static double std(List<long[]> 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<s.length; i++) {
|
||||||
|
double diff = s[i] - mean;
|
||||||
|
sumsQ += diff * diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return Math.sqrt(sumsQ/(width*height));
|
||||||
|
}
|
||||||
|
public static double[] std(List<long[]> 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<s.length; i++) {
|
||||||
|
double diff = s[i] - means[i];
|
||||||
|
sumsQ[i] += diff * diff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (int i = 0; i < width; i++) {
|
||||||
|
stD[i] = Math.sqrt(sumsQ[i]/height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return stD;
|
||||||
|
}
|
||||||
|
public static double std(long[] series) {
|
||||||
|
return std(series, mean(series));
|
||||||
|
}
|
||||||
|
public static double std(long[] series, double mean) {
|
||||||
|
double sqDiffSum = 0;
|
||||||
|
for(long s: series ) {
|
||||||
|
double diff = s - mean;
|
||||||
|
sqDiffSum += diff * diff;
|
||||||
|
}
|
||||||
|
return Math.sqrt(sqDiffSum / series.length);
|
||||||
|
}
|
||||||
|
public static double std(double[] series) {
|
||||||
|
return std(series, mean(series));
|
||||||
|
}
|
||||||
|
public static double std(double[] series, double mean) {
|
||||||
|
double sqDiffSum = 0;
|
||||||
|
for(double s: series) {
|
||||||
|
double diff = s - mean;
|
||||||
|
sqDiffSum += diff * diff;
|
||||||
|
}
|
||||||
|
return Math.sqrt(sqDiffSum / series.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue