Created
February 4, 2014 13:50
-
-
Save jasiek/8803881 to your computer and use it in GitHub Desktop.
Stripe CTF 2014 Java Miner.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.lang.ProcessBuilder; | |
import java.io.File; | |
import java.io.FileWriter; | |
import java.io.FileReader; | |
import java.io.InputStreamReader; | |
import java.io.BufferedReader; | |
import java.security.MessageDigest; | |
import javax.xml.bind.DatatypeConverter; | |
public class Miner { | |
public static String DIRECTORY = "level1"; | |
public static void solve(String difficulty, String directory) throws Exception { | |
// Create an entry in the ledger. | |
FileWriter ledger = new FileWriter(directory + "/LEDGER.txt", true); | |
ledger.write("user-fn27nmtz: 1\n"); | |
ledger.close(); | |
run("git add LEDGER.txt", directory); | |
String tree = run("git write-tree", directory); | |
String parent = run("git rev-parse HEAD", directory); | |
long timestamp = System.currentTimeMillis() / 1000; | |
int counter = 0; | |
StringBuilder sb = new StringBuilder(); | |
sb.append(String.format("tree %s\n", tree)); | |
sb.append(String.format("parent %s\n", parent)); | |
sb.append(String.format("author LOL <[email protected]> %d +0000", timestamp) + "\n"); | |
sb.append(String.format("commiter LOL <[email protected]> %d +0000", timestamp) + "\n"); | |
sb.append("\n"); | |
String body = sb.toString(); | |
String content = String.format("commit %d\0", body.length() + 10) + body; | |
MessageDigest digest = MessageDigest.getInstance("SHA-1"); | |
digest.update(content.getBytes("UTF-8")); | |
while (true) { | |
MessageDigest digestClone = (MessageDigest)digest.clone(); | |
String counterString = formatCounter(counter); | |
digestClone.update(counterString.getBytes("UTF-8")); | |
String sha1 = DatatypeConverter.printHexBinary(digestClone.digest()); | |
if (sha1.compareTo(difficulty) < 0) { | |
System.out.println("found: " + sha1); | |
FileWriter tmpbody = new FileWriter(directory + "/body"); | |
tmpbody.write(body + counterString); | |
tmpbody.close(); | |
puts(run("git hash-object -t commit -w body", directory)); | |
puts(run(String.format("git reset --hard %s", sha1), directory)); | |
break; | |
} | |
counter++; | |
} | |
} | |
public static String formatCounter(int counter) { | |
char[] digits = new char[10]; | |
for (int d = 9; d >= 0; d--) { | |
digits[d] = Character.forDigit(counter % 10, 10); | |
counter /= 10; | |
} | |
return new String(digits); | |
} | |
public static String run(String command, String directory) throws Exception { | |
ProcessBuilder pb = new ProcessBuilder(command.split(" ")); | |
pb.directory(new File(directory)); | |
Process p = pb.start(); | |
p.waitFor(); | |
if (p.exitValue() != 0) throw new Exception("command: " + command + " failed."); | |
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream())); | |
return reader.readLine(); | |
} | |
public static String readDifficulty() throws Exception { | |
BufferedReader br = new BufferedReader(new FileReader("level1/difficulty.txt")); | |
return br.readLine(); | |
} | |
public static int commit(String directory) throws Exception { | |
Process p = Runtime.getRuntime().exec("git push origin master".split(" "), null, new File(directory)); | |
p.waitFor(); | |
return p.exitValue(); | |
} | |
public static void reset(String directory) throws Exception { | |
puts(run("git log", directory)); | |
puts(run("git fetch origin master", directory)); | |
puts(run("git reset --hard origin/master", directory)); | |
} | |
public static void puts(String s) { | |
System.out.println(s); | |
} | |
public static void main(String[] args) { | |
try { | |
String difficulty = readDifficulty().toUpperCase(); | |
reset(DIRECTORY); | |
while (true) { | |
solve(difficulty, DIRECTORY); | |
if (commit(DIRECTORY) == 0) { | |
break; | |
} else { | |
reset(DIRECTORY); | |
} | |
} | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment