166 lines
4.9 KiB
Python
166 lines
4.9 KiB
Python
import hashlib
|
|
import itertools
|
|
import time
|
|
import string
|
|
|
|
# Define character set: 0-9, a-z, A-Z, and special symbols
|
|
CHARACTERS = string.digits + string.ascii_lowercase + string.ascii_uppercase + '#$%^&*'
|
|
|
|
|
|
def generate_sha256_hash(password):
|
|
"""Generate SHA256 hash of a password."""
|
|
return hashlib.sha256(password.encode()).hexdigest()
|
|
|
|
|
|
def read_password_database(filename):
|
|
"""
|
|
Read password database from a text file.
|
|
|
|
Args:
|
|
filename: Path to the file containing [username, hash] pairs
|
|
|
|
Returns:
|
|
List of [username, hash] pairs
|
|
"""
|
|
database = []
|
|
|
|
try:
|
|
with open(filename, 'r') as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if line and line.startswith('[') and line.endswith(']'):
|
|
# Remove brackets and split by comma
|
|
content = line[1:-1]
|
|
parts = content.split(',', 1) # Split only on first comma
|
|
if len(parts) == 2:
|
|
username = parts[0].strip()
|
|
password_hash = parts[1].strip()
|
|
database.append([username, password_hash])
|
|
|
|
print(f"Loaded {len(database)} accounts from {filename}")
|
|
return database
|
|
|
|
except FileNotFoundError:
|
|
print(f"Error: File '{filename}' not found.")
|
|
return []
|
|
except Exception as e:
|
|
print(f"Error reading file: {e}")
|
|
return []
|
|
|
|
|
|
def dictionary_attack(password_database, N):
|
|
"""
|
|
Perform dictionary attack on password database.
|
|
|
|
Args:
|
|
password_database: List of [username, hash] pairs
|
|
N: Length of passwords to try
|
|
|
|
Returns:
|
|
Dictionary mapping usernames to cracked passwords
|
|
Time taken for the attack
|
|
"""
|
|
print(f"\n{'='*60}")
|
|
print(f"Starting Dictionary Attack")
|
|
print(f"Password length: {N}")
|
|
print(f"Character set size: {len(CHARACTERS)}")
|
|
print(f"Total possible passwords: {len(CHARACTERS)**N}")
|
|
print(f"Number of accounts to crack: {len(password_database)}")
|
|
print(f"{'='*60}\n")
|
|
|
|
# Create a dictionary of hash -> username for faster lookup
|
|
hash_to_user = {entry[1]: entry[0] for entry in password_database}
|
|
cracked_passwords = {}
|
|
|
|
start_time = time.time()
|
|
attempts = 0
|
|
|
|
# Generate all possible passwords of length N
|
|
for password_tuple in itertools.product(CHARACTERS, repeat=N):
|
|
password = ''.join(password_tuple)
|
|
attempts += 1
|
|
|
|
# Hash the password
|
|
password_hash = generate_sha256_hash(password)
|
|
|
|
# Check if this hash matches any in the database
|
|
if password_hash in hash_to_user:
|
|
username = hash_to_user[password_hash]
|
|
cracked_passwords[username] = password
|
|
print(f"[+] Cracked! {username}: {password}")
|
|
|
|
# If all passwords are cracked, we can stop
|
|
if len(cracked_passwords) == len(password_database):
|
|
break
|
|
|
|
# Progress indicator (every 10000 attempts for small N, adjust as needed)
|
|
if attempts % 10000 == 0:
|
|
print(f"Tried {attempts} passwords...")
|
|
|
|
end_time = time.time()
|
|
time_taken = end_time - start_time
|
|
|
|
print(f"\n{'='*60}")
|
|
print(f"Attack Complete!")
|
|
print(f"Time taken: {time_taken:.4f} seconds")
|
|
print(f"Total attempts: {attempts}")
|
|
print(f"Passwords cracked: {len(cracked_passwords)}/{len(password_database)}")
|
|
print(f"{'='*60}\n")
|
|
|
|
return cracked_passwords, time_taken
|
|
|
|
|
|
def main():
|
|
"""Main function to run the dictionary attack demonstration."""
|
|
print("Dictionary Attack on SHA256 Password Hashes")
|
|
print("=" * 60)
|
|
|
|
# Get input file and password length from user
|
|
filename = input("Enter password database filename: ")
|
|
N = int(input("Enter password length N: "))
|
|
|
|
# Warn if N is too large
|
|
if N > 4:
|
|
total_passwords = len(CHARACTERS) ** N
|
|
print(f"\nWarning: With N={N}, there are {total_passwords:,} possible passwords.")
|
|
print("This may take a very long time!")
|
|
confirm = input("Continue? (yes/no): ")
|
|
if confirm.lower() != 'yes':
|
|
print("Attack cancelled.")
|
|
return
|
|
|
|
# Read password database from file
|
|
print("\nReading password database...")
|
|
password_database = read_password_database(filename)
|
|
|
|
if not password_database:
|
|
print("No valid data found. Exiting.")
|
|
return
|
|
|
|
print("\nPassword Database:")
|
|
for username, password_hash in password_database:
|
|
print(f"[{username}, {password_hash}]")
|
|
|
|
# Perform dictionary attack
|
|
cracked_passwords, time_taken = dictionary_attack(password_database, N)
|
|
|
|
# Display results
|
|
print("\nResults:")
|
|
for username, password in cracked_passwords.items():
|
|
print(f"{username}: {password}")
|
|
|
|
print(f"\nTotal time: {time_taken:.4f} seconds")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|