Java tutorial
/** * ***************************************************************************** * Copyright (c) 2015 CodeJumble.com. All rights reserved. * * This file is part of OSBFA - www.codejumble.com * * Foobar is free software: you can redistribute it and/or modify it under the * terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR * A PARTICULAR PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with * OSBFA. If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************** */ package com.codejumble.osbfa.attacker; import com.codejumble.osbfa.Main; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; import javax.swing.SwingWorker; import net.lingala.zip4j.core.ZipFile; import org.apache.commons.io.FileUtils; /** * Class in charge of calculating the possible combinations * * @author alopcas */ public class CombinationFinder extends SwingWorker { static Main mainFrame; private final long totalNumberOfCombinations; private List<String> combinations; private final List<String> options; private char[] endCharSet; private final int maxPasswordSize; private final int minPasswordSize; private File tmpFolder; // Default charsets defined public static final String numbersCharSet = "0123456789"; public static final String highCapsCharSet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; public static final String lowCapsCharSet = "abcdefghijklmnopqrstuvwxyz"; public static final String specialCharSet = "!.:,;\\/?-_$"; public static final String extraSpecialCharSet = "%&()=+*~'#<>|"; public static String customCharSet = ""; // Regarding execution private long alreadyTriedCombinations; private boolean done; List<CombinationExploiter> miners; /** * Initializes the combination finder with the charsets to be used. * * @param mainFrame Main frame of the application * @param options Preferences of the user * @param maxPasswordLength maximum key size * @param amountOfThreads number of threads * @param zipFile Zipfile to be attacked */ public CombinationFinder(Main mainFrame, List<String> options, int minPasswordLength, int maxPasswordLength, int amountOfThreads, ZipFile zipFile) { tmpFolder = new File("tmp"); try { FileUtils.cleanDirectory(tmpFolder); } catch (IOException ex) { mainFrame.createErrorDialog(mainFrame, "Error", ex.getMessage()); } CombinationFinder.mainFrame = mainFrame; alreadyTriedCombinations = 0; done = false; this.options = options; createEndCharSet(); maxPasswordSize = maxPasswordLength; minPasswordSize = minPasswordLength; totalNumberOfCombinations = (long) Math.pow(endCharSet.length, maxPasswordSize); mainFrame.appendToMainLog("Number of possible combinations: " + getTotalNumberOfCombinations()); combinations = new ArrayList<String>(); miners = new ArrayList<CombinationExploiter>(); for (int i = 0; i < amountOfThreads; i++) { mainFrame.appendToMainLog("Adding exploiter thread number " + (i + 1)); File destFile = new File(tmpFolder.getAbsolutePath().concat(File.separator + i)); miners.add(new CombinationExploiter(this, zipFile, destFile)); } } private void createEndCharSet() { String tmp = ""; for (String charSet : options) { tmp = tmp.concat(charSet); } endCharSet = removeDuplicates(tmp); mainFrame.appendToMainLog("CombinationFinder was initialized with charset = " + getEndCharSet()); } /** * Returns the charset generated after the initialization * * @return the charset */ public String getEndCharSet() { return Arrays.toString(endCharSet); } /** * Removes the duplications from the end charset. * * @param endCharSet set to be cleared */ public char[] removeDuplicates(String endCharSet) { List<Character> alreadyIncludedCharacters = new ArrayList<Character>(); char[] providedCharSet = endCharSet.toCharArray(); String tmpNewChars = ""; for (char tmp : providedCharSet) { // If the character is already in the end char set, do not add it if (!alreadyIncludedCharacters.contains(tmp)) { alreadyIncludedCharacters.add(tmp); tmpNewChars += tmp; } } return tmpNewChars.toCharArray(); } /** * Returns the total number of possible combinations given the charset * * @return number of combinations */ public final long getTotalNumberOfCombinations() { return totalNumberOfCombinations; } /** * Starts the generation of all the possible combinations * * @return null * @throws Exception Runtime exception */ @Override protected Object doInBackground() throws Exception { for (int length = 1; length <= maxPasswordSize; length++) { mainFrame.appendToMainLog("Trying with key length=" + length); generate("", 0, length); } return null; } /** * Waits until all the possible combinations have been tried or the right * password has been found out. */ @Override protected void done() { while (stillOnGoing()) { try { Thread.sleep(900); } catch (InterruptedException ex) { Logger.getLogger(CombinationFinder.class.getName()).log(Level.SEVERE, null, ex); } } // OVER } /** * Generates recursesively the possible combinations * * @param str key * @param pos current position * @param length current length * @throws java.lang.InterruptedException Interruption */ public void generate(String str, int pos, int length) throws InterruptedException { if (length == 0) { combinations.add(str); if (combinations.size() > 8000000) { Thread.sleep(8000); mainFrame.appendToMainLog("Removed from pool: " + alreadyTriedCombinations + " (" + (int) ((float) alreadyTriedCombinations / totalNumberOfCombinations * 100) + "%) Next: " + combinations.get(0)); } } else { for (int i = pos; i < endCharSet.length; i++) { generate(str + endCharSet[i], i, length - 1); } } } /** * Returns whether the process is still on going * * @return is continuing */ public boolean stillOnGoing() { return !combinations.isEmpty() && !done; } /** * Returns a combination to be tried out * * @return combination */ public String getCombination() { alreadyTriedCombinations++; return combinations.remove(0); } /** * Starts all the combination exploiters * * @throws java.lang.InterruptedException Interrumption */ public void fireExploitersUp() throws InterruptedException { for (CombinationExploiter combinationExploiter : miners) { Thread.sleep(200); combinationExploiter.execute(); } } /** * Cancels all the exploiters, normally called when the right password has * been found out * * @param cancel cancel or not */ public void cancelMinning(Boolean cancel) { done = true; } }