Last active
June 12, 2023 13:40
-
-
Save yosignals/ce4a23c8bf15a4efa81b5783cfb9b730 to your computer and use it in GitHub Desktop.
Publicker - A little script that takes your cracked passwords and cross references them against the SecList Passwords folder, exporting results to an external file citing the password and the location of the public wordlist it was seen in - more on this at https://thecontractor.io/publicker
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import requests | |
import chardet | |
import sys | |
GITHUB_API = 'https://api.github.com' | |
OWNER = 'danielmiessler' | |
REPO = 'SecLists' | |
BRANCH = 'master' | |
DIR_PATH = 'Passwords' | |
OUTPUT_DIR = 'Passwords' | |
def download_file(url, output_path): | |
response = requests.get(url, stream=True) | |
with open(output_path, 'wb') as out_file: | |
out_file.write(response.content) | |
def download_directory(repo_path, output_path): | |
os.makedirs(output_path, exist_ok=True) | |
contents_url = f'{GITHUB_API}/repos/{OWNER}/{REPO}/contents/{repo_path}?ref={BRANCH}' | |
response = requests.get(contents_url) | |
response.raise_for_status() | |
for entry in response.json(): | |
path = os.path.join(output_path, entry['name']) | |
if entry['type'] == 'file': | |
download_file(entry['download_url'], path) | |
elif entry['type'] == 'dir': | |
download_directory(os.path.join(repo_path, entry['name']), path) | |
def load_passwords(file_path): | |
with open(file_path, 'r') as file: | |
passwords = [line.strip() for line in file.readlines()] | |
return passwords | |
def load_wordlist(file_path): | |
# Detect file encoding | |
with open(file_path, 'rb') as f: | |
result = chardet.detect(f.read()) | |
encoding = result['encoding'] | |
with open(file_path, 'r', encoding=encoding) as file: | |
words = [line.strip() for line in file.readlines()] | |
return words | |
def compare_passwords(wordlists_dir, complex_passwords, output_file): | |
total_files = 0 | |
processed_files = 0 | |
total_matches = 0 | |
matches_by_file = {} | |
for file in os.listdir(wordlists_dir): | |
if file.endswith((".txt", ".lst", ".csv")): # assuming wordlists are text files | |
total_files += 1 | |
matches_by_file[file] = 0 | |
print("Processing Files...") | |
for file in os.listdir(wordlists_dir): | |
if file.endswith((".txt", ".lst", ".csv")): # assuming wordlists are text files | |
wordlist = load_wordlist(os.path.join(wordlists_dir, file)) | |
common = set(wordlist).intersection(set(complex_passwords)) | |
if common: | |
total_matches += len(common) | |
matches_by_file[file] += len(common) | |
for password in common: | |
output_line = f"Password '{password}' found in {file}\n" | |
with open(output_file, 'a') as out_file: | |
out_file.write(output_line) # write to file | |
processed_files += 1 | |
print(f"Processed {processed_files}/{total_files} files...") | |
print(f"Total matches found: {total_matches}") | |
print("Summary:") | |
with open(output_file, 'a') as out_file: | |
out_file.write(f"Total matches found: {total_matches}\n\n") | |
out_file.write("Summary:\n\n") | |
for file, matches in matches_by_file.items(): | |
summary_line = f"{file}: {matches} matches\n" | |
print(summary_line) | |
out_file.write(summary_line) | |
# Main script | |
wordlist_option = input("Choose an option:\n1. Provide a path to your wordlist folder.\n2. Download wordlist folder from GitHub.\n") | |
if wordlist_option == '1': | |
wordlists_dir = input("Enter the path to your wordlist folder: ") | |
if not os.path.exists(wordlists_dir): | |
print(f"The directory {wordlists_dir} does not exist. Exiting.") | |
sys.exit(1) | |
elif wordlist_option == '2': | |
if not os.path.exists(OUTPUT_DIR): | |
download_directory(DIR_PATH, OUTPUT_DIR) | |
wordlists_dir = OUTPUT_DIR | |
else: | |
print("Invalid option. Exiting.") | |
sys.exit(1) | |
complex_passwords_file = input("Enter the file name for complex passwords: ") | |
if os.path.exists(complex_passwords_file): | |
print(f"Using {complex_passwords_file} as the list of passwords.") | |
else: | |
print(f"{complex_passwords_file} not found. Exiting.") | |
sys.exit(1) | |
output_file = 'publickers.txt' | |
# Write banner to output file | |
with open(output_file, 'w') as out_file: | |
out_file.write(" _______ __ __ _______ ___ ___ _______ ___ _ _______ ______ \n") | |
out_file.write("| || | | || _ || | | | | || | | || || _ | \n") | |
out_file.write("| _ || | | || |_| || | | | | || |_| || ___|| | || \n") | |
out_file.write("| |_| || |_| || || | | | | || _|| |___ | |_||_ \n") | |
out_file.write("| ___|| || _ | | |___ | | | _|| |_ | ___|| __ |\n") | |
out_file.write("| | | || |_| || || | | |_ | _ || |___ | | | |\n") | |
out_file.write("|___| |_______||_______||_______||___| |_______||___| |_||_______||___| |_|\n\n") | |
out_file.write("All seen passwords are known publicly in these common wordlists, therefore hold a higher chance of successful compromise from attackers.\n\n") | |
compare_passwords(wordlists_dir, load_passwords(complex_passwords_file), output_file) | |
print(f"Results saved to {output_file}.") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment