Я пытаюсь извлечь защищенный паролем файл .zip с документом .txt (скажем Congrats.txt
для этого случая).Теперь Congrats.txt
содержит текст, поэтому его размер не равен 0 КБ.Он помещается в .zip (ради этого потока давайте назовем этот .zip zipv1.zip
) с паролем dominique
для этого потока.Этот пароль хранится среди других слов и имен в другом .txt (который мы назовем его file.txt
ради этого вопроса).Теперь, если я запускаю приведенный ниже код, выполнив python Program.py -z zipv1.zip -f file.txt
(при условии, что все эти файлы находятся в той же папке, что и Program.py
), моя программа отобразит dominique
в качестве правильного пароля для zipv1.zip
среди других слов / паролей в file.txt
и извлекает zipv1.zip
, но Congrats.txt
пуст и имеет размер 0 КБ.
Теперь мой код выглядит следующим образом:
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')} \n")
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)
Однако, если я еще один zip (zipv2.zip
) тем же методом, что и zipv1.zip
, с той лишь разницей, что Congrats.txt
находится в папке, в которую папка упакована вместе с Congrats.txt
Я получаю те же результаты, что и zipv1.zip
, но на этот раз Congrats.txt
извлекается вместепапка, в которой она находилась, и Congrats.txt
была целой;текст в нем и его размер были целы.
Поэтому, чтобы решить эту проблему, я попытался прочитать документацию zipfile , где я обнаружил, что если пароль не совпадает с .zip, он выбрасываетRuntimeError
.Поэтому я изменил except:
в коде на except RuntimeError:
и получил эту ошибку при попытке разархивировать zipv1.zip
:
(venv) C:\Users\USER\Documents\Jetbrains\PyCharm\Program>Program.py -z zipv1.zip -f file.txt
[+] Password for the .zip: dominique
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 121, in worker
result = (True, func(*args, **kwds))
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 47, in starmapstar
return list(itertools.starmap(args[0], args[1]))
File "C:\Users\USER\Documents\Jetbrains\PyCharm\Program\Program.py", line 16, in extract_zip
zip_file.extractall(pwd=password)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 1594, in extractall
self._extract_member(zipinfo, path, pwd)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 1649, in _extract_member
shutil.copyfileobj(source, target)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 79, in copyfileobj
buf = fsrc.read(length)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 876, in read
data = self._read1(n)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 966, in _read1
self._update_crc(data)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.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:\Users\USER\Documents\Jetbrains\PyCharm\Program\Program.py", line 38, in <module>
main(args.zip, args.file)
File "C:\Users\USER\Documents\Jetbrains\PyCharm\Program\Program.py", line 33, in main
pool.starmap(extract_zip, [(zip, line.strip()) for line in txt_file])
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 276, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 657, in get
raise self._value
zipfile.BadZipFile: Bad CRC-32 for file 'Congrats.txt'
Хотя те же результаты более счастливы;пароль был найден в file.txt
, zipv1.zip
был извлечен, но Congrats.txt
был пуст и имел размер 0 КБ.Поэтому я снова запустил программу, но на этот раз zipv2.zip
и получил в результате:
(venv) C:\Users\USER\Documents\Jetbrains\PyCharm\Program>Program.py -z zipv2.zip -f file.txt
[+] Password for the .zip: dominique
multiprocessing.pool.RemoteTraceback:
"""
Traceback (most recent call last):
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 121, in worker
result = (True, func(*args, **kwds))
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 47, in starmapstar
return list(itertools.starmap(args[0], args[1]))
File "C:\Users\USER\Documents\Jetbrains\PyCharm\Program\Program.py", line 16, in extract_zip
zip_file.extractall(pwd=password)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 1594, in extractall
self._extract_member(zipinfo, path, pwd)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 1649, in _extract_member
shutil.copyfileobj(source, target)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\shutil.py", line 79, in copyfileobj
buf = fsrc.read(length)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 876, in read
data = self._read1(n)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.py", line 966, in _read1
self._update_crc(data)
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\zipfile.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:\Users\USER\Documents\Jetbrains\PyCharm\Program\Program.py", line 38, in <module>
main(args.zip, args.file)
File "C:\Users\USER\Documents\Jetbrains\PyCharm\Program\Program.py", line 33, in main
pool.starmap(extract_zip, [(zip, line.strip()) for line in txt_file])
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 276, in starmap
return self._map_async(func, iterable, starmapstar, chunksize).get()
File "C:\Users\USER\AppData\Local\Programs\Python\Python37\lib\multiprocessing\pool.py", line 657, in get
raise self._value
zipfile.BadZipFile: Bad CRC-32 for file 'Congrats.txt'
Опять те же результаты;где папка была успешно извлечена, и Congrats.txt
также был извлечен с текстом внутри нее, а ее размер не изменился.
Я также взглянул на эту аналогичную ветку, а такжекак этот поток, но они не помогли.Я также проверил документацию zipfile , но это не помогло в отношении проблемы.
Я не уверен, что является причиной моей проблемы или как ее исправить, и хотел бы получить некоторую помощь в отношении этой проблемы..
РЕДАКТИРОВАТЬ
Теперь после реализации with zipfile.ZipFile(zip_filename, 'r') as zip_file:
по неизвестной и странной причине;программа может читать / обрабатывать небольшой список слов / список паролей / словарь, но не может, если он большой (?).
Под этим я подразумеваю, что текст .txt присутствует в zipv1.zip
;с именем Congrats.txt
с текстом You have cracked the .zip!
.Тот же самый .txt присутствует и в zipv2.zip
, но на этот раз помещен в папку с именем ZIP Contents
, а затем защищен паролем.Пароль - dominique
для обоих почтовых индексов.
Обратите внимание, что каждый ZIP-файл был создан с использованием Deflate
метода сжатия и ZipCrypto
шифрования в 7zip.
Теперь этот пароль в Line 35
(35/52 строк) John The Ripper Jr.txt
и Line 1968
для John The Ripper.txt
(1968/3106 строк).
Теперь, если вы делаете python Program.py -z zipv1 -f "John The Ripper Jr.txt"
в своем CMD (или IDE по вашему выбору);он создаст папку с именем Extracted
и поместит Congrats.txt
с предложением, которое мы ранее установили.То же самое касается zipv2
, но Congrats.txt
будет в папке ZIP Contents
, которая находится внутри папки Extracted
.Нет проблем с извлечением .zips в этом случае.
Но если вы попробуете то же самое с John The Ripper.txt
, т.е. python Program.py -z zipv1 -f "John The Ripper.txt"
в вашей CMD (или IDE по вашему выбору), это создаст папку Extracted
с двумя zip-файлами;точно так же, как John The Ripper Jr.txt
, но на этот раз Congrats.txt
будет пусто для них обоих по неизвестной причине.
Мой код и все необходимые файлы выглядят следующим образом:
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')} \n")
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__':
# Program.py - z zipname.zip -f filename.txt
main(args.zip, args.file)
Program.py
zipv1.zip
zipv2.zip
Джон Потрошитель Jr.txt
Джон Потрошитель.txt
Джон Потрошитель v2.txt
Я не уверен, почему это происходит, и не могу найти ответ на этот вопрос нигде.Это абсолютно неизвестно из того, что я могу сказать, и я не могу найти способ отладить или решить эту проблему.
Это продолжает происходить независимо от разных списков слов / паролей.Попытался сгенерировать больше .zips с тем же Congrats.txt
, но с разными паролями из разных списков слов / списков паролей / словарей.Тот же метод;была использована более крупная и меньшая версия .txt, и были достигнуты те же результаты, что и выше.
НО Я обнаружил, что если я вырежу первые 2k слов в John The Ripper.txt
исделать новый .txt;скажем John The Ripper v2.txt
;ZIP-файл успешно извлечен, появляется папка Extracted
и присутствует Congrats.txt
с текстом внутри нее.Поэтому я считаю, что это связано со строками после ввода пароля.Так что в этом случае Line 1968
;где скрипт не останавливается после Line 1968
?Я не уверен, почему это работает, хотя.Это не решение, а шаг к решению, я думаю ...
Любая помощь будет принята с благодарностью.
РЕДАКТИРОВАТЬ 2
Поэтому я попытался использовать код «завершения пула»:
import argparse
import multiprocessing
import zipfile
parser = argparse.ArgumentParser(description="Unzips a password protected .zip by performing a brute-force attack using", 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, queue):
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')} \n")
queue.put("Done") # Signal success
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):
print(parser.usage) # If the args are not used, it displays how to use them to the user.
exit(0)
# Opens the word list/password list/dictionary in "read binary" mode.
txt_file = open(file, "rb")
# Create a Queue
manager = multiprocessing.Manager()
queue = manager.Queue()
with multiprocessing.Pool(8) as pool: # Allows 8 instances of Python to be ran simultaneously.
pool.starmap_async(extract_zip, [(zip, line.strip(), queue) for line in txt_file]) # "starmap" expands the tuples as 2 separate arguments to fit "extract_zip"
pool.close()
queue.get(True) # Wait for a process to signal success
pool.terminate() # Terminate the pool
pool.join()
if __name__ == '__main__':
main(args.zip, args.file) # Program.py -z zip.zip -f file.txt.
Теперь, если я использую это, оба архива извлекаются успешно, как и предыдущие экземпляры. НО на этот раз zipv1.zip
Congrats.txt
не поврежден;есть сообщение внутри него.Но то же самое нельзя сказать о zipv2.zip
, поскольку он все еще пуст.