I am trying to extract a password protected .zip which has a .txt document (Say Congrats.txt
for this case). Now Congrats.txt
has text in it thus its not 0kb in size. Its placed in a .zip (For the sake of the thread lets name this .zip zipv1.zip
) with the password dominique
for the sake of this thread. That password is stored among other words and names within another .txt (Which we'll name it as file.txt
for the sake of this question).
Now if I run the code below by doing python Program.py -z zipv1.zip -f file.txt
(Assuming all these files are in the same folder as Program.py
) my program displays dominique
as the correct password for the zipv1.zip
among the other words/passwords in file.txt
and extracts the zipv1.zip
but the Congrats.txt
is empty and has the size of 0kb.
Now my code is as follows:
import argparse
import multiprocessing
import zipfile
parser = argparse.ArgumentParser(description="Unzips a password protected .zip", usage="Program.py -z zip.zip -f file.txt")
# Creates -z arg
parser.add_argument("-z", "--zip", metavar="", required=True, help="Location and the name of the .zip file.")
# Creates -f arg
parser.add_argument("-f", "--file", metavar="", required=True, help="Location and the name of file.txt.")
args = parser.parse_args()
def extract_zip(zip_filename, password):
try:
zip_file = zipfile.ZipFile(zip_filename)
zip_file.extractall(pwd=password)
print(f"[+] Password for the .zip: {password.decode('utf-8')}
")
except:
# If a password fails, it moves to the next password without notifying the user. If all passwords fail, it will print nothing in the command prompt.
pass
def main(zip, file):
if (zip == None) | (file == None):
# If the args are not used, it displays how to use them to the user.
print(parser.usage)
exit(0)
# Opens the word list/password list/dictionary in "read binary" mode.
txt_file = open(file, "rb")
# Allows 8 instances of Python to be ran simultaneously.
with multiprocessing.Pool(8) as pool:
# "starmap" expands the tuples as 2 separate arguments to fit "extract_zip"
pool.starmap(extract_zip, [(zip, line.strip()) for line in txt_file])
if __name__ == '__main__':
main(args.zip, args.file)
However if I another zip (zipv2.zip
) with the same method as zipv1.zip
with only difference being Congrats.txt
is in a folder which the folder is zipped alongside Congrats.txt
I do get the same results as zipv1.zip
but this time Congrats.txt
extracted along the folder it was in, and Congrats.txt
was intact; the text in it and the size of it was intact.
So to solve this I tried reading zipfile's documentation where I found out that if a password doesn't match the .zip it throws a RuntimeError
. So I did changed except:
in the code to except RuntimeError:
and got this error when trying to unzip zipv1.zip
:
(venv) C:UsersUSERDocumentsJetbrainsPyCharmProgram>Program.py -z zipv1.zip -f file.txt
[+] Password for the .zip: dominique
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 121, in worker
result = (True, func(*args, **kwds))
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 47, in starmapstar
return list(itertools.starmap(args[0], args[1]))
File "C:UsersUSERDocumentsJetbrainsPyCharmProgramProgram.py", line 16, in extract_zip
zip_file.extractall(pwd=password)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 1594, in extractall
self._extract_member(zipinfo, path, pwd)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 1649, in _extract_member
shutil.copyfileobj(source, target)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libshutil.py", line 79, in copyfileobj
buf = fsrc.read(length)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 876, in read
data = self._read1(n)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 966, in _read1
self._update_crc(data)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 894, in _update_crc
raise BadZipFile("Bad CRC-32 for file %r" % self.name)
zipfile.BadZipFile: Bad CRC-32 for file 'Congrats.txt'
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:UsersUSERDocumentsJetbrainsPyCharmProgramProgram.py", line 38, in <module>
main(args.zip, args.file)
File "C:UsersUSERDocumentsJetbrainsPyCharmProgramProgram.py", line 33, in main
pool.starmap(extract_zip, [(zip, line.strip()) for line in txt_file])
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 276, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 657, in get
raise self._value
zipfile.BadZipFile: Bad CRC-32 for file 'Congrats.txt'
The same results happpen though; password was found in file.txt
, zipv1.zip
was extracted but Congrats.txt
was empty and 0kb in size. So I ran the program again, but for zipv2.zip
this time and got this as a result:
(venv) C:UsersUSERDocumentsJetbrainsPyCharmProgram>Program.py -z zipv2.zip -f file.txt
[+] Password for the .zip: dominique
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 121, in worker
result = (True, func(*args, **kwds))
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 47, in starmapstar
return list(itertools.starmap(args[0], args[1]))
File "C:UsersUSERDocumentsJetbrainsPyCharmProgramProgram.py", line 16, in extract_zip
zip_file.extractall(pwd=password)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 1594, in extractall
self._extract_member(zipinfo, path, pwd)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 1649, in _extract_member
shutil.copyfileobj(source, target)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libshutil.py", line 79, in copyfileobj
buf = fsrc.read(length)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 876, in read
data = self._read1(n)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 966, in _read1
self._update_crc(data)
File "C:UsersUSERAppDataLocalProgramsPythonPython37libzipfile.py", line 894, in _update_crc
raise BadZipFile("Bad CRC-32 for file %r" % self.name)
zipfile.BadZipFile: Bad CRC-32 for file 'Congrats.txt'
"""
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "C:UsersUSERDocumentsJetbrainsPyCharmProgramProgram.py", line 38, in <module>
main(args.zip, args.file)
File "C:UsersUSERDocumentsJetbrainsPyCharmProgramProgram.py", line 33, in main
pool.starmap(extract_zip, [(zip, line.strip()) for line in txt_file])
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 276, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "C:UsersUSERAppDataLocalProgramsPythonPython37libmultiprocessingpool.py", line 657, in get
raise self._value
zipfile.BadZipFile: Bad CRC-32 for file 'Congrats.txt'
Again, same results; where the folder was extracted successfully and Congrats.txt
was also extracted with the text inside it and the size of it was intact.
I did take a look at this similar thread, as well as this thread but they were no help. I also checked zipfile's documentation but it wasn't helpful regarding the issue.
Edit
Now after implementing with zipfile.ZipFile(zip_filename, 'r') as zip_file:
for some unknown and weird reason; the program can read/process a small word list/password list/dictionary but can't if its large(?).
What I mean by that is that say a .txt document is present in zipv1.zip
; named Congrats.txt
with the text You have cracked the .zip!
. The same .txt is present in zipv2.zip
aswell, but this time placed in a folder named ZIP Contents
then zipped/password protected. The password is dominique
for both of the zips.
Do note that each .zip was generated using Deflate
compression method and ZipCrypto
encryption in 7zip.
Now that password is in Line 35
(35/52 lines)John The Ripper Jr.txt
and in Line 1968
for John The Ripper.txt
(1968/3106 lines).
Now if you do python Program.py -z zipv1 -f "John The Ripper Jr.txt"
in your CMD (or IDE of your choice); it will create a folder named Extracted
and place Congrats.txt
with the sentence we previously set. Same goes for zipv2
but Congrats.txt
will be in ZIP Contents
folder which is inside the Extracted
folder. No trouble extracting the .zips in this instance.
But if you try the same thing with John The Ripper.txt
i.e python Program.py -z zipv1 -f "John The Ripper.txt"
in your CMD (or IDE of your choice) it will create the Extracted
folder both of the zips; just like John The Ripper Jr.txt
but this time Congrats.txt
will be empty for both of them for some unknown reason.
My code and all necessary files are as follows:
import argparse
import multiprocessing
import zipfile
parser = argparse.ArgumentParser(description="Unzips a password protected .zip by performing a brute-force attack.", usage="Program.py -z zip.zip -f file.txt")
# Creates -z arg
parser.add_argument("-z", "--zip", metavar="", required=True, help="Location and the name of the .zip file.")
# Creates -f arg
parser.add_argument("-f", "--file", metavar="", required=True, help="Location and the name of the word list/password list/dictionary.")
args = parser.parse_args()
def extract_zip(zip_filename, password):
try:
with zipfile.ZipFile(zip_filename, 'r') as zip_file:
zip_file.extractall('Extracted', pwd=password)
print(f"[+] Password for the .zip: {password.decode('utf-8')}
")
except:
# If a password fails, it moves to the next password without notifying the user. If all passwords fail, it will print nothing in the command prompt.
pass
def main(zip, file):
if (zip == None) | (file == None):
# If the args are not used, it displays how to use them to the user.
print(parser.usage)
exit(0)
# Opens the word list/password list/dictionary in "read binary" mode.
txt_file = open(file, "rb")
# Allows 8 instances of P