How to Brute Force ZIP File Passwords in Python
Learn how to brute force zip file passwords using dictionary attack in Python using the built-in zip file module. Day 5 of python for pentesters.
Say you're tasked to investigate a suspect's computer and you find a zip file that seems very useful but is protected with a password. In this tutorial, you will write a simple, but yet precise Python script that tries to crack a zip file's password using dictionary attack.
We will be using Python's built-in
zipfile module, and the third-party tqdm library for quickly printing progress bars:
pip3 install tqdm
As I have mentioned, we are going to use a dictionary attack, which means we need a wordlist to brute force this password-protected zip file. For this tutorial, we are going to use the big rockyou wordlist (with a size of about 133MB), if you're on Kali Linux, you can find it under the /usr/share/wordlists/rockyou.txt.gz
path. Otherwise, you can download it here.
You can also use the crunch tool to generate your custom wordlist as you exactly specify.
Enough talking, let's now jump into the part we want.
Scripting
import zipfile
from tqdm import tqdm
Let's specify our target zip file along with the word list path:
# the password list path you want to use, must be available in the current directory
wordlist = "rockyou.txt"
# the zip file you want to crack its password
zip_file = "secret.zip"
Copy
To read the zip file in Python, we use the zipfile.ZipFile
class that has methods to open, read, write, close, list and extract zip files (we will only use extractall()
method here
# initialize the Zip File object
zip_file = zipfile.ZipFile(zip_file)
# count the number of words in this wordlist
n_words = len(list(open(wordlist, "rb")))
# print the total number of passwords
print("Total passwords to test:", n_words)
Notice we read the entire wordlist and then get only the number of passwords to test, this can prove useful for tqdm so we can track where we are in the brute forcing process, here is the rest of the code:
with open(wordlist, "rb") as wordlist:
for word in tqdm(wordlist, total=n_words, unit="word"):
try:
zip_file.extractall(pwd=word.strip())
except:
continue
else:
print("[+] Password found:", word.decode().strip())
exit(0)
print("[!] Password not found, try other wordlist.")
Since wordlist now is a Python generator, using tqdm won't give much progress information, that's why I introduced the total parameter to give tqdm insight into how many words are in the file.
We open the wordlist and read it word by word and try it as a password to extract the zip file, reading the entire line will come with the new line character, as a result, we use the strip() method to remove white spaces.
The method extractall() will raise an exception whenever the password is incorrect, so we can pass it to the next password in that case, otherwise, we print the correct password and exit the program.
Results
0xtraw@xtremepentest:~# gunzip /usr/share/wordlists/rockyou.txt.gz
0xtraw@xtremepentest:~# python3 zip_cracker.py secret.zip /usr/share/wordlists/rockyou.txt
Total passwords to test: 14344395
3%|▉ | 435977/14344395 [01:15<40:55, 5665.23word/s]
[+] Password found: abcdef12345
As you can see, I found the password after around 435K trials, which took about a minute on my machine. Note the Rockyou wordlist has more than 14 million words which are the most frequently used passwords sorted by frequency.
Alright, we have successfully built a simple but useful script that cracks the zip file password, try to use much bigger wordlists if you failed to crack it using this list.
Finally, I highly encourage you to use multiple threads for cracking the password much faster, if you succeed to do so, please share your results with us in the comments below!
Here is your challenge
improve the script to use threads for cracking the password much faster. If you succeed to do so, please share your results with me on Twitter (twitter.com/xtremepentest)
DISCLAIMER*: Use this script for a file you have permission to access. Otherwise, we are not responsible for any misuse.*