From a967ba60cdde222729befddc619c026bf628ad67 Mon Sep 17 00:00:00 2001 From: Justin Bollinger Date: Fri, 13 Feb 2026 19:33:23 -0500 Subject: [PATCH] feat: send full wordlist to Ollama with configurable num_ctx Remove 500-line wordlist cap and send the entire file to Ollama. Add ollamaNumCtx config key (default 32768) to control the context window size. Invert wordlist prompt to default-yes, remove unused ollamaCandidateCount config. Co-Authored-By: Claude Opus 4.6 --- config.json.example | 4 ++-- hate_crack/attacks.py | 4 ++-- hate_crack/main.py | 30 +++++++++++++++--------------- tests/test_pull_ollama_model.py | 1 - 4 files changed, 19 insertions(+), 20 deletions(-) diff --git a/config.json.example b/config.json.example index 71439b6..9f2f61b 100644 --- a/config.json.example +++ b/config.json.example @@ -24,6 +24,6 @@ "hashview_api_key": "", "hashmob_api_key": "", "ollamaModel": "llama3.2", - "ollamaCandidateCount": 5000, - "ollamaWordlist": "rockyou.txt" + "ollamaWordlist": "rockyou.txt", + "ollamaNumCtx": 32768 } diff --git a/hate_crack/attacks.py b/hate_crack/attacks.py index d0ad15b..161d7e1 100644 --- a/hate_crack/attacks.py +++ b/hate_crack/attacks.py @@ -499,8 +499,8 @@ def ollama_attack(ctx: Any) -> None: if isinstance(default_wl, list): default_wl = default_wl[0] if default_wl else "" print(f"\nDefault wordlist: {default_wl}") - override = input("Use a different wordlist? [y/N]: ").strip().lower() - if override == "y": + use_default = input("Use the default wordlist? [Y/n]: ").strip().lower() + if use_default == "n": wordlist = ctx.select_file_with_autocomplete("Enter wordlist path") wordlist = ctx._resolve_wordlist_path(wordlist, ctx.hcatWordlists) else: diff --git a/hate_crack/main.py b/hate_crack/main.py index 4bfc7da..5716b54 100755 --- a/hate_crack/main.py +++ b/hate_crack/main.py @@ -463,15 +463,6 @@ except KeyError as e: ) ) ollamaModel = default_config.get("ollamaModel", "llama3.2") -try: - ollamaCandidateCount = int(config_parser["ollamaCandidateCount"]) -except KeyError as e: - print( - "{0} is not defined in config.json using defaults from config.json.example".format( - e - ) - ) - ollamaCandidateCount = int(default_config.get("ollamaCandidateCount", 5000)) try: ollamaWordlist = config_parser["ollamaWordlist"] except KeyError as e: @@ -481,6 +472,15 @@ except KeyError as e: ) ) ollamaWordlist = default_config.get("ollamaWordlist", "rockyou.txt") +try: + ollamaNumCtx = int(config_parser["ollamaNumCtx"]) +except KeyError as e: + print( + "{0} is not defined in config.json using defaults from config.json.example".format( + e + ) + ) + ollamaNumCtx = int(default_config.get("ollamaNumCtx", 32768)) hcatExpanderBin = "expander.bin" hcatCombinatorBin = "combinator.bin" @@ -1546,19 +1546,18 @@ def hcatOllama(hcatHashType, hcatHashFile, mode, context_data): if not os.path.isfile(wordlist_path): print(f"Error: Wordlist not found: {wordlist_path}") return - sample_lines = [] + lines = [] try: with open(wordlist_path, "r", errors="ignore") as f: - for i, line in enumerate(f): - if i >= 500: - break + for line in f: stripped = line.strip() if stripped: - sample_lines.append(stripped) + lines.append(stripped) except Exception as e: print(f"Error reading wordlist: {e}") return - wordlist_sample = "\n".join(sample_lines) + print(f"Loaded {len(lines)} passwords from wordlist.") + wordlist_sample = "\n".join(lines) prompt = ( "You are a password generation expert. Below is a sample of real passwords. " "Study the patterns, character choices, and structures. Then generate hashcat rules" \ @@ -1592,6 +1591,7 @@ def hcatOllama(hcatHashType, hcatHashFile, mode, context_data): "model": ollamaModel, "prompt": prompt, "stream": False, + "options": {"num_ctx": ollamaNumCtx}, }).encode("utf-8") if debug_mode: diff --git a/tests/test_pull_ollama_model.py b/tests/test_pull_ollama_model.py index 0df75e0..832be9c 100644 --- a/tests/test_pull_ollama_model.py +++ b/tests/test_pull_ollama_model.py @@ -654,7 +654,6 @@ class TestOllamaAttackHandler: ctx.hcatHashType = "0" ctx.hcatHashFile = "/tmp/hashes.txt" ctx.ollamaWordlist = "/tmp/wordlist.txt" - ctx.ollamaCandidateCount = 5000 ctx.hcatWordlists = "/tmp/wordlists" for k, v in overrides.items(): setattr(ctx, k, v)