updated makefile

This commit is contained in:
Justin Bollinger
2026-02-01 20:46:01 -05:00
parent 0ca3c9ca97
commit 8e6909d602
6 changed files with 201 additions and 58 deletions
+35 -5
View File
@@ -1,12 +1,25 @@
.PHONY: all install clean hashcat-utils test
all: hashcat-utils
.PHONY: install clean hashcat-utils test
hashcat-utils:
$(MAKE) -C hashcat-utils
install: hashcat-utils
uv tool install .
install:
@echo "Detecting OS and installing dependencies..."
@if [ "$(shell uname)" = "Darwin" ]; then \
echo "Detected macOS"; \
command -v brew >/dev/null 2>&1 || { echo >&2 "Homebrew not found. Please install Homebrew first: https://brew.sh/"; exit 1; }; \
brew install p7zip transmission-cli; \
uv tool install .; \
elif [ -f /etc/debian_version ]; then \
echo "Detected Debian/Ubuntu"; \
sudo apt-get update; \
sudo apt-get install -y p7zip-full transmission-cli; \
uv tool install .; \
else \
echo "Unsupported OS. Please install dependencies manually."; \
exit 1; \
fi
clean:
-$(MAKE) -C hashcat-utils clean
@@ -15,3 +28,20 @@ clean:
test:
uv run pytest -v
uninstall:
@echo "Detecting OS and uninstalling dependencies..."
@if [ "$(shell uname)" = "Darwin" ]; then \
echo "Detected macOS"; \
command -v brew >/dev/null 2>&1 || { echo >&2 "Homebrew not found. Please uninstall Homebrew packages manually."; exit 1; }; \
brew uninstall --ignore-dependencies p7zip transmission-cli || true; \
uv tool uninstall hate_crack || true; \
elif [ -f /etc/debian_version ]; then \
echo "Detected Debian/Ubuntu"; \
sudo apt-get remove -y p7zip-full transmission-cli || true; \
uv tool uninstall hate_crack || true; \
else \
echo "Unsupported OS. Please uninstall dependencies manually."; \
exit 1; \
fi
+67 -25
View File
@@ -8,41 +8,67 @@
```
## Installation
### 1. Install hashcat
Get the latest hashcat binaries (https://hashcat.net/hashcat/)
```
```bash
git clone https://github.com/hashcat/hashcat.git
cd hashcat/
make
make install
```
### 2. Download hate_crack
```bash
git clone --recurse-submodules https://github.com/trustedsec/hate_crack.git
cd hate_crack
```
* Customize binary and wordlist paths in "config.json"
* The hashcat-utils repo is a submodule. If you didn't clone with --recurse-submodules then initialize with:
```bash
git submodule update --init --recursive
```
### 3. Install dependencies and hate_crack
The easiest way is to use `make install` which auto-detects your OS and installs:
- External dependencies (p7zip, transmission-cli)
- Python tool via uv
```bash
make install
```
**Or install dependencies manually:**
### External Dependencies
These are required for certain download/extraction flows:
- `7z`/`7za` (p7zip) — used to extract `.7z` archives.
- `transmission-cli` — used to download Weakpass torrents.
Install commands:
Manual install commands:
Manual install commands:
Ubuntu/Kali:
```
```bash
sudo apt-get update
sudo apt-get install -y p7zip-full transmission-cli
```
macOS (Homebrew):
```
```bash
brew install p7zip transmission-cli
```
### Download hate_crack
```git clone --recurse-submodules https://github.com/trustedsec/hate_crack.git```
* Customize binary and wordlist paths in "config.json"
* The hashcat-utils repo is a submodule. If you didnt clone with --recurse-submodules then initialize with
```cd hate_crack;git submodule update --init --recursive```
Then install the Python tool:
```bash
uv tool install .
```
-------------------------------------------------------------------
## Project Structure
@@ -69,16 +95,16 @@ This project depends on and is inspired by a number of external projects and ser
## Usage
You can run hate_crack as a tool, as a script, or via `uv run`:
```
```bash
uv run hate_crack.py
or
# or
uv run hate_crack.py <hash_file> <hash_type> [options]
```
### Run as a tool (recommended)
Install once from the repo root:
```
```bash
uv tool install .
hate_crack
```
@@ -86,46 +112,52 @@ hate_crack
If you run the tool outside the repo, set `HATE_CRACK_HOME` so assets like
`hashcat-utils` can be found:
```
```bash
HATE_CRACK_HOME=/path/to/hate_crack hate_crack
```
### Run as a script
The script uses a `uv` shebang. Make it executable and run:
```
```bash
chmod +x hate_crack.py
./hate_crack.py
```
You can also use Python directly:
```
```bash
python hate_crack.py
```
### Makefile helpers
Build hashcat-utils and install the tool:
Install OS dependencies + tool (auto-detects macOS vs Debian/Ubuntu):
```
```bash
make install
```
Build only hashcat-utils:
Uninstall OS dependencies + tool:
```bash
make uninstall
```
make
Build hashcat-utils only:
```bash
make hashcat-utils
```
Clean build/test artifacts:
```
```bash
make clean
```
Run the test suite:
```
```bash
make test
```
@@ -168,7 +200,8 @@ $ ./hate_crack.py <hash file> 1000
## Testing
The project includes comprehensive test coverage for the Hashview integration.
The test suite is mostly offline and uses mocks/fixtures. Live network checks and
system dependency checks are opt-in via environment variables.
### Running Tests Locally
@@ -182,7 +215,16 @@ uv run pytest tests/test_hashview.py -v
You can also run the full suite with `make test`.
### Live Hashview Tests
### Live Tests (Opt-In)
Set any of the following to enable live checks:
- `HASHMOB_TEST_REAL=1` — live Hashmob connectivity/CLI menu check
- `HASHVIEW_TEST_REAL=1` — live Hashview CLI menu check
- `WEAKPASS_TEST_REAL=1` — live Weakpass CLI menu check
- `HATE_CRACK_REQUIRE_DEPS=1` — fail if `7z` or `transmission-cli` is missing
### Live Hashview Upload Test
The live Hashview upload test is skipped by default. To run it, set the
environment variable and provide valid credentials in `config.json`:
+63 -22
View File
@@ -1,7 +1,7 @@
# Testing Guide
## Overview
The test suite uses mocked API responses and local fixtures so it can run without external services (Hashview, Hashmob, Weakpass). Most tests are fast and run entirely offline.
The test suite uses mocked API responses and local fixtures so it can run without external services (Hashview, Hashmob, Weakpass). Most tests are fast and run entirely offline. Live network checks and system dependency checks are now opt-in via environment variables.
## Changes Made
@@ -18,22 +18,32 @@ The test suite uses mocked API responses and local fixtures so it can run withou
- Hashfile upload
- Complete job creation workflow
**tests/test_hate_crack_utils.py**
- Unit tests for utility helpers (session id generation, line counts, path resolution, hex conversion)
- Uses `HATE_CRACK_SKIP_INIT=1` to avoid heavy dependency checks
**tests/test_api.py**
- Tests for download functionality, 7z extraction triggers, exception handling, and progress bars
- Uses mocked requests and filesystem operations
**tests/test_menu_snapshots.py**
- Snapshot-based tests for menu output text
- Uses fixtures in `tests/fixtures/menu_outputs/`
**tests/test_cli_menus.py**
- Tests CLI menu flags (--hashview, --weakpass, --hashmob)
- Skips by default unless respective TEST_REAL env vars are set
**tests/test_dependencies.py**
- Checks local tool availability (7z, transmission-cli)
- Skips missing dependency failures unless `HATE_CRACK_REQUIRE_DEPS=1` (or true/yes)
**tests/test_module_imports.py**
- Ensures core modules import cleanly (`hashview`, `hashmob_wordlist`, `weakpass`, `cli`, `api`, `attacks`)
**tests/test_ui_menu_options.py**
- Tests all menu option handlers (attacks 1-13, utilities 91-100)
- Validates menu routing and function resolution
**tests/test_pipal.py** and **tests/test_pipal_integration.py**
- Tests pipal analysis functionality and executable integration
- Validates baseword parsing and output handling
**tests/test_submodule_hashcat_utils.py**
- Verifies hashcat-utils submodule is initialized correctly
**tests/test_hashmob_connectivity.py**
- Mocked Hashmob API connectivity test
- Mocked Hashmob API connectivity test by default
- Set `HASHMOB_TEST_REAL=1` to run against live Hashmob
### 2. Key Mock Patterns
@@ -55,19 +65,38 @@ Updated `readme.md` with:
- Testing section explaining how to run tests locally
- Description of test structure
## Environment Variables for Live Tests
By default, external service checks are skipped. Enable them explicitly:
- `HASHMOB_TEST_REAL=1` — run live Hashmob tests (including connectivity and CLI menu flag)
- `HASHVIEW_TEST_REAL=1` — run live Hashview CLI menu test
- `WEAKPASS_TEST_REAL=1` — run live Weakpass CLI menu test
- `HATE_CRACK_REQUIRE_DEPS=1` — fail if required system tools are missing
- `HATE_CRACK_RUN_LIVE_TESTS=1` — run live Hashview upload tests (requires config.json credentials)
- `HATE_CRACK_RUN_LIVE_HASHVIEW_TESTS=1` — run live Hashview wordlist upload tests
- `HATE_CRACK_RUN_E2E=1` — run end-to-end local installation tests
- `HATE_CRACK_RUN_DOCKER_TESTS=1` — run Docker-based end-to-end tests
When `HASHMOB_TEST_REAL` is enabled, tests will still skip if Hashmob returns errors like HTTP 523 (origin unreachable).
## Test Results
25 tests passing
⚡ Tests run in <1 second on a typical dev machine
✅ 56 tests passing (as of current version)
⚡ Tests run in ~1 second on a typical dev machine
### Test Coverage
Highlights:
1. Hashview API workflows (list customers, upload hashfile, create jobs, download left hashes)
2. Utility helpers (sanitize session ids, line count, path resolution, hex conversion)
3. Menu output snapshots
4. Hashmob connectivity (mocked)
5. Module import sanity checks
2. API download functionality (mocked downloads, 7z extraction, progress bars)
3. CLI menu flags (--hashview, --weakpass, --hashmob)
4. Dependency checks (7z, transmission-cli)
5. Hashmob connectivity (mocked by default, opt-in live tests)
6. Pipal integration and analysis
7. UI menu options (all attack modes)
8. Hashcat-utils submodule verification
9. Docker and E2E installation tests (opt-in)
## Benefits
@@ -80,17 +109,29 @@ Highlights:
## Running Tests
```bash
# Install dependencies
pip install pytest pytest-mock requests
# Run all tests
pytest -v
uv run pytest -v
# Or via Makefile
make test
# Run specific test
pytest tests/test_hashview.py -v
uv run pytest tests/test_hashview.py -v
# Run a specific test method
pytest tests/test_hashview.py::TestHashviewAPI::test_create_job_workflow -v
uv run pytest tests/test_hashview.py::TestHashviewAPI::test_create_job_workflow -v
# Run live Hashmob checks
HASHMOB_TEST_REAL=1 uv run pytest tests/test_hashmob_connectivity.py -v
# Require system deps (7z, transmission-cli)
HATE_CRACK_REQUIRE_DEPS=1 uv run pytest tests/test_dependencies.py -v
# Run end-to-end tests
HATE_CRACK_RUN_E2E=1 uv run pytest tests/test_e2e_local_install.py -v
# Run Docker tests
HATE_CRACK_RUN_DOCKER_TESTS=1 uv run pytest tests/test_docker_script_install.py -v
```
## Note on Real API Testing
+10
View File
@@ -11,6 +11,13 @@ HATE_CRACK_SCRIPT = os.path.join(os.path.dirname(__file__), '..', 'hate_crack.py
("--hashmob", "Official Hashmob Wordlists", None),
])
def test_direct_menu_flags(monkeypatch, flag, menu_text, alt_text):
# Only check external services if explicitly enabled
if flag == "--hashmob" and not os.environ.get('HASHMOB_TEST_REAL', '').lower() in ('1', 'true', 'yes'):
pytest.skip("Skipping --hashmob test unless HASHMOB_TEST_REAL is set.")
if flag == "--hashview" and not os.environ.get('HASHVIEW_TEST_REAL', '').lower() in ('1', 'true', 'yes'):
pytest.skip("Skipping --hashview test unless HASHVIEW_TEST_REAL is set.")
if flag == "--weakpass" and not os.environ.get('WEAKPASS_TEST_REAL', '').lower() in ('1', 'true', 'yes'):
pytest.skip("Skipping --weakpass test unless WEAKPASS_TEST_REAL is set.")
cli_cmd = [sys.executable, HATE_CRACK_SCRIPT, flag]
def fake_input(prompt):
return 'q'
@@ -23,6 +30,9 @@ def test_direct_menu_flags(monkeypatch, flag, menu_text, alt_text):
env={**os.environ, 'PYTHONUNBUFFERED': '1'}
)
output = result.stdout + result.stderr
# If Hashmob is down, skip the test for --hashmob
if flag == "--hashmob" and ("523" in output or "Server Error" in output or "Error listing official wordlists" in output):
pytest.skip("Hashmob is down or unreachable (error 523 or server error)")
if alt_text:
assert menu_text in output or alt_text in output, f"Expected '{menu_text}' or '{alt_text}' in output for flag {flag}"
else:
+4 -1
View File
@@ -1,3 +1,4 @@
import os
import shutil
import warnings
@@ -7,7 +8,9 @@ import pytest
def _require_executable(name):
if shutil.which(name) is None:
warnings.warn(f"Missing required dependency: {name}", RuntimeWarning)
pytest.fail(f"Required dependency not installed: {name}")
if os.environ.get("HATE_CRACK_REQUIRE_DEPS", "").lower() in ("1", "true", "yes"):
pytest.fail(f"Required dependency not installed: {name}")
pytest.skip(f"Missing required dependency: {name}")
def test_dependency_7z_installed():
+22 -5
View File
@@ -1,16 +1,33 @@
import os
import re
import pytest
from hate_crack.api import download_hashmob_wordlist_list
def test_hashmob_connectivity_real(capsys):
try:
result = download_hashmob_wordlist_list()
except Exception as e:
pytest.skip(f"Network or API unavailable: {e}")
if not os.environ.get('HASHMOB_TEST_REAL', '').lower() in ('1', 'true', 'yes'):
# Mocked response
result = [
{'name': 'mock_wordlist_1', 'information': 'Mock info 1'},
{'name': 'mock_wordlist_2', 'information': 'Mock info 2'}
]
print("Available Hashmob Wordlists:")
for idx, wl in enumerate(result):
print(f"{idx+1}. {wl['name']} - {wl['information']}")
captured = capsys.readouterr()
else:
try:
result = download_hashmob_wordlist_list()
except Exception as e:
if '523' in str(e) or 'HTTP ERROR 523' in str(e):
pytest.skip("Hashmob returned HTTP ERROR 523 (Origin is unreachable)")
pytest.skip(f"Network or API unavailable: {e}")
captured = capsys.readouterr()
if 'HTTP ERROR 523' in captured.out or '523' in captured.out:
pytest.skip("Hashmob returned HTTP ERROR 523 (Origin is unreachable)")
assert isinstance(result, list)
assert any('name' in wl for wl in result)
captured = capsys.readouterr()
# Check for at least one wordlist name in output using regex
names = [wl['name'] for wl in result if 'name' in wl]
found = False