Skip to content

Commit b5e3729

Browse files
committed
finished basic graphical portion
1 parent 1b2a24f commit b5e3729

10 files changed

+134
-78
lines changed

Input/passwod1.txt

-1
This file was deleted.

Input/password2.txt

-3
This file was deleted.

Input/passwords.txt

-9
This file was deleted.

Input/rule.txt

-4
This file was deleted.

Output/o1.txt

-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +0,0 @@
1-
password
2-
password
3-
crack

Readme.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,8 @@ SHA-2
8989
NIST
9090
MD-5
9191

92-
BCrypt must use Tara's method and talk about challenger protocol --> use custom challenge to create custom rainbowList
93-
9492

93+
ClERAYa4
9594

9695

9796

RuleApplyer.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -304,4 +304,5 @@ def prependMemory(curString : str) -> str:
304304
"z": 2, # second argument is how many times first character will be duplicated
305305
"Z": 2, # second argument is how many times last character will be duplicated
306306
"X": 4, # Insert substring of length M starting from position N of word saved to memory at position I
307-
}
307+
}
308+

graphics.py

+121-48
Original file line numberDiff line numberDiff line change
@@ -32,40 +32,37 @@ class Menu(QWidget):
3232
def __init__(self):
3333
super().__init__()
3434
# set up all the default variable to be used in password cracker
35-
self.inputFile = "" # input file holds path to file with password or ash to crack
35+
self.inputFile = "" # input file holds path to file with password or hash to crack
3636
self.outputFile = "" # output file will be the file where the passwords are printed
3737
self.mode = Menu.BRUTE_FORCE # by default will use brute force method
3838
# file that contains the words for the dictionary attack to run or masks for the masks attack
39-
self.methodInput= ""
39+
self.methodInput = ""
4040
self.rules = "" #holds path to the file with rules
4141
self.appendMask = "" #hold the mask that will be applied to end of brute force
4242
self.prependMask = "" #hold the mask that will be applied to start of brute force
4343
# by default we assume we are dealing with plain passwords
44-
self.hashMode = passwordCracker.NO_HASH
45-
self.onlineHashCheck = False
4644
# make window stay the same size
47-
# testing
48-
self.setUpShortcuts()
4945
self.openMenu()
5046

51-
#probably remove **
52-
def setUpShortcuts(self):
53-
# opening file test
54-
openFile = QAction("&Open File", self)
55-
openFile.setShortcut("Ctrl+O")
56-
openFile.setStatusTip('Open File')
57-
openFile.triggered.connect(self.file_open)
5847

59-
def file_open(self, path = 'Input'):
48+
def fileOpen(self, path = 'Input'):
6049
fileDialog = QFileDialog()
6150
filePath = QFileDialog.getOpenFileName(fileDialog, 'Open File', path, "Text files (*.txt)")
62-
print(filePath[0])
6351
try:
6452
with open(filePath[0],"r+", encoding="utf-8") as file:
6553
return file.read().splitlines()
6654
except FileNotFoundError:
6755
print("ERROR: could not open file")
68-
return ""
56+
return ""
57+
58+
def fileSelectInput(self, path = 'Input'):
59+
if(self.methodInput == ""):
60+
self.methodInput = self.fileOpen("Input/Recommended")
61+
if(self.methodInput != ""):
62+
pass # change to X icon **
63+
else:
64+
self.methodInput = ""
65+
# change box to back to open icon **
6966

7067
def openMenu(self):
7168
# self.setStyleSheet(menuCSS)
@@ -102,9 +99,9 @@ def openMenu(self):
10299
btn.setIconSize(QSize(240,35))
103100
btn.setStyleSheet('QPushButton{border: 0px solid;}')
104101
btn.setToolTip('Open up the input file that the program will use to crack the passwords')
105-
btn.clicked.connect(lambda:self.file_open("Input"))
102+
btn.clicked.connect(lambda: self.fileSelectInput("Input"))
106103
btn.resize(btn.sizeHint())
107-
layout.addWidget(btn, 0, 2)
104+
layout.addWidget(btn, 0, 2,1,2)
108105

109106
# Togglable options for dictionary attack
110107
# Check-box to add rules to add to dictionary attack
@@ -122,45 +119,65 @@ def openMenu(self):
122119
self.maskPrependBox.toggled.connect(self.togglePrependMask)
123120
layout.addWidget(self.maskPrependBox , 1, 2)
124121

122+
# validate input for text box
123+
# self.onlyInt = QIntValidator()
124+
self.minBoxLabel = QLabel(self)
125+
self.minBoxLabel.setText("Min")
126+
self.minBoxLabel.setAlignment(Qt.AlignRight)
127+
layout.addWidget(self.minBoxLabel, 2, 0)
128+
129+
self.minBox = QSpinBox(self)
130+
self.minBox.setRange(0,10)
131+
# self.minBox.setValidator(self.onlyInt)
132+
layout.addWidget(self.minBox , 2, 1)
133+
134+
self.maxBoxLabel = QLabel(self)
135+
self.maxBoxLabel.setText("Max")
136+
self.maxBoxLabel.setAlignment(Qt.AlignRight)
137+
layout.addWidget(self.maxBoxLabel, 2, 2)
138+
139+
self.maxBox = QSpinBox(self)
140+
self.maxBox.setValue(1)
141+
self.maxBox.setRange(0,10)
142+
# self.maxBox.setValidator(self.onlyInt)
143+
layout.addWidget(self.maxBox , 2, 3)
144+
125145
self.hashBox = QCheckBox("Hash mode")
126-
self.hashBox.toggled.connect(self.toggleHashMode)
127-
layout.addWidget(self.hashBox , 2, 0)
146+
layout.addWidget(self.hashBox , 3, 0)
128147

129148
self.rainbowBox = QCheckBox("Rainbow check")
130-
self.rainbowBox.toggled.connect(self.toggleOnlineHash)
131-
layout.addWidget(self.rainbowBox , 2, 1)
149+
layout.addWidget(self.rainbowBox , 3, 1)
132150

133151
self.hashDropdown = QComboBox(self)
134-
self.hashDropdown.addItem("SHA1")
135-
self.hashDropdown.addItem("MD5")
136-
self.hashDropdown.addItem("bcrypt")
137-
self.hashDropdown.currentIndexChanged.connect(self.toggleHashMode)
138-
layout.addWidget(self.hashDropdown , 2, 2,1 , 2)
152+
self.hashDropdown.addItem("SHA1", QVariant(passwordCracker.SHA1))
153+
self.hashDropdown.addItem("MD5", QVariant(passwordCracker.MD5))
154+
self.hashDropdown.addItem("bcrypt", QVariant(passwordCracker.BCRYPT))
155+
layout.addWidget(self.hashDropdown , 3, 2, 1, 2)
139156

140157
# ** USE save file mode instead of open
141158
self.inputBtn = QPushButton('', self)
142159
self.inputBtn.setIcon(QIcon('Resources/Images/filepw.png'))
143160
self.inputBtn.setIconSize(QSize(240,35))
144161
self.inputBtn.setStyleSheet('QPushButton{border: 0px solid;}')
145162
self.inputBtn.setToolTip('Select file with all the passwords or hashes that you want to crack ')
146-
self.inputBtn.toggled.connect(self.getInputFile)
147-
layout.addWidget(self.inputBtn , 3, 1)
163+
self.inputBtn.clicked.connect(self.getInputFile)
164+
layout.addWidget(self.inputBtn, 4, 0, 1, 2)
148165

149166
self.outputBtn = QPushButton('', self)
150167
self.outputBtn.setIcon(QIcon('Resources/Images/savepw.png'))
151168
self.outputBtn.setIconSize(QSize(240,35))
152169
self.outputBtn.setStyleSheet('QPushButton{border: 0px solid;}')
153170
self.outputBtn.setToolTip('Select file that will store the cracked passwords ')
154-
self.outputBtn.toggled.connect(self.getOutputFile)
155-
layout.addWidget(self.outputBtn , 3, 2)
171+
self.outputBtn.clicked.connect(self.getOutputFile)
172+
layout.addWidget(self.outputBtn, 4, 2, 1, 2)
156173

157174
self.startBtn = QPushButton('', self)
158175
self.startBtn.setIcon(QIcon('Resources/Images/crackpw.png'))
159-
self.startBtn.setIconSize(QSize(240,35))
176+
self.startBtn.setIconSize(QSize(260,45))
160177
self.startBtn.setStyleSheet('QPushButton{border: 0px solid;}')
161-
self.startBtn.toggled.connect(self.startCrack)
178+
self.startBtn.clicked.connect(self.startCrack)
162179
self.outputBtn.setToolTip('Select folder to save password to')
163-
layout.addWidget(self.startBtn , 4, 1, 1, 2)
180+
layout.addWidget(self.startBtn , 5, 0, 1, 4)
164181

165182
# self.setFixedSize(self.size())
166183

@@ -171,32 +188,88 @@ def selectAttackMode(self):
171188
self.ruleBox.setVisible(True)
172189
self.maskAppendBox.setVisible(True)
173190
self.maskPrependBox.setVisible(True)
191+
self.minBoxLabel.setVisible(True)
192+
self.minBox.setVisible(True)
193+
self.maxBoxLabel.setVisible(True)
194+
self.maxBox.setVisible(True)
195+
174196
if(radiobutton.methodNum == Menu.MASK):
175197
self.ruleBox.setVisible(False)
176198
self.maskAppendBox.setVisible(False)
177199
self.maskPrependBox.setVisible(False)
200+
self.minBoxLabel.setVisible(False)
201+
self.minBox.setVisible(False)
202+
self.maxBoxLabel.setVisible(False)
203+
self.maxBox.setVisible(False)
178204

179205
def toggleRules(self):
180-
pass
206+
if(self.ruleBox.isChecked()):
207+
self.rules = self.fileOpen("Input/Recommended/Rules")
208+
if(self.rules == ""):
209+
self.ruleBox.setChecked(False)
210+
else:
211+
self.rules = ""
212+
181213
def toggleAppendMask(self):
182-
pass
214+
if(self.maskAppendBox.isChecked()):
215+
self.appendMask = self.fileOpen("Input/Recommended/Mask")
216+
if(self.appendMask == ""):
217+
self.maskAppendBox.setChecked(False)
218+
else:
219+
self.appendMask = ""
183220
def togglePrependMask(self):
184-
pass
185-
def toggleHashMode(self):
186-
pass
187-
def toggleOnlineHash(self):
188-
pass
221+
if(self.maskPrependBox.isChecked()):
222+
self.prependMask = self.fileOpen("Input/Recommended/Mask")
223+
if(self.prependMask == ""):
224+
self.maskPrependBox.setChecked(False)
225+
else:
226+
self.prependMask = ""
227+
228+
def getHashMode(self):
229+
hashMode = 0
230+
if(self.hashBox.isChecked()):
231+
hashMode = self.hashDropdown.currentData()
232+
return hashMode
233+
189234
def getInputFile(self):
190-
pass
235+
fileDialog = QFileDialog()
236+
filePath = QFileDialog.getOpenFileName(fileDialog, 'Open File', 'Input/TargetFile', "Text files (*.txt)")
237+
self.inputFile = filePath[0]
238+
191239
def getOutputFile(self):
192-
pass
193-
def startCrack(self):
194-
pass
240+
fileDialog = QFileDialog()
241+
filePath= QFileDialog.getSaveFileName(fileDialog, 'Open File', 'Output', "Text files (*.txt)")
242+
self.outputFile = filePath[0]
243+
244+
def startCrack(self):
245+
if(self.inputFile == ""):
246+
print("You need to select input file that contains the files to crack")
247+
return
248+
if(self.outputFile == ""):
249+
print("You must select an output file where the cracked passwords will be saved")
250+
return
251+
if(self.methodInput == "" ):
252+
print("You must have an input file for the method")
253+
return
254+
cracker = passwordCracker(self.inputFile, self.outputFile)
255+
cracker.setVerboseMode(True)
256+
if(self.mode == Menu.BRUTE_FORCE):
257+
cracker.setRuleList(self.rules)
258+
cracker.setPrependMask(self.prependMask)
259+
cracker.setAppendMask(self.appendMask)
260+
cracker.setHashNum(self.getHashMode())
261+
if(self.hashBox.isChecked() and self.rainbowBox.isChecked()):
262+
pass # use this to run on-line hash check ***
263+
# Brute force stuff
264+
cracker.bruteForce(self.methodInput , int(self.minBox.value()), int(self.maxBox.value()))
265+
else:
266+
cracker.maskAttack(self.methodInput)
267+
# mask stuff
268+
print(cracker.endingPrompt())
269+
195270
# Look at different option like input file/output file, rules file and so on
196271
if __name__ == '__main__':
197272
app = QApplication(sys.argv)
198273
screen = Menu()
199274
screen.show()
200-
sys.exit(app.exec_())
201-
202-
275+
sys.exit(app.exec_())

main.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -43,21 +43,21 @@ def passwordCrackingMenu():
4343
# 3. Mask attack
4444
# 4. Rule-based with dictionary
4545
# 5. Combination'''))
46-
mode = 2
46+
mode = 5
4747
cracker.setVerboseMode(True)
4848
if(mode == 1):
4949
# get key space from file or one of the pre selected
5050
cracker.bruteForce("456789", 0,4)
5151
if(mode == 2):
52-
cracker.setHashNum(passwordCracker.BCRYPT)
52+
# cracker.setHashNum(passwordCracker.BCRYPT)
5353
cracker.bruteForce(['password','crack'], 0,2)
5454
if(mode == 3):
5555
cracker.maskAttack("?d?d?d?d")
5656
if(mode == 4):
5757
# get rule File using Tkinter
5858
with open("Input/rule.txt","r+", encoding="utf-8") as ruleFile:
5959
cracker.setRuleList(ruleFile.read().splitlines())
60-
cracker.bruteForce(['p','prat', 'p@ssW0rd'], 0,3)
60+
cracker.bruteForce([ 'p@ssW0rd'], 0,1)
6161
if(mode == 5 ):
6262
cracker.setPrependMask("?d?d?d?d")
6363
# get rule File using Tkinter

passwordCracker.py

+7-4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class passwordCracker:
1616
SHA1 = 1
1717
MD5 = 2
1818
BCRYPT = 3
19+
1920
def __init__(self, inputPasswordFile : str, oFile : str):
2021
# I would try and catch error here but I want the program to crash if the input, output file are not set incorrectly
2122
self.passwordList = getFileInfo(inputPasswordFile)
@@ -57,9 +58,9 @@ def checkMask(self,plainTextPassword) -> bool:
5758
if(len(self.appendMask) == 0 and len(self.prependMask) == 0):
5859
return False
5960
if(len(self.appendMask) != 0): # apply mask to end
60-
self.maskAttack(self.appendMask, "", plainTextPassword)
61+
self.maskAttack(self.appendMask, plainTextPassword)
6162
if (len(self.prependMask) != 0 ):
62-
self.maskAttack(self.prependMask, plainTextPassword)
63+
self.maskAttack(self.prependMask, "", plainTextPassword)
6364
return True
6465

6566
def ruleAttack(self, keyspace, min_length = 0, max_length = 1) -> bool:
@@ -70,7 +71,10 @@ def ruleAttack(self, keyspace, min_length = 0, max_length = 1) -> bool:
7071
if 0 == len(self.passwordList):
7172
return True
7273
return False
73-
74+
def endingPrompt(self) -> str:
75+
if 0 == len(self.passwordList):
76+
return "All passwords cracked!"
77+
return "Finished cracker. Could not find all passwords:("
7478
def passwordCheck(self, plainTextPassword):
7579
possiblePassword = self.getWord(plainTextPassword)
7680
for password in self.passwordList:
@@ -81,7 +85,6 @@ def passwordCheck(self, plainTextPassword):
8185
self.outputFile.write(plainTextPassword+"\n")
8286
self.passwordList.remove(password)
8387
if 0 == len(self.passwordList):
84-
print("All passwords cracked!")
8588
return True
8689
return False
8790
# for some hashes we can't just straight compare passwords

0 commit comments

Comments
 (0)