1
2
3
4
5
6
7
8
9
10
11 package com.jsql.view.swing.manager.util;
12
13 import com.jsql.util.I18nUtil;
14 import com.jsql.util.LogLevelUtil;
15 import com.jsql.util.bruter.Bruter;
16 import com.jsql.util.bruter.HashBruter;
17 import com.jsql.view.swing.manager.ManagerBruteForce;
18 import com.jsql.view.swing.util.I18nViewUtil;
19 import org.apache.commons.lang3.StringUtils;
20 import org.apache.logging.log4j.LogManager;
21 import org.apache.logging.log4j.Logger;
22
23 import javax.swing.*;
24 import javax.swing.text.BadLocationException;
25 import java.awt.event.ActionEvent;
26 import java.awt.event.ActionListener;
27 import java.util.Locale;
28
29
30
31
32 public class ActionBruteForce implements ActionListener, Runnable {
33
34 private static final Logger LOGGER = LogManager.getRootLogger();
35
36 private final ManagerBruteForce bruteForceManager;
37
38 private boolean isStopped = false;
39
40 public ActionBruteForce(ManagerBruteForce bruteForceManager) {
41 this.bruteForceManager = bruteForceManager;
42 }
43
44 @Override
45 public void actionPerformed(ActionEvent actionEvent) {
46 if (this.bruteForceManager.getRun().getState() == StateButton.STOPPABLE) {
47 this.bruteForceManager.getRun().setEnabled(false);
48 this.isStopped = true;
49 } else {
50 if (StringUtils.isEmpty(this.bruteForceManager.getHash().getText())) {
51 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, () -> I18nUtil.valueByKey("BRUTEFORCE_EMPTY_HASH"));
52 return;
53 } else if (this.isRangeNotSelected()) {
54 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, () -> I18nUtil.valueByKey("BRUTEFORCE_CHARACTER_RANGE"));
55 return;
56 } else if (this.isLengthNotValid()) {
57 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, () -> I18nUtil.valueByKey("BRUTEFORCE_INCORRECT_MIN_MAX_LENGTH"));
58 return;
59 }
60 new Thread(this, "ThreadDisplayBruteForce").start();
61 }
62 }
63
64 private boolean isLengthNotValid() {
65 return Integer.parseInt(this.bruteForceManager.getMaximumLength().getValue().toString())
66 < Integer.parseInt(this.bruteForceManager.getMinimumLength().getValue().toString());
67 }
68
69 private boolean isRangeNotSelected() {
70 return !this.bruteForceManager.getSpecialCharacters().isSelected()
71 && !this.bruteForceManager.getUpperCaseCharacters().isSelected()
72 && !this.bruteForceManager.getLowerCaseCharacters().isSelected()
73 && !this.bruteForceManager.getNumericCharacters().isSelected();
74 }
75
76 @Override
77 public void run() {
78
79 this.bruteForceManager.getRun().setText(I18nViewUtil.valueByKey("BRUTEFORCE_STOP"));
80 this.bruteForceManager.getRun().setState(StateButton.STOPPABLE);
81 this.bruteForceManager.showLoader(true);
82 this.bruteForceManager.getResult().setText(null);
83
84 final var hashBruter = new HashBruter();
85 this.initBruter(hashBruter);
86
87
88 new Thread(hashBruter::tryBruteForce, "ThreadRunBruteForce").start();
89 while (!hashBruter.isDone() && !hashBruter.isFound() && !this.isStopped) {
90
91 hashBruter.setEndtime(System.nanoTime());
92
93 try {
94 Thread.sleep(1000);
95 } catch (InterruptedException e) {
96 LOGGER.log(LogLevelUtil.IGNORE, e, e);
97 Thread.currentThread().interrupt();
98 }
99
100 int selectionStart = this.bruteForceManager.getResult().getSelectionStart();
101 int selectionEnd = this.bruteForceManager.getResult().getSelectionEnd();
102
103 this.updateResult(hashBruter);
104
105 this.bruteForceManager.getResult().setSelectionStart(selectionStart);
106 this.bruteForceManager.getResult().setSelectionEnd(selectionEnd);
107
108 if (this.isStopped) {
109 hashBruter.setIsDone(true);
110 hashBruter.setFound(true);
111 break;
112 }
113 }
114
115 this.displayResult(hashBruter);
116
117 this.isStopped = false;
118 this.bruteForceManager.showLoader(false);
119 this.bruteForceManager.getRun().setText(I18nViewUtil.valueByKey("BRUTEFORCE_RUN_BUTTON_LABEL"));
120 this.bruteForceManager.getRun().setEnabled(true);
121 this.bruteForceManager.getRun().setState(StateButton.STARTABLE);
122 }
123
124 private void updateResult(final HashBruter hashBruter) {
125 this.bruteForceManager.getResult().setText(I18nUtil.valueByKey("BRUTEFORCE_CURRENT_STRING") + ": " + hashBruter.getPassword());
126 this.append(I18nUtil.valueByKey("BRUTEFORCE_CURRENT_HASH") + ": " + hashBruter.getGeneratedHash() + "\n");
127 this.append(I18nUtil.valueByKey("BRUTEFORCE_POSSIBILITIES") + ": " + hashBruter.getNumberOfPossibilities());
128 this.append(I18nUtil.valueByKey("BRUTEFORCE_CHECKED_HASHES") + ": " + hashBruter.getCounter());
129 this.append(I18nUtil.valueByKey("BRUTEFORCE_ESTIMATED") + ": " + hashBruter.getRemainder());
130 this.append(I18nUtil.valueByKey("BRUTEFORCE_PERSECOND") + ": " + hashBruter.getPerSecond() + "\n");
131 this.append(hashBruter.calculateTimeElapsed());
132
133 if (hashBruter.getPerSecond() != 0) {
134 float remainingDuration = Float.parseFloat(Long.toString(hashBruter.getRemainder())) / hashBruter.getPerSecond();
135 this.append(String.format(
136 Bruter.PATTERN_PERIOD,
137 I18nUtil.valueByKey("BRUTEFORCE_TRAVERSING_REMAINING"),
138 Math.round(Math.floor(remainingDuration / 60f / 60.0f / 24f)), I18nUtil.valueByKey("BRUTEFORCE_DAYS"),
139 Math.round(Math.floor(remainingDuration / 60f / 60f % 24)), I18nUtil.valueByKey("BRUTEFORCE_HOURS"),
140 Math.round(Math.floor(remainingDuration / 60f % 60)), I18nUtil.valueByKey("BRUTEFORCE_MINUTES"),
141 Math.round(remainingDuration % 60), I18nUtil.valueByKey("BRUTEFORCE_SECONDS")
142 ));
143 }
144
145 this.append(String.format(
146 "%s: %s%%",
147 I18nUtil.valueByKey("BRUTEFORCE_PERCENT_DONE"),
148 100 * (float) hashBruter.getCounter() / hashBruter.getNumberOfPossibilities()
149 ));
150 }
151
152 private void initBruter(final HashBruter hashBruter) {
153 hashBruter.setMinLength(Integer.parseInt(this.bruteForceManager.getMinimumLength().getValue().toString()));
154 hashBruter.setMaxLength(Integer.parseInt(this.bruteForceManager.getMaximumLength().getValue().toString()));
155
156 if (this.bruteForceManager.getSpecialCharacters().isSelected()) {
157 hashBruter.addSpecialCharacters();
158 }
159 if (this.bruteForceManager.getUpperCaseCharacters().isSelected()) {
160 hashBruter.addUpperCaseLetters();
161 }
162 if (this.bruteForceManager.getLowerCaseCharacters().isSelected()) {
163 hashBruter.addLowerCaseLetters();
164 }
165 if (this.bruteForceManager.getNumericCharacters().isSelected()) {
166 hashBruter.addDigits();
167 }
168 if (StringUtils.isNotEmpty(this.bruteForceManager.getExclude().getText())) {
169 hashBruter.excludeChars(this.bruteForceManager.getExclude().getText());
170 }
171
172 hashBruter.setType((String) this.bruteForceManager.getHashTypes().getSelectedItem());
173 hashBruter.setHash(
174 this.bruteForceManager.getHash().getText()
175 .toUpperCase(Locale.ROOT)
176 .replaceAll("[^a-zA-Z0-9]", StringUtils.EMPTY)
177 .trim()
178 );
179 }
180
181 private void displayResult(final HashBruter hashBruter) {
182
183 if (this.isStopped) {
184 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, () -> I18nUtil.valueByKey("BRUTEFORCE_ABORTED"));
185 } else if (hashBruter.isFound()) {
186 this.append(String.format(
187 "%n%s:%n%s => %s",
188 I18nUtil.valueByKey("BRUTEFORCE_FOUND_HASH"),
189 hashBruter.getGeneratedHash(),
190 hashBruter.getPassword()
191 ));
192 LOGGER.log(
193 LogLevelUtil.CONSOLE_SUCCESS,
194 "{}: {} => {}",
195 () -> I18nUtil.valueByKey("BRUTEFORCE_FOUND_HASH"),
196 hashBruter::getGeneratedHash,
197 hashBruter::getPassword
198 );
199 } else if (hashBruter.isDone()) {
200 this.append("\n"+ I18nUtil.valueByKey("BRUTEFORCE_HASH_NOT_FOUND"));
201 LOGGER.log(LogLevelUtil.CONSOLE_ERROR, () -> I18nUtil.valueByKey("BRUTEFORCE_HASH_NOT_FOUND"));
202 }
203 }
204
205 private void append(String text) {
206 try {
207 JTextPane textPane = this.bruteForceManager.getResult();
208 textPane.getDocument().insertString(
209 textPane.getDocument().getLength(),
210 (textPane.getDocument().getLength() == 0 ? StringUtils.EMPTY : "\n") + text,
211 null
212 );
213 } catch (BadLocationException e) {
214 LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
215 }
216 }
217 }