Skip to content

Instantly share code, notes, and snippets.

@WKBae
Last active September 21, 2017 08:54
Show Gist options
  • Save WKBae/649776aff4b6380043b86d75b81c4090 to your computer and use it in GitHub Desktop.
Save WKBae/649776aff4b6380043b86d75b81c4090 to your computer and use it in GitHub Desktop.
Quick brute-force password finder of an encrypted zip file.
"""
Quick brute-force password finder of an encrypted zip file.
"Life's short, use Python."
by WKBae (https://github.com/WKBae/)
"""
import zipfile
from multiprocessing import Pool
# Unused character for marking 'end' of the list.
# Change if this character is used
dummy_char = '`'
# Whole list of the password letters, numbers(0-9) only
letters = [str(i) for i in range(10)] + [dummy_char]
# Including numbers, alphabets upper&lower cases
"""
letters = [str(i) for i in range(10)] +
[chr(c) for c in range(ord('a'), ord('z') + 1)] +
[chr(c) for c in range(ord('A'), ord('Z') + 1)] +
[dummy_char]
"""
def str_to_pwd(pwstr):
return list(map(lambda c: letters.index(c), reversed(pwstr)))
def pwd_to_str(pwd):
return ''.join(map(lambda i: letters[i], reversed(pwd)))
def add_and_check_range(pwd, digit):
if digit >= len(pwd):
return
pwd[digit] += 1
if pwd[digit] >= len(letters):
pwd[digit] = 0
add_and_check_range(pwd, digit + 1)
def cracker(filename, start, end):
try:
curr = str_to_pwd(start)
last = str_to_pwd(end)
zip_file = zipfile.ZipFile(filename)
while curr != last:
pws = pwd_to_str(curr)
try:
# May need to change string encoding if non-ascii characters are used(not tested)
zip_file.extractall(pwd=pws.encode('ascii'))
return pws
except:
pass
add_and_check_range(curr, 0)
return None
except KeyboardInterrupt:
return None
def main():
file = 'a.zip'
min_length = 1
max_length = 9
pool = Pool(None)
try:
for length in range(min_length, max_length + 1):
works = []
last_pws = None
for c in letters:
new_pws = c + '0' * (length - 1)
if last_pws is not None:
works.append((file, last_pws, new_pws))
last_pws = new_pws
results = pool.starmap(cracker, works)
successes = list(filter(lambda result: result is not None, results))
if len(successes) > 0:
print("Password found:")
for pwd in successes:
print("> " + pwd)
break
else:
print("Not found at length {}".format(length))
except KeyboardInterrupt:
print("Interrupted!")
return
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment