fix(hashview): prompt for hash type when session type is unset

The download-hashes flow scoped the customer hashfile listing to
hcatHashType, but that is None when the Hashview menu is entered
without a hashfile loaded this session -> "No hashfiles of type None
found". Since Hashview only lists hashfiles per type, prompt for a
hashcat hash-type when none is set (Q cancels back to the menu) and
use it for the listing. Downstream selection still derives the real
type from the chosen hashfile.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Justin Bollinger
2026-06-18 17:40:36 -04:00
parent 25fd0f6362
commit 874c30dcaf
2 changed files with 28 additions and 6 deletions
+1 -1
View File
@@ -913,7 +913,7 @@ Interactive menu for downloading and managing wordlists from Weakpass.com via Bi
### Version History
Version 2.10.6
- Fixed the Hashview integration calling API routes that don't exist in Hashview (verified against v0.8.3-dev), which 404'd as soon as a customer ID was entered ("Could not list hashfiles"). The customer→hashfile listing relied on a phantom `GET /v1/hashfiles` list-all route; it now enumerates via the real `GET /v1/hashfiles/hash_type/<type>` endpoint, scoped to the session hash type, and filters by customer. Additional client-side route fixes: hashfile hash-type lookup now uses `GET /v1/getHashType/<id>`; "left" (uncracked) hash download uses `GET /v1/hashfiles/<id>`; `delete_job` uses `DELETE /v1/jobs/<id>`; `start_job` uses `POST`. Hashview exposes no stop-job route, so `stop_job` now raises with guidance to use `delete_job`; and no bulk cracked-hash export exists, so the best-effort "found" merge degrades gracefully
- Fixed the Hashview integration calling API routes that don't exist in Hashview (verified against v0.8.3-dev), which 404'd as soon as a customer ID was entered ("Could not list hashfiles"). The customer→hashfile listing relied on a phantom `GET /v1/hashfiles` list-all route; it now enumerates via the real `GET /v1/hashfiles/hash_type/<type>` endpoint, scoped to the session hash type (prompting for a hash type when none is loaded this session), and filters by customer. Additional client-side route fixes: hashfile hash-type lookup now uses `GET /v1/getHashType/<id>`; "left" (uncracked) hash download uses `GET /v1/hashfiles/<id>`; `delete_job` uses `DELETE /v1/jobs/<id>`; `start_job` uses `POST`. Hashview exposes no stop-job route, so `stop_job` now raises with guidance to use `delete_job`; and no bulk cracked-hash export exists, so the best-effort "found" merge degrades gracefully
Version 2.10.5
- Pipal analysis no longer corrupts its input when cracked passwords contain `$HEX[...]` rows. `binascii.unhexlify().decode()` returned the bytes without the trailing newline that normal rows inherit from `password[-1]`, so every HEX-encoded password got concatenated with the next one in the `.passwords` file fed to pipal (e.g. three cracks → two lines, one of them a bogus mashup). Pipal then under-counted entries and reported wrong top base words. The HEX branch now re-appends `\n` so each cracked password lands on its own line
+27 -5
View File
@@ -3710,6 +3710,7 @@ def hashview_api():
elif option_key == "download_hashes":
# Download left hashes
try:
cancel_download = False
while True:
# First, list customers to help user select
customers_result = api_harness.list_customers()
@@ -3758,17 +3759,34 @@ def hashview_api():
continue
# List hashfiles for the customer. Hashview has no
# list-all route, so we enumerate by the session hash
# type (the type of the hashes loaded in this session).
# list-all route, so we must enumerate by hash type.
# Prefer the session hash type (set when a hashfile is
# loaded); otherwise prompt, since None can't be queried.
download_hash_type = hcatHashType
if not download_hash_type:
ht_input = input(
"\nNo hash type loaded this session. Enter the hashcat "
"hash-type to list (e.g. 1000 for NTLM), or Q to cancel: "
).strip()
if ht_input.lower() == "q":
cancel_download = True
break
if not ht_input.isdigit():
print(
"\n✗ Error: Hash type must be a numeric hashcat mode."
)
continue
download_hash_type = ht_input
try:
customer_hashfiles = api_harness.get_customer_hashfiles(
customer_id, hash_type=hcatHashType
customer_id, hash_type=download_hash_type
)
if not customer_hashfiles:
print(
f"\nNo hashfiles of type {hcatHashType} found for "
f"customer ID {customer_id}"
f"\nNo hashfiles of type {download_hash_type} found "
f"for customer ID {customer_id}"
)
continue
@@ -3820,6 +3838,10 @@ def hashview_api():
break
break
# User cancelled at the hash-type prompt: back to the menu.
if cancel_download:
continue
# Set output filename automatically
output_file = f"left_{customer_id}_{hashfile_id}.txt"