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