Initial commit

This commit is contained in:
2025-04-13 20:30:34 +02:00
commit 3d9b4f83f6
25 changed files with 1419 additions and 0 deletions

25
gchashcrack_console/.gitignore vendored Normal file
View File

@@ -0,0 +1,25 @@
target/
!.mvn/wrapper/maven-wrapper.jar
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/build/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

View File

@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>gchashcrack</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.release>11</maven.compiler.release>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/commons-cli/commons-cli -->
<dependency>
<groupId>commons-cli</groupId>
<artifactId>commons-cli</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.14</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>14</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<archive>
<manifest>
<mainClass>
org.tenvoorde.gchashcrack.GcHashCrack
</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.openjfx</groupId>
<artifactId>javafx-maven-plugin</artifactId>
<version>0.0.4</version>
<configuration>
<mainClass>HelloFX</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,181 @@
package org.tenvoorde.gchashcrack;
import lombok.Builder;
import lombok.Data;
import org.apache.commons.cli.*;
import org.apache.commons.codec.digest.DigestUtils;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class GcHashCrack {
private static String format;
private static String digest;
private static String hash;
private static List<RangeVariable> rangeVariables = new ArrayList<>();
private static String formattedString;
private static int totalCombinations = 1;
@Builder
@Data
private static class RangeVariable {
private int lower;
private int upper;
}
public static void main(String[] args) {
if (!parseOptions(args)) {
System.exit(255);
}
parseFormattedString();
startCracking();
}
private static void startCracking() {
Integer[] loopVar = new Integer[rangeVariables.size()];
for (int i = 0; i < rangeVariables.size(); i++) {
loopVar[i] = rangeVariables.get(i).getLower();
totalCombinations *= (rangeVariables.get(i).getUpper() - rangeVariables.get(i).getLower() + 1);
}
System.out.println("Total combinations: " + totalCombinations);
boolean success = false;
String stringToHash;
int counter = 0;
int percentage = 0;
int percentage10 = 0;
do {
counter++;
stringToHash = String.format(formattedString, (Object[]) loopVar);
success = testHash(stringToHash);
if ((100 * counter / totalCombinations) > percentage) {
System.out.print(".");
percentage = 100 * counter / totalCombinations;
}
if ((percentage / 10) > (percentage10 / 10)) {
System.out.print(percentage + "%");
//percentage10 =
}
if (!increaseLoopVars(loopVar)) {
break;
}
} while (!success);
if (success) {
System.out.println("Success: " + stringToHash);
} else {
System.out.println("No match found");
}
}
private static boolean testHash(String stringToHash) {
String generatedHash;
switch(digest) {
case "MD5":
generatedHash = DigestUtils.md5Hex(stringToHash);
break;
default:
System.err.println("Illegal digest: " + digest);
}
return stringToHash.equalsIgnoreCase(hash);
}
private static boolean increaseLoopVars(Integer[] loopVar) {
boolean done = false;
int cursor = 0;
do {
if (cursor == rangeVariables.size()) {
return false;
}
loopVar[cursor]++;
if (loopVar[cursor] > rangeVariables.get(cursor).getUpper()) {
loopVar[cursor] = rangeVariables.get(cursor).getLower();
cursor++;
} else {
done = true;
}
} while (!done);
return true;
}
private static void parseFormattedString() {
// \[[0-9]-[0-9]\]
// N52 [0-5][0-9].[0-9][0-9][0-9] E005 [0-5][0-9].[0-9][0-9][0-9]
String pattern = "\\[[0-9]-[0-9]\\]";
Pattern p = Pattern.compile(pattern);
Matcher matcher = p.matcher(format);
int count = 0;
while (matcher.find()) {
String range = format.substring(matcher.start(), matcher.end());
rangeVariables.add(rangeVariableFromFormat(range));
}
formattedString = format.replaceAll(pattern, "%d");
System.out.println(formattedString);
}
private static RangeVariable rangeVariableFromFormat(String range) {
range = range.substring(1, range.length() - 1);
return RangeVariable.builder()
.lower(Integer.parseInt(range.substring(0, 1)))
.upper(Integer.parseInt(range.substring(2, 3)))
.build();
}
private static boolean parseOptions(String[] args) {
CommandLineParser parser = new DefaultParser();
Option formatOption = Option.builder("f").desc("Formatted string (between \"\" quotes) to be hashed").hasArg(true).numberOfArgs(1).optionalArg(false).longOpt("formattedString").build();
Option digestOption = Option.builder("d").desc("Digest type (currently supported: MD5)").hasArg(true).numberOfArgs(1).optionalArg(false).longOpt("digest").build();
Option hashOption = Option.builder("h").desc("Hash to compare with").hasArg(true).numberOfArgs(1).optionalArg(false).longOpt("hash").build();
Options options = new Options();
options.addOption(formatOption);
options.addOption(digestOption);
options.addOption(hashOption);
CommandLine line = null;
try {
line = parser.parse( options, args );
} catch( ParseException exp ) {
System.err.println(exp.getMessage());
}
boolean errorInCmdLine = false;
if (!line.hasOption("f")) {
System.err.println("Missing argument: -f");
errorInCmdLine = true;
}
if (!line.hasOption("d")) {
System.err.println("Missing argument: -d");
errorInCmdLine = true;
}
if (!line.hasOption("h")) {
System.err.println("Missing argument: -h");
errorInCmdLine = true;
}
if (!errorInCmdLine) {
format = line.getOptionValue("f");
digest = line.getOptionValue("d");
hash = line.getOptionValue("h");
} else {
HelpFormatter formatter = new HelpFormatter();
formatter.setLongOptSeparator("=");
formatter.printHelp(160, "gcHashCrack", "\n", options, "Example: gcHashCrack --hash=c35d8729ca887d26366da4ef9b843c08 --string=\"N52 [4-5][0-9].[0-9][0-9][0-9] E005 58.[0-9][0-9][0-9]\" --digest=MD5", true);
errorInCmdLine = true;
}
return !errorInCmdLine;
}
}