try: resp = requests.get(url, timeout=15) resp.raise_for_status() cache_file.write_bytes(resp.content) print(f"[✓] Saved to cache_file") return cache_file except Exception as e: raise RuntimeError(f"Failed to download name: e") def load_passwords(name: str, cache_dir: Path = DEFAULT_CACHE_DIR) -> List[str]: """Return list of passwords (stripped, non-empty).""" path = download_wordlist(name, cache_dir) passwords = [] with open(path, "r", encoding="utf-8", errors="ignore") as f: for line in f: pwd = line.strip() if pwd: passwords.append(pwd) return passwords Search / Filter / Sample ---------------------------------------------------------------------- def filter_passwords( passwords: List[str], min_len: Optional[int] = None, max_len: Optional[int] = None, pattern: Optional[str] = None, only_digits: bool = False, only_alpha: bool = False, only_lower: bool = False, only_upper: bool = False, exclude_special: bool = False, must_contain: Optional[str] = None, ) -> List[str]: """Apply various filters to password list.""" result = passwords
args = parser.parse_args()
WORDLISTS = "10k_most_common": "url": f"SECLISTS_BASE_URL/Common-Credentials/10k-most-common.txt", "description": "10,000 most common passwords", , "500_worst": "url": f"SECLISTS_BASE_URL/500-worst-passwords.txt", "description": "500 worst passwords", , "rockyou_20": "url": f"SECLISTS_BASE_URL/RockYou-20.txt", "description": "Top 20 from RockYou leak", , "xato_10k": "url": f"SECLISTS_BASE_URL/xato-net-10-million-passwords-10000.txt", "description": "Xato 10k most common", , "linkedin": "url": f"SECLISTS_BASE_URL/LinkedIn-common-passwords.txt", "description": "LinkedIn leak common passwords", , Download & Cache Management ---------------------------------------------------------------------- def download_wordlist(name: str, cache_dir: Path) -> Path: """Download wordlist to cache directory, return local path.""" if name not in WORDLISTS: raise ValueError(f"Unknown wordlist: name. Choose from list(WORDLISTS.keys())") seclists password
print(f"[↓] Downloading name from url") cache_dir.mkdir(parents=True, exist_ok=True)
def search_passwords(passwords: List[str], query: str, case_sensitive: bool = False) -> List[str]: """Simple substring search.""" if not case_sensitive: query = query.lower() return [p for p in passwords if query in p.lower()] return [p for p in passwords if query in p] Export ---------------------------------------------------------------------- def export_results(passwords: List[str], output_file: Path, fmt: str = "txt"): """Export to txt, json, or csv.""" output_file.parent.mkdir(parents=True, exist_ok=True) if fmt == "txt": output_file.write_text("\n".join(passwords), encoding="utf-8") elif fmt == "json": json.dump(passwords, output_file.open("w", encoding="utf-8"), indent=2) elif fmt == "csv": import csv with open(output_file, "w", newline="", encoding="utf-8") as f: writer = csv.writer(f) writer.writerow(["password"]) writer.writerows([[p] for p in passwords]) else: raise ValueError(f"Unsupported format: fmt") print(f"[✓] Exported len(passwords) passwords to output_file") ---------------------------------------------------------------------- CLI ---------------------------------------------------------------------- def main(): parser = argparse.ArgumentParser( description="SecLists Password Tool – fetch, filter, search, and sample common passwords." ) parser.add_argument( "--list", "-l", choices=list(WORDLISTS.keys()), default=DEFAULT_WORDLIST, help=f"Wordlist to use (default: DEFAULT_WORDLIST)" ) parser.add_argument( "--search", "-s", help="Substring search (case-insensitive by default)" ) parser.add_argument( "--case-sensitive", action="store_true", help="Make --search case-sensitive" ) parser.add_argument( "--pattern", "-p", help="Regex pattern to match" ) parser.add_argument( "--min-len", type=int, help="Minimum password length" ) parser.add_argument( "--max-len", type=int, help="Maximum password length" ) parser.add_argument( "--only-digits", action="store_true", help="Only numeric passwords" ) parser.add_argument( "--only-alpha", action="store_true", help="Only alphabetic passwords" ) parser.add_argument( "--only-lower", action="store_true", help="Only lowercase letters" ) parser.add_argument( "--only-upper", action="store_true", help="Only uppercase letters" ) parser.add_argument( "--exclude-special", action="store_true", help="Exclude any non-alphanumeric characters" ) parser.add_argument( "--must-contain", help="Must contain this substring" ) parser.add_argument( "--sample", "-n", type=int, help="Randomly sample N passwords (after filters)" ) parser.add_argument( "--output", "-o", type=Path, help="Export results to file (txt, json, csv based on extension or --format)" ) parser.add_argument( "--format", choices=["txt", "json", "csv"], help="Export format (default from file extension or txt)" ) parser.add_argument( "--no-cache-dir", action="store_true", help="Do not use default cache (specify custom via --cache-dir)" ) parser.add_argument( "--cache-dir", type=Path, help="Custom cache directory" ) parser.add_argument( "--stats", action="store_true", help="Show statistics of selected passwords" ) parser.add_argument( "--verbose", action="store_true", help="Show additional info" ) try: resp = requests
# Output to stdout or file if args.output: # Determine format fmt = args.format if not fmt: ext = args.output.suffix.lower() if ext == ".json": fmt = "json" elif ext == ".csv": fmt = "csv" else: fmt = "txt" export_results(result, args.output, fmt) else: # Print to stdout (limit to 1000 lines to avoid spam) if len(result) > 1000 and not args.sample: print(f"Warning: len(result) passwords. Showing first 100. Use --sample or --output to manage.", file=sys.stderr) result = result[:100] for pwd in result: print(pwd) if == " main ": main() Usage Examples 1. Install dependency pip install requests 2. Basic – Show first 20 of 10k most common python seclists_password.py | head -20 3. Search for passwords containing "admin" python seclists_password.py --search admin 4. Regex pattern: passwords starting with "pass" and at least 6 chars python seclists_password.py --pattern "^pass.*" --min-len 6 5. Only numeric passwords between 4–6 digits python seclists_password.py --only-digits --min-len 4 --max-len 6 6. Sample 10 random passwords python seclists_password.py --sample 10 7. Use the "500 worst passwords" list, export to JSON python seclists_password.py --list 500_worst --output worst.json --format json 8. Statistics & verbose python seclists_password.py --stats --verbose --only-lower --min-len 8 9. Must contain "123" and exclude special chars python seclists_password.py --must-contain "123" --exclude-special Programmatic Usage (in your own Python scripts) from seclists_password import load_passwords, filter_passwords, sample_passwords passwords = load_passwords("10k_most_common") filtered = filter_passwords(passwords, min_len=8, only_alpha=True) random_10 = sample_passwords(filtered, 10)
if args.verbose and any([args.min_len, args.max_len, args.pattern, args.only_digits, args.only_alpha, args.only_lower, args.only_upper, args.exclude_special, args.must_contain]): print(f"[*] After filters: len(filtered) passwords") Use --sample or --output to manage
if args.search: filtered = search_passwords(filtered, args.search, args.case_sensitive) if args.verbose: print(f"[*] After substring search 'args.search': len(filtered) passwords")