- Modificato
In questa discussione vediamo come fare bruteforce ad un file .zip (protetto da password non AES) in modo da accedere ai contenuti protetti al suo interno.
Il bruteforce è un tipo di attacco usato per scoprire password provando in modo automatizzato tutte le combinazioni fino a trovare quella corretta.
Il tool è composto da main.py (la logica del bot) e gui_version.py che è un interfaccia grafica basata su tkinter.
L'unico requisito da installare oltre a Python è tkinter, gli altri moduli sono già inclusi nella libreria standard di Python.
Requisiti
Per andare a scaricare la libreria in un ambiente virtuale:
python3 -m venv venv
source venv/bin/activate
(Debian)venv\Scripts\activate
(WSL Windows)sudo apt-get install python3-tk
Codice
Iniziamo a scrivere il main.py, le librerie necessarie:
- os.path e os usate per mettere mano ai file system, in questo caso sfruttiamo os per confermare l'esistenza di percorsi di file.
- zipfile per manipolare file .zip
- itertools per la GUI
Definiamo i colori in escape ANSI:
GREEN = '\033[92m'
RED = '\033[91m'
PURPLE = '\033[95m'
RESET = '\033[0m'
Qui trovate una lista di colori completa.
La prima cosa che deve fare il codice è cercare di estrarre il file zip (funzione extract_zip) per individuare il campo per fare bruteforce.
Dopo aver letto la documentazione: zip_file.extractall(pwd=password.encode())
.
extractall
cerca di estrarre tutti i file presenti nel file zip, il campo della password viene convertita in un byte string con .encode()
per garantire in ogni caso un formato corretto.
Se l'estrazione riesce ci restituisce true altrimenti false se tutti i tentativi sono sbagliati.
Ora scriviamo la funzione brute_force
per provare tutte le password di una wordlist.
zipfile.ZipFile(zip_file_path)
apre il file .zip specificato nel percorso zip_file_path
.
open(wordlist_path, 'r', encoding='latin-1')
apre la wordlist con codifica latin-1 (da cambiare se usate wordlist differenti).
passwords = f.readlines()
legge tutte le righe all'interno della wordlist.
Poi tramite il for password oltre a scorrere ogni riga, con password.strip()
vengono rimossi spazi inutili e extract_zip(zip_file, password)
viene ripetuto in continuazione per tentare di estrarre il file zip.
Nel main viene gestito l'input e vengono verificati i parametri che fornisce l'utente.
Ora vediamo la GUI, oltre alla libreria tkinter viene aggiunto anche subprocess. In questo caso usato per Popen che permette di eseguire lo script (main) in un processo separato in modo da prendere l'output.
Guardando la documentazione ho mappato tutte le azioni di main.py.
main.py
import os.path
import os
import zipfile
import itertools
GREEN = '\033[92m'
RED = '\033[91m'
PURPLE = '\033[95m'
RESET = '\033[0m'
print(f"""{RED}
_______ _____ ______ _______ _ _ ______ _ _
(_______|_____|_____ (_______) | | |/ _____) | / )
__ _ _____) )____ | | | | / | | / /
/ / | | | ____/ ___) | | | | | | |< <
/ /____ _| |_| | | | | |___| | \_____| | \ \
(_______|_____)_| |_| \______|\______)_| \_)
""")
# apertura zip con psw
def extract_zip(zip_file, password):
try:
zip_file.extractall(pwd=password.encode())
return True
except Exception:
return False
# bruteforce sincronizzato con extract_zip
def brute_force(zip_file_path, wordlist_path):
with zipfile.ZipFile(zip_file_path) as zip_file:
with open(wordlist_path, 'r', encoding='latin-1') as f:
passwords = f.readlines()
print(f"{GREEN}Attempting to bruteforce the zip file{RESET}")
for password in passwords:
password = password.strip()
print(f"Trying Password: {RED}{password}{RESET}")
if extract_zip(zip_file, password):
print(f"\n{GREEN}Password found: {PURPLE}{password}{RESET}")
return
print("Password not found in wordlist.")
def main():
print(
f"{PURPLE}NOTE : {RESET}{GREEN}This Tool only works with {RED}'ZIP Legacy Encryption'{RESET}")
print(f"{GREEN}Welcome to ZipFuck! {RED}EHF{RESET}")
print(f"{GREEN}Please provide the path to the zip file and the wordlist.{RESET}")
while True:
zip_file_path = input(f"{PURPLE}Enter the path to the zip file: {RESET}")
print(f"{GREEN}({RED}To Use the default wordlist type:{PURPLE} rockyou.txt{GREEN})")
wordlist_path = input(f"{PURPLE}Enter the path to the wordlist: {RESET}")
if not os.path.exists(zip_file_path) or not os.path.exists(wordlist_path):
print(f"{PURPLE}Please specify a valid path. {RESET}")
else:
break
print(f"{RED}\nStarting brute force attack...\n{RED}")
brute_force(zip_file_path, wordlist_path)
if __name__ == "__main__":
main()
gui_version.py
import os
import tkinter as tk
from tkinter import filedialog, messagebox
from subprocess import Popen, PIPE
from main import main
window = tk.Tk()
window.title("ZipFuck by EHF")
window.configure(bg="#34495E")
def run_cli_version():
process = Popen(["python", "main.py"], stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate()
output_text.insert(tk.END, stdout.decode(), "output")
output_text.insert(tk.END, stderr.decode(), "output")
def select_zip_file():
zip_file_path = filedialog.askopenfilename(title="Select Zip File", filetypes=[("Zip files", "*.zip")])
zip_file_entry.delete(0, tk.END)
zip_file_entry.insert(0, zip_file_path)
def select_wordlist():
wordlist_path = filedialog.askopenfilename(title="Select Wordlist", filetypes=[("Text files", "*.txt")])
wordlist_entry.delete(0, tk.END)
wordlist_entry.insert(0, wordlist_path)
def strip_ansi_escape_codes(text):
import re
ansi_escape = re.compile(r'\x1B(?:[@-Z\\-_]|\[[0-?]*[-/]*[@-~])')
return ansi_escape.sub('', text)
def start_bruteforce():
zip_file_path = zip_file_entry.get()
wordlist_path = wordlist_entry.get()
bruteforce_inprogress.grid(row=5, columnspan=3)
window.update()
if os.path.exists(zip_file_path) and os.path.exists(wordlist_path):
process = Popen(["python", "main.py"], stdin=PIPE, stdout=PIPE, stderr=PIPE)
stdout, stderr = process.communicate(f"{zip_file_path}\n{wordlist_path}\n".encode())
output_text.insert(tk.END, strip_ansi_escape_codes(stdout.decode()), "output")
output_text.insert(tk.END, strip_ansi_escape_codes(stderr.decode()), "output")
output_text.see(tk.END)
else:
messagebox.showwarning("Warning", "Please select both a zip file and a wordlist.")
def on_enter(e):
e.widget['background'] = '#16A085' # Lighter green
def on_leave(e):
e.widget['background'] = '#1ABC9C' # Original green
# Shows the Disclaimer of this program
title_label = tk.Label(window,
text="This Tool only works with 'ZIP Legacy Encryption'\n"
"ethicalhacking.freeflarum.com",
bg="#34495E", fg="#ECF0F1", font=("Helvetica", 12, "bold"))
title_label.grid(row=0, columnspan=3, pady=(10, 0))
zip_file_label = tk.Label(window, text="Zip File:", bg="#34495E", fg="#ECF0F1", font=("Helvetica", 10))
zip_file_label.grid(row=1, column=0, sticky="e")
zip_file_entry = tk.Entry(window, width=50, highlightbackground="#1ABC9C", highlightthickness=2, relief="flat",
font=("Helvetica", 10))
zip_file_entry.grid(row=1, column=1, padx=5, pady=5)
zip_file_button = tk.Button(window, text="Browse", command=select_zip_file, bg="#1ABC9C", fg="#ECF0F1",
activebackground="#16A085", relief="flat", borderwidth=0, padx=10, pady=5,
font=("Helvetica", 10, "bold"))
zip_file_button.grid(row=1, column=2, padx=5, pady=5)
wordlist_label = tk.Label(window, text="Wordlist:", bg="#34495E", fg="#ECF0F1", font=("Helvetica", 10))
wordlist_label.grid(row=2, column=0, sticky="e")
wordlist_entry = tk.Entry(window, width=50, highlightbackground="#1ABC9C", highlightthickness=2, relief="flat",
font=("Helvetica", 10))
wordlist_entry.grid(row=2, column=1, padx=5, pady=5)
wordlist_button = tk.Button(window, text="Browse", command=select_wordlist, bg="#1ABC9C", fg="#ECF0F1",
activebackground="#16A085", relief="flat", borderwidth=0, padx=10, pady=5,
font=("Helvetica", 10, "bold"))
wordlist_button.grid(row=2, column=2, padx=5, pady=5)
start_button = tk.Button(window, text="Start Bruteforce", command=start_bruteforce, bg="#E67E22", fg="#ECF0F1",
activebackground="#D35400", relief="flat", borderwidth=0, padx=10, pady=10,
font=("Helvetica", 12, "bold"))
start_button.grid(row=3, columnspan=3, pady=10)
# Button to run CLI version
run_cli_button = tk.Button(window, text="Run CLI Version", command=run_cli_version, bg="#E67E22", fg="#ECF0F1",
activebackground="#D35400", relief="flat", borderwidth=0, padx=10, pady=10,
font=("Helvetica", 12, "bold"))
run_cli_button.grid(row=4, columnspan=3, pady=10)
# Text widget to display output
output_text = tk.Text(window, height=10, width=70, bg="#2C3E50", fg="#ECF0F1", font=("Helvetica", 12, "bold"),
highlightbackground="#1ABC9C", highlightthickness=2, relief="flat", padx=5, pady=5)
output_text.grid(row=6, columnspan=3, padx=10, pady=10)
output_text.tag_configure("output", foreground="#ECF0F1")
bruteforce_inprogress = tk.Label(window,
text="Bruteforce Attack is Activated in the Background\n "
"You will be Notified after the attack is completed",
bg="#34495E", fg="#ECF0F1", font=("Helvetica", 10))
for button in [zip_file_button, wordlist_button, start_button, run_cli_button]:
button.bind("<Enter>", on_enter)
button.bind("<Leave>", on_leave)
window.mainloop()
if __name__ == "__main__":
main()
Qui sotto trovate la repo del tool, ho incluso la wordlist (RockYou non completa) e per chi non vuole installare Python la GUI convertita in exe tramite pyinstaller che purtroppo VirusTotal lo riconosce come trojan (link analisi). Chiaramente un falso positivo.