From 01a51bbca6d0c7a20696aeef9ed92b143e26b10c Mon Sep 17 00:00:00 2001
From: Hardik Zinzuvadiya <25708027+Z4nzu@users.noreply.github.com>
Date: Sun, 15 Mar 2026 20:03:08 +0530
Subject: [PATCH] Restructure for v2.0.0 with new tools, features, and UI
updates (#590)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
* Phase 0: Add foundation files for v2.0.0 restructure
- constants.py: single source of truth for repo URLs, version (2.0.0),
all paths via Path.home(), UI theme constants, PRIV_CMD auto-detection
- os_detect.py: OSInfo dataclass, auto-detect OS/distro/package manager,
CURRENT_OS singleton, per-OS install command maps
- config.py: get_tools_dir(), load()/save() config.json, get_sudo_cmd()
- tools/__init__.py, tools/others/__init__.py: make proper Python packages
- IMPLEMENTATION.md: full 18-section restructuring plan (2350+ lines)
- LOG.md: 13-phase progress tracker
* Phase 1+2: Fix all 30 critical bugs and 4 security vulnerabilities
* Phase 3: Installation & path overhaul
* Phase 4+5: Core architecture + shared console across all tool files
Phase 4 (core.py — largely done in Phase 1, completed here):
- HackingTool: add ARCHIVED, ARCHIVED_REASON, SUPPORTED_OS, REQUIRES_* fields
- HackingTool: remove INSTALLATION_DIR (unused)
- HackingToolsCollection: add _active_tools(), _archived_tools(), _incompatible_tools()
- HackingToolsCollection: add _show_archived_tools() (option 98 sub-menu)
- HackingToolsCollection.show_options(): filter by OS and ARCHIVED flag
- OS-incompatible tools show count but are hidden from menu
- Archived tools accessible via option 98 with reason displayed
Phase 5 (all 22 remaining tool files):
- Remove local console = Console() and _theme = Theme() from all 22 files
- Remove P_COLOR and PURPLE_STYLE local constants
- Add `from core import HackingTool, HackingToolsCollection, console` everywhere
- Remove show_options() overrides from all collection classes (500+ lines deleted)
- Remove pretty_print() overrides from all collection classes
- Remove _get_attr() / _get_attr_fallback() helpers from all collection classes
- Replace super(ClassName, self).__init__() → super().__init__() in all files
- Remove # coding=utf-8 headers from all files
- Fix remaining PURPLE_STYLE usages → "bold magenta" literal
All 28 tool modules import cleanly. Zero local console instances remain.
* Phase 6: Naming & structure cleanup
- Rename tools/phising_attack.py → phishing_attack.py (fix typo)
- Rename tools/information_gathering_tools.py → information_gathering.py
- Rename tools/wireless_attack_tools.py → wireless_attack.py
- Rename tools/forensic_tools.py → forensics.py
- Rename tools/sql_tools.py → sql_injection.py
- Rename tools/webattack.py → web_attack.py
- Rename class autophisher → Autophisher (PEP-8 CapWords)
- Rename class ddos → DDoSTool (PEP-8 CapWords), TITLE "ddos" → "DDoS"
- Update all imports in hackingtool.py and exploit_frameworks.py
* Phase 7: Tool install command fixes
- Replace setup.py install → pip install --user . (explo, takeover, reconspider, infoga)
- Mark Blazy as ARCHIVED: Python 2 only (pip2.7/python2.7)
- Replace sudo git clone → git clone everywhere (no root needed for user tools dir)
- Replace sudo pip install → pip install --user everywhere
- Fix dalfox: git clone + cd approach → go install github.com/hahwul/dalfox/v2@latest
- Add apt -y flag to ReconSpider apt install
* Phase 8: Mark archived tools and add SUPPORTED_OS flags
- Remove stale sys.path.append hack from forensics.py (unused since package structure)
- Add SUPPORTED_OS = ["linux"] to BulkExtractor, Guymager (apt/Linux-only)
- Add SUPPORTED_OS = ["linux"] to all android_attack.py tools (bash scripts)
- Add SUPPORTED_OS = ["linux"], REQUIRES_WIFI = True to wifi_jamming.py tools
- Fix WifiJammerNG RUN_COMMANDS: python → python3, remove boxes/lolcat pipe
* Phase 11: requirements.txt and Dockerfile cleanup
- requirements.txt: remove boxes, lolcat (system CLI tools not pip packages),
flask (unused), requests (unused at runtime); pin rich>=13.0.0
- Dockerfile: add --break-system-packages to pip3 install (PEP 668 compliance
on Kali/Debian externally-managed Python environments)
* Phase 13: Python 3 modernization and os.system cleanup
- Replace os.system("cd X; ...") no-op cd subshells with subprocess.run(cwd=...)
in: xss_attack.py (XSSCon, XanXSS), payload_creator.py (TheFatRat update/troubleshoot),
forensics.py (BulkExtractor gui/cli), phishing_attack.py (BlackPhish update)
- Replace os.system echo+boxes+lolcat in post_exploitation.py with console.print
- Fix socialmedia_finder.py: print()+os.system+lolcat → subprocess+console.print
- Fix forensics.py cli_mode: os.system apt/bulk_extractor → subprocess.run list form
* Phase 13 (cont): Final os.system cleanup
- anonsurf.py: os.system("sudo anonsurf stop") → subprocess.run list form
- tool_manager.py: os.system(f"{priv}{cmd}") → subprocess.run(shell=True)
(shell=True justified: cmd is from hardcoded PACKAGE_UPDATE_CMDS dict, not user input)
* Phase 9: Add SUPPORTED_OS flags to remaining Linux-only tools
Mark bash-script and apt-dependent tools as linux-only so they are
hidden automatically on macOS via _active_tools() filter in core.py:
- phishing_attack.py: 14 tools (all bash-script based)
- ddos.py: all 6 tools (Linux network stack required)
- post_exploitation.py: Vegile, ChromeKeyLogger
- payload_creator.py: all 7 tools (bash setup scripts)
- exploit_frameworks.py: WebSploit (bash install)
- reverse_engineering.py: Apk2Gold (bash build)
- xss_attack.py: RVuln (Rust + apt deps)
* Phase 10: Add modern tools across 6 categories
Information Gathering (+7):
theHarvester, Amass, Masscan, RustScan, Holehe, Maigret, httpx
Web Attack (+6):
Nuclei, ffuf, Feroxbuster, Nikto, wafw00f, Katana
Wordlist/Password (+3):
Hashcat, John the Ripper, haiti
Wireless Attack (+3):
Airgeddon, hcxdumptool, hcxtools
Forensics (+2):
Volatility3, Binwalk
Post Exploitation (+1):
pwncat-cs
* Phase 12: Update README for v2.0.0
- Version badge: v1.2.0 -> v2.0.0
- Python badge: Python-3 -> Python-3.10+
- Add macOS to platform badge
- Add 'What's new in v2.0.0' section replacing stale v1.2.0 notes
- Regenerate full tool list — 22 new tools marked with new
- Fix docker build typo: 'docker buitl' -> 'docker build'
- Add Requirements section (Python 3.10+, Go 1.21+, Ruby)
- Remove stale 'To do' checklist and old Docker output block
* Redesign README, templates, and update .github workflows
README.md:
- Modern centered header with full badge row
- Stats banner: 17 categories, 150+ tools
- What's new as a comparison table
- Tool category table with per-category counts
- Complete tool listing with star markers for new tools
- Contributing section with enforced title formats for issues and PRs
- Star History chart (Z4nzu/hackingtool)
- Cleaned up Installation, Requirements, Social sections
README_template.md:
- Full redesign matching README.md layout
- {{toc}} and {{tools}} placeholders preserved for generate_readme.py
- Contributing section with title format rules embedded in template
.github/ISSUE_TEMPLATE/bug_report.md:
- Remove irrelevant browser/smartphone sections
- Add tool name, category, error output, environment table
.github/ISSUE_TEMPLATE/feature_request.md:
- Tighten to 4 focused fields, note tool additions use separate template
.github/ISSUE_TEMPLATE/tool_request.md (new):
- Structured template for new tool suggestions
- Required fields: name, URL, category, OS, install/run commands, reason
- Enforced title format: [Tool Request] ToolName - Category
.github/PULL_REQUEST_TEMPLATE.md (new):
- PR checklist for new tool additions and other change types
- Enforced title format: [New Tool] / [Fix] / [Improve]
- All required class fields listed as checklist items
.github/workflows/lint_python.yml:
- actions/checkout v3 -> v4, setup-python v4 -> v5
- python-version: 3.x -> 3.12 (project requires 3.10+)
- ruff target-version: py37 -> py310
- ruff --show-source -> --output-format=full (updated flag name)
- Remove deprecated safety check command
.github/workflows/test_install.yml:
- actions/checkout v3 -> v4, setup-python v4 -> v5
- python-version: 3.x -> 3.12
- Replace fragile matrix of hard-coded menu numbers with
two simple smoke tests: launch+quit, and navigate+back
* Improve Dockerfile, docker-compose, add .dockerignore
Dockerfile:
- Add '# syntax=docker/dockerfile:1' to enable BuildKit features
- Add LABEL metadata (OCI image spec)
- Remove unused apt packages: sudo, python3-venv
- Replace --no-cache-dir with --mount=type=cache for pip (faster rebuilds)
- Add comments explaining each decision
docker-compose.yml:
- Remove deprecated 'version:' field (Compose v2 ignores it, shows warning)
- Add 'image: hackingtool:latest' tag for clarity
- Add 'restart: unless-stopped' for production service
- Add 'hackingtool-dev' profile service with live source volume mount
so dev workflow (edit without rebuild) is separate from default run
- Clarify volume purpose in comments
.dockerignore (new):
- Exclude .git/, images/, __pycache__/, .github/, *.md, tests/
- Prevents multi-hundred-MB build context; dramatically reduces image size
- Keeps layer cache more stable (README changes no longer bust COPY layer)
README.md / README_template.md:
- Replace single-line Docker snippet with 3-option step-by-step guide:
Option A: docker run -it --rm (no Compose)
Option B: docker compose up -d + exec (recommended)
Option C: docker compose --profile dev (live source mount)
- Add docker compose down / down -v stop instructions
* Fix Docker sudo error, 99 back navigation, and empty input exit
install.py:
- sudo prefix now determined by euid (== 0 means root) not by OS name
- Previously used 'sudo ' for all Linux — breaks inside Docker where we
run as root but sudo is not installed
- Single priv variable computed once at top of install_system_packages()
Dockerfile:
- Add python3-venv back to apt installs
- Was removed as 'unused' but install.py uses 'python3 -m venv' to create
the virtualenv in APP_INSTALL_DIR; missing package caused venv failure
core.py (HackingTool.show_options + HackingToolsCollection.show_options):
- 99 always returns now instead of sys.exit() when parent is None
Previously: sub-menus with no parent called sys.exit() — since
interact_menu() never passes parent, pressing 99 in any category
exited the entire program instead of returning to the main menu
- Empty Enter (blank input) now continues the loop instead of
defaulting to "99" and triggering exit
Previously: Prompt default="99" meant pressing Enter without typing
anything was treated as choosing exit
- "Exit" label on 99 row changed to "Main Menu" since it now returns
* Restore Description column and 1-based numbering in collection menus
HackingToolsCollection.show_options():
- Add Description column back (was dropped during restructure)
- Show first line of description; '—' for tools with no description
- Switch to box.SIMPLE_HEAD with show_lines=True for row separators
- Numbering changed from 0-based to 1-based (index 1..N)
- Input validation updated: 1 <= choice <= len(active) with active[choice-1]
* Redesign main menu: compact header, 2-column grid, 1-based numbering, ? help
Header:
- Replace 8-line pixelated ASCII logo with a compact 9-line styled panel
- Shows tool name, version, repo URL, and legal warning in one block
- Screen is now cleared inside build_menu() on each main menu render
Menu layout:
- Single narrow column → 2-column grid (9 left / 8 right)
- Full terminal width is used; short display labels prevent truncation
- tool_definitions gains a third field (menu_label) for the grid;
full TITLE is still used when entering a category
Numbering:
- 0-based → 1-based throughout interact_menu()
- ToolManager is item 18 (was mislabeled 99, conflicting with exit)
- Input validation: 1 <= choice <= len(all_tools) → all_tools[choice - 1]
Commands:
- Add ? / help → show Quick Help overlay (main/category/tool reference)
- Add q / quit / exit → clean exit with goodbye message
- Remove Confirm.ask("Return to main menu?") — pressing 99 in any
sub-menu already returns here; the extra prompt was redundant friction
- Ctrl+C still works as force quit
Error messages updated to reflect new command set
* Redesign header: hacker split-layout with ASCII art + live system info
Replace compact text panel with a Metasploit-style split header:
- Left: "HT" block-letter ASCII art in bright green
- Vertical │ separator that runs the full height of the art block
- Right: live system stats — os, kernel, user@host, ip, tool count, session time
- Bottom: random hacker quote (10 options, changes on each launch)
- Bottom: authorized-use warning in dim red
- Panel title: '[ HackingTool v2.0.0 ]' left-aligned (terminal bracket style)
- Panel subtitle: '[ timestamp ]' right-aligned
- Border: bright_magenta HEAVY box
Live info gathered via platform, socket, os.getlogin() with fallbacks:
- OS: platform.freedesktop_os_release() → PRETTY_NAME, else platform.system()
- IP: UDP connect trick (no data sent, gets local outbound IP)
- User: os.getlogin() → USER env → LOGNAME env → 'root'
* Redesign header: full HACKING TOOL art + ? and q in all sub-menus
hackingtool.py:
- Replace 6-line "HT" art with full 12-line "HACKING TOOL" block letters
- Right side gains 3 more info lines: python version, arch, status
- 12 art lines paired with 12 stat lines for consistent separator
- Layout optimized for wide terminals (100+ chars); gracefully
truncates on narrow ones
core.py — ? and q support in all sub-menus:
- Add _show_inline_help() function: compact navigation reference
(1-N select, 99 back, 98 project page, ? help, q quit)
- HackingTool.show_options(): parse ? → inline help, q → SystemExit
- HackingToolsCollection.show_options(): same ? and q handling
- Both menus now show hint bar: "Enter number · ? help · q quit"
- Prompt changed from "[?] Select" to ">" for consistency with main menu
- q/quit/exit raises SystemExit(0) to cleanly exit from any depth
* Add install.sh one-liner and fix install.py to detect local source
install.sh (new):
- Standalone bash installer for curl | sudo bash one-liner
- Detects package manager (apt-get, pacman, dnf, brew)
- Installs prerequisites: git, python3, pip, venv
- Checks Python >= 3.10
- Clones repo with --depth 1 (shallow, faster)
- Creates venv + installs requirements
- Creates /usr/bin/hackingtool launcher
- Creates ~/.hackingtool/ dirs with correct ownership (SUDO_USER)
install.py:
- Add _is_source_dir() — detects if install.py is being run from a local
clone (hackingtool.py exists alongside it)
- install_source() replaces git_clone() — copies source to /usr/share/
instead of re-cloning when running from a local clone
- Falls back to git clone --depth 1 when not in a source directory
- Eliminates the redundant clone-after-clone pattern
README.md / README_template.md:
- Add one-liner install as primary method
- Keep manual git clone + install.py as alternative
- Remove sudo from hackingtool run command (launcher handles it)
* Add 35 new tools across 3 new + 6 existing categories
New categories:
- tools/active_directory.py: BloodHound, NetExec (nxc), Impacket,
Responder, Certipy, Kerbrute (6 tools)
- tools/cloud_security.py: Prowler, ScoutSuite, Pacu, Trivy (4 tools)
- tools/mobile_security.py: MobSF, Frida, Objection (3 tools)
Existing categories expanded:
- information_gathering.py: +SpiderFoot, Subfinder, TruffleHog, Gitleaks (4)
- web_attack.py: +Gobuster, Dirsearch, OWASP ZAP, testssl.sh, Arjun,
Caido, mitmproxy (7)
- post_exploitation.py: +Sliver, Havoc, PEASS-ng, Ligolo-ng, Chisel,
Evil-WinRM, Mythic (7)
- reverse_engineering.py: +Ghidra, Radare2 (2)
- forensics.py: +pspy (1)
- wireless_attack.py: +Bettercap (1)
hackingtool.py:
- Import 3 new category modules
- Add 3 new entries to tool_definitions (AD, Cloud, Mobile)
- Add 3 new instances to all_tools list
- Categories: 17 -> 20, total tools: 150+ -> 185+
- Help overlay updated for new range (1-20, 21=Update)
* Feature: Search tools by name or keyword (/ or s)
- Add _collect_all_tools() — walks all collections recursively and
returns (tool_instance, category_name) pairs for 185 tools
- Add search_tools() — prompts for query, matches against TITLE and
DESCRIPTION (case-insensitive), shows results table with category,
user selects a result number to jump directly into tool.show_options()
- Wire / and s commands into interact_menu()
- Add / search to help overlay and hint bar
- Fix ToolManager row number: was hardcoded 18, now computed dynamically
from len(categories) + 1 (currently 21)
* Feature: Show installed status (✔/✘) next to each tool
core.py:
- Add is_installed property to HackingTool class
Checks: (1) shutil.which() for binary from first RUN_COMMAND,
(2) os.path.isdir() for git clone target directory
Handles "cd foo && binary" and "sudo binary" patterns
- Add status column to HackingToolsCollection.show_options() table
✔ (green) = installed, ✘ (dim) = not installed
- Archived/back rows updated for extra column
* Feature: Tag-based filtering with auto-derived tags (t command)
core.py:
- Add TAGS field to HackingTool class (list[str], default empty)
- Allows manual tag override per tool
hackingtool.py:
- Add _get_all_tags() — builds tag index from 19 regex rules that
auto-derive tags from tool TITLE + DESCRIPTION (osint, scanner, c2,
web, cloud, mobile, wireless, forensics, reversing, etc.)
- Manual TAGS on a tool class take priority over auto-derived
- Add filter_by_tag() — shows all available tags with tool counts,
user picks a tag, results shown with installed status, select to
jump directly into tool.show_options()
- Wire t/tag/tags/filter commands into interact_menu()
- Search also matches against TAGS field
- Updated hint bar: / search · t tags · ? help · q quit
- Updated help overlay with tag filter entry
* Feature: Install all tools in a category (option 97)
HackingToolsCollection.show_options():
- Count not-installed tools using is_installed property
- Show option 97 'Install all (N not installed)' when N > 0
- On select: iterates all not-installed tools, calls tool.install()
with progress counter (1/N, 2/N, ...) and error handling per tool
- Hidden when all tools are already installed
- Updated inline help to mention option 97
* Feature: Update command for each tool (option 3 in tool menu)
HackingTool:
- Add update() method — detects install method from INSTALL_COMMANDS
and runs the appropriate update:
git clone → git -C
pull
pip install → pip install --upgrade
go install → re-runs go install (fetches latest)
gem install → gem update
- Checks is_installed first; shows warning if not installed
- Added as option 3 in every tool's OPTIONS menu (Install, Run, Update)
* Feature: Tool recommendations — "I want to do X" (r command)
- Add _RECOMMENDATIONS dict — maps 22 common tasks to tag names:
"scan a network" → scanner, "crack passwords" → bruteforce/credentials,
"pentest active directory" → active-directory, "pivot through network"
→ network, etc.
- Add recommend_tools() — shows numbered task list, user picks one,
shows all matching tools with installed status, select to jump in
- Wire r/rec/recommend into interact_menu()
- Updated hint bar and help overlay
* Update README with all new features, 3 new categories, 35 new tools
- Stats banner: 17 → 20 categories, 150+ → 185+ tools
- What's New table: add 10 new feature entries (search, tags, recommend,
install status, install all, update, one-liner, new categories/tools)
- Add Quick Commands reference table (/, t, r, ?, q, 97, 99)
- Tool Categories table: add Active Directory, Cloud Security,
Mobile Security rows; update tool counts for expanded categories
- Add 3 new category sections: Active Directory Tools (6), Cloud
Security Tools (4), Mobile Security Tools (3) with GitHub links
- Mark all 35 new tools with ★ in their respective category sections
* UI: Dual-line prompt and inline /query search
Prompt style (all menus):
- Replace bare '>' with '╰─>' connected to the hint bar above
- Hint bar uses Claude CLI style: first letter highlighted in cyan,
rest dimmed (/search tags recommend ?help quit)
- Creates a visual dual-line input area similar to Claude Code CLI
Inline search:
- Typing /subdomain at the main prompt immediately searches and
shows results — no second "enter query" prompt needed
- / (bare slash) still opens the interactive search prompt
- s still works as a search alias
- search_tools() now accepts optional query parameter
core.py sub-menus:
- Same dual-line prompt style: hint bar + ╰─>
- Compact hint: ?help quit 99 back
* Fix is_installed crash on sub-collections (OtherTools)
OtherTools.TOOLS contains HackingToolsCollection instances (like
SocialMediaBruteforceTools) which don't have the is_installed property.
- Guard is_installed access with hasattr() in both the status column
and the not_installed count for Install All
- Sub-collections show blank status; individual tools show ✔/✘
* Add Buy Me a Coffee link to README and FUNDING.yml
- README.md: Add Support section with Buy Me a Coffee button above Social
- .github/FUNDING.yml: Add buy_me_a_coffee: hardikzinzu
(enables GitHub Sponsor button on the repo page)
* Feature: Open Folder option to manually access tool directory
HackingTool:
- Add _get_tool_dir() — finds the tool's local directory by checking:
1. Git clone target dir (from INSTALL_COMMANDS)
2. "cd foo && bar" pattern in RUN_COMMANDS
3. Binary location via shutil.which() → dirname
- Add open_folder() — opens the tool's directory in a new shell ($SHELL)
so the user can inspect files, run manual install steps, or debug
If dir not found: shows a helpful message with git clone command
- Added as option 4 in every tool menu (Install, Run, Update, Open Folder)
- Updated inline help to mention the tool menu options
* Add SVG logo and update README header
images/logo.svg:
- Terminal-style dark background with rounded corners
- Red/yellow/green window dots (macOS style)
- Green shield with skull & crossbones icon
- "HACKING" in purple-to-pink gradient with glow
- "TOOL" in hacker green with glow effect
- Blinking cursor animation, binary numbers, corner brackets
- Monospace font, 600x200 viewport
README.md:
- Replace plain # HackingTool heading with centered logo SVG
* Redesign README with modern GitHub features
Header:
- for-the-badge style badges with logos and custom colors
- Stats counter table (20 categories, 185+ tools, 19 tags, 2 platforms)
- CTA buttons: Install Now, Quick Commands, Suggest a Tool
What's New:
- Wrapped in collapsible with icon-prefixed table rows
- Each feature has an emoji icon for visual scanning
Quick Commands:
- Centered table with Works-in column showing scope
Tool Categories:
- 2-column table layout showing all 20 categories side by side
- Wrapped in collapsible section
Tool lists:
- Every category wrapped in collapsible sections
- Keeps README scannable — users expand only what they need
- New tools still marked with star
Contributing:
- Side-by-side table: Issue template left, PR template right
Installation:
- Side-by-side table: One-liner left, Manual right
- Docker in collapsible section (not everyone needs it)
Requirements:
- Table format with version, dependency, and "needed for" columns
Support/Social:
- Centered layout with for-the-badge Twitter/GitHub follow buttons
- Larger Buy Me a Coffee button
* Redesign README header, add category emojis, left-align support
Header:
- Consolidate badges into 2 clean rows instead of 4 sparse rows
- Row 1: flat-square badges (license, python, version, stars, forks,
issues, last commit) — compact, inline, no awkward gaps
- Row 2: for-the-badge stat pills (20 Categories, 185+ Tools, 19 Tags,
Linux|Kali|Parrot|macOS) — single row, removes duplicate Platform badge
- CTA buttons tightened with consistent spacing
Category headings:
- Add emoji to every ## category heading throughout the README
(matching the index table emojis)
Support section:
- Left-aligned instead of centered
- Social split into its own heading
Also removes all / collapse wrappers — all sections
are plain visible as requested
* Fix missing imports: subprocess in payload_creator, Table in wordlist_generator
- payload_creator.py: add 'import subprocess' (used by TheFatRat methods)
- wordlist_generator.py: add 'from rich.table import Table' (used by show_options)
- Fixes 6 ruff F821 'Undefined name' errors
* Fix codespell error: 'ags' flagged as misspelling in hint bar
Restructure the hint bar string so shortcut letters and their labels
are separate tokens ('t' + 'tags') instead of split across Rich markup
tags ('t' + 'ags') which codespell flagged as a misspelling.
* Fix 12 issues from Copilot PR review (#590)
post_exploitation.py:
- Rename INSTALL_OS -> SUPPORTED_OS in Havoc class (typo, field was ignored)
- Sliver: replace curl|sudo bash pipe with download-then-execute pattern
ddos.py:
- Add DDoSTool() to DDOSTools.TOOLS list (was defined but unreachable)
phishing_attack.py:
- Rename class Evilginx2 -> Evilginx3 (installs v3 via go install)
- Update instance in TOOLS list to match
- Fix stale comment: wireless_attack_tools.py -> wireless_attack.py
forensics.py:
- Remove installable=False from Guymager (conflicted with INSTALL_COMMANDS)
tool_manager.py:
- Skip sudo prefix when already root (os.geteuid() == 0), matching
the pattern already used in install.py
install.py:
- Add chown -R root:root after cp -a to prevent git "dubious ownership"
errors when the source clone has different ownership
update.sh:
- Add git config safe.directory before pull to prevent dubious ownership
- Add --upgrade flag to pip install so dependencies actually update
os_detect.py:
- Add pkg (FreeBSD) entries to PACKAGE_INSTALL_CMDS, PACKAGE_UPDATE_CMDS,
and REQUIRED_PACKAGES — was detected but had no command mappings (KeyError)
Skipped (not applicable):
- #1 subprocess import: already fixed in prior commit
- #11 Path.home() under sudo: by design (installer runs as root)
---
.dockerignore | 30 +
.github/FUNDING.yml | 1 +
.github/ISSUE_TEMPLATE/bug_report.md | 55 +-
.github/ISSUE_TEMPLATE/feature_request.md | 25 +-
.github/ISSUE_TEMPLATE/tool_request.md | 43 +
.github/PULL_REQUEST_TEMPLATE.md | 45 ++
.github/workflows/lint_python.yml | 19 +-
.github/workflows/test_install.yml | 34 +-
Dockerfile | 34 +-
README.md | 575 ++++++++++----
README_template.md | 216 +++--
config.py | 43 +
constants.py | 65 ++
core.py | 527 ++++++++++---
docker-compose.yml | 37 +-
hackingtool.py | 746 ++++++++++++++----
images/logo.svg | 106 +++
install.py | 347 ++++----
install.sh | 153 ++++
os_detect.py | 131 +++
requirements.txt | 10 +-
tools/__init__.py | 0
tools/active_directory.py | 75 ++
tools/anonsurf.py | 106 +--
tools/cloud_security.py | 51 ++
tools/ddos.py | 203 ++---
tools/exploit_frameworks.py | 109 +--
tools/forensic_tools.py | 179 -----
tools/forensics.py | 156 ++++
...ring_tools.py => information_gathering.py} | 284 ++++---
tools/mobile_security.py | 42 +
tools/other_tools.py | 83 +-
tools/others/__init__.py | 0
tools/others/android_attack.py | 85 +-
tools/others/email_verifier.py | 67 +-
tools/others/hash_crack.py | 65 +-
tools/others/homograph_attacks.py | 67 +-
tools/others/mix_tools.py | 96 +--
tools/others/payload_injection.py | 73 +-
tools/others/socialmedia.py | 103 +--
tools/others/socialmedia_finder.py | 100 +--
tools/others/web_crawling.py | 69 +-
tools/others/wifi_jamming.py | 80 +-
tools/payload_creator.py | 181 ++---
tools/phishing_attack.py | 256 ++++++
tools/phising_attack.py | 319 --------
tools/post_exploitation.py | 196 +++--
tools/remote_administration.py | 93 +--
tools/reverse_engineering.py | 114 +--
tools/sql_injection.py | 88 +++
tools/sql_tools.py | 149 ----
tools/steganography.py | 73 +-
tools/tool_manager.py | 146 ++--
tools/web_attack.py | 285 +++++++
tools/webattack.py | 186 -----
tools/wireless_attack.py | 233 ++++++
tools/wireless_attack_tools.py | 233 ------
tools/wordlist_generator.py | 102 ++-
tools/xss_attack.py | 60 +-
update.sh | 67 +-
60 files changed, 4469 insertions(+), 3647 deletions(-)
create mode 100644 .dockerignore
create mode 100644 .github/FUNDING.yml
create mode 100644 .github/ISSUE_TEMPLATE/tool_request.md
create mode 100644 .github/PULL_REQUEST_TEMPLATE.md
create mode 100644 config.py
create mode 100644 constants.py
create mode 100644 images/logo.svg
create mode 100755 install.sh
create mode 100644 os_detect.py
create mode 100644 tools/__init__.py
create mode 100644 tools/active_directory.py
create mode 100644 tools/cloud_security.py
delete mode 100644 tools/forensic_tools.py
create mode 100644 tools/forensics.py
rename tools/{information_gathering_tools.py => information_gathering.py} (50%)
create mode 100644 tools/mobile_security.py
create mode 100644 tools/others/__init__.py
create mode 100644 tools/phishing_attack.py
delete mode 100644 tools/phising_attack.py
create mode 100644 tools/sql_injection.py
delete mode 100644 tools/sql_tools.py
create mode 100644 tools/web_attack.py
delete mode 100644 tools/webattack.py
create mode 100644 tools/wireless_attack.py
delete mode 100644 tools/wireless_attack_tools.py
diff --git a/.dockerignore b/.dockerignore
new file mode 100644
index 0000000..a087df4
--- /dev/null
+++ b/.dockerignore
@@ -0,0 +1,30 @@
+# Version control
+.git/
+.gitignore
+
+# GitHub / docs
+.github/
+images/
+*.md
+
+# Python cache
+__pycache__/
+*.py[cod]
+*.pyo
+.mypy_cache/
+.ruff_cache/
+.pytest_cache/
+
+# Tests
+tests/
+test_*.py
+
+# Docker files themselves (don't recurse)
+Dockerfile
+docker-compose.yml
+.dockerignore
+
+# OS / editor noise
+.DS_Store
+*.swp
+*.swo
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..d22dbc2
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+buy_me_a_coffee: hardikzinzu
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
index dd84ea7..d3f4891 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -1,38 +1,37 @@
---
-name: Bug report
-about: Create a report to help us improve
-title: ''
-labels: ''
+name: Bug Report
+about: Report a broken install, crash, or unexpected behavior
+title: "[BUG] — "
+labels: bug
assignees: ''
-
---
-**Describe the bug**
-A clear and concise description of what the bug is.
+## Description
+
-**To Reproduce**
-Steps to reproduce the behavior:
-1. Go to '...'
-2. Click on '....'
-3. Scroll down to '....'
-4. See error
+## Affected Tool
+- **Category:**
+- **Tool name:**
-**Expected behavior**
-A clear and concise description of what you expected to happen.
+## Steps to Reproduce
+1.
+2.
+3.
-**Screenshots**
-If applicable, add screenshots to help explain your problem.
+## Expected Behavior
+
-**Desktop (please complete the following information):**
- - OS: [e.g. iOS]
- - Browser [e.g. chrome, safari]
- - Version [e.g. 22]
+## Error Output
+```
+
+```
-**Smartphone (please complete the following information):**
- - Device: [e.g. iPhone6]
- - OS: [e.g. iOS8.1]
- - Browser [e.g. stock browser, safari]
- - Version [e.g. 22]
+## Environment
+| Field | Value |
+|---|---|
+| OS | |
+| Python | |
+| hackingtool | v2.0.0 |
-**Additional context**
-Add any other context about the problem here.
+## Additional Context
+
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index bbcbbe7..e69de57 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,20 +1,19 @@
---
-name: Feature request
-about: Suggest an idea for this project
-title: ''
-labels: ''
+name: Feature Request
+about: Suggest an improvement to hackingtool itself (not a new tool addition — use the Tool Request template for that)
+title: "[FEATURE] "
+labels: enhancement
assignees: ''
-
---
-**Is your feature request related to a problem? Please describe.**
-A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
+## Problem
+
-**Describe the solution you'd like**
-A clear and concise description of what you want to happen.
+## Proposed Solution
+
-**Describe alternatives you've considered**
-A clear and concise description of any alternative solutions or features you've considered.
+## Alternatives Considered
+
-**Additional context**
-Add any other context or screenshots about the feature request here.
+## Additional Context
+
diff --git a/.github/ISSUE_TEMPLATE/tool_request.md b/.github/ISSUE_TEMPLATE/tool_request.md
new file mode 100644
index 0000000..30c684d
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/tool_request.md
@@ -0,0 +1,43 @@
+---
+name: Tool Request
+about: Suggest a new tool to be added to hackingtool
+title: "[Tool Request] — "
+labels: tool-request
+assignees: ''
+---
+
+
+
+## Tool Details
+
+| Field | Value |
+|---|---|
+| **Tool name** | |
+| **GitHub URL** | |
+| **Category** | |
+| **Supported OS** | |
+| **Language** | |
+| **Install method** | |
+
+## Why should it be added?
+
+
+## Install Command
+```bash
+# paste the install command(s) here
+```
+
+## Run Command
+```bash
+# paste the run/usage command here
+```
+
+## Is the tool actively maintained?
+
+
+## Additional Notes
+
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000..8893cc3
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,45 @@
+
+
+## Type of Change
+- [ ] New tool addition
+- [ ] Bug fix
+- [ ] Improvement / refactor
+- [ ] Documentation update
+
+---
+
+## For New Tool Additions — Required Fields
+
+| Field | Value |
+|---|---|
+| **Tool name** | |
+| **GitHub URL** | |
+| **Category** | |
+| **Supported OS** | Linux / macOS / Both |
+| **Install method** | pip / go install / apt / git clone |
+
+**Why should it be added?**
+
+
+**Is the tool actively maintained?**
+
+
+---
+
+## Checklist
+
+- [ ] Title follows the format above
+- [ ] New tool class added to the correct `tools/*.py` file
+- [ ] `TITLE`, `DESCRIPTION`, `INSTALL_COMMANDS`, `RUN_COMMANDS`, `PROJECT_URL` all set
+- [ ] `SUPPORTED_OS` set correctly (`["linux"]` / `["linux", "macos"]`)
+- [ ] Tool added to the `TOOLS` list in the collection class at the bottom of the file
+- [ ] No new dependencies added to `requirements.txt` without discussion
+- [ ] Tested locally — install and run commands work
diff --git a/.github/workflows/lint_python.yml b/.github/workflows/lint_python.yml
index fff9533..8e37d90 100644
--- a/.github/workflows/lint_python.yml
+++ b/.github/workflows/lint_python.yml
@@ -8,24 +8,21 @@ jobs:
lint_python:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
- python-version: 3.x
+ python-version: "3.12"
- run: pip install --upgrade pip ruff setuptools wheel
- name: "Ruff: Show stopper (must-fix) issues"
- run: ruff . --select=E9,F63,F7,F82,PLE,YTT --show-source .
+ run: ruff check . --select=E9,F63,F7,F82,PLE,YTT --output-format=full
- name: "Ruff: All issues"
- run: ruff --exit-zero --select=ALL --statistics --target-version=py37 .
+ run: ruff check --exit-zero --select=ALL --statistics --target-version=py310 .
- name: "Ruff: All fixable (ruff --fix) issues"
- run: ruff --exit-zero --select=ALL --ignore=ANN204,COM812,ERA001,RSE102
- --statistics --target-version=py37 . | grep "\[\*\]"
- - run: pip install black codespell mypy pytest safety
+ run: ruff check --exit-zero --select=ALL --ignore=ANN204,COM812,ERA001,RSE102 --statistics --target-version=py310 . | grep "\[\*\]" || true
+ - run: pip install black codespell mypy pytest
- run: black --check . || true
- run: codespell
- - run: pip install -r requirements.txt || pip install --editable . || pip install . || true
+ - run: pip install -r requirements.txt || true
- run: mkdir --parents --verbose .mypy_cache
- run: mypy --ignore-missing-imports --install-types --non-interactive . || true
- run: pytest . || true
- - run: pytest --doctest-modules . || true
- - run: safety check
diff --git a/.github/workflows/test_install.yml b/.github/workflows/test_install.yml
index 353b9b6..148761b 100644
--- a/.github/workflows/test_install.yml
+++ b/.github/workflows/test_install.yml
@@ -9,28 +9,20 @@ jobs:
runs-on: ubuntu-latest
env:
TERM: "linux"
- strategy:
- fail-fast: false
- matrix:
- commands:
- # Enter hackingtool starting from the main menu with \n as the delimiter.
- - "17\n0\n1\n\n99\n99\n99" # Install, run, update, update system, press ENTER to continue, back to main menu, quit
- - "17\n0\n2\n\n99\n99\n99" # Install, run, update, update hackingtool, press ENTER to continue, back to main menu, quit
- - "17\n1\n1\n" # Install, run, uninstall, press ENTER to continue
- - "99" # Install, run, quit
steps:
- - uses: actions/checkout@v3
- - uses: actions/setup-python@v4
+ - uses: actions/checkout@v4
+ - uses: actions/setup-python@v5
with:
- python-version: 3.x
+ python-version: "3.12"
cache: 'pip'
- run: pip install --upgrade pip
- - run: pwd && ls -hal
- - run: sudo ./install.py 1
- - run: pwd && ls -hal
- # Typing "1" will allow us to manually enter the filepath to hackingtool.
- # Provide the filepath ${HOME}/work/hackingtool/hackingtool
- # Type the matrix.commands.
- - run: echo -e "1\n${HOME}/work/hackingtool/hackingtool\n${{ matrix.commands }}\n" | hackingtool
- - run: pwd && ls -hal
-
+ - run: pip install -r requirements.txt
+ - run: sudo python3 install.py 1
+ # Verify the hackingtool entrypoint is on PATH
+ - run: which hackingtool
+ # Smoke test: launch and immediately quit (99)
+ - name: "Smoke test: launch and quit"
+ run: echo -e "99\n" | hackingtool || true
+ # Navigate into first category and back out
+ - name: "Navigation test: enter category 1, quit"
+ run: echo -e "1\n99\n99\n" | hackingtool || true
diff --git a/Dockerfile b/Dockerfile
index f7b0f2b..01022be 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,12 +1,34 @@
+# syntax=docker/dockerfile:1
+# Enables BuildKit features (cache mounts, faster builds)
FROM kalilinux/kali-rolling:latest
+
+LABEL org.opencontainers.image.title="hackingtool" \
+ org.opencontainers.image.description="All-in-One Hacking Tool for Security Researchers" \
+ org.opencontainers.image.source="https://github.com/Z4nzu/hackingtool" \
+ org.opencontainers.image.licenses="MIT"
+
+# Install system dependencies
+# - sudo and python3-venv are not needed (container runs as root, venv unused)
+# - --no-install-recommends keeps the layer lean
RUN apt-get update && \
- apt-get install -y git python3-pip figlet sudo && \
- apt-get install -y boxes php curl xdotool wget
+ apt-get install -y --no-install-recommends \
+ git python3-pip python3-venv curl wget php && \
+ rm -rf /var/lib/apt/lists/*
WORKDIR /root/hackingtool
+
+# Copy requirements first so this layer is cached unless requirements change
COPY requirements.txt ./
-RUN pip3 install --no-cache-dir boxes flask lolcat requests -r requirements.txt
+
+# --mount=type=cache persists the pip cache across rebuilds (BuildKit only)
+# --break-system-packages required on Kali (PEP 668 externally-managed env)
+RUN --mount=type=cache,target=/root/.cache/pip \
+ pip3 install --break-system-packages -r requirements.txt
+
+# Copy the rest of the source (respects .dockerignore)
COPY . .
-RUN true && echo "/root/hackingtool/" > /home/hackingtoolpath.txt;
-EXPOSE 1-65535
-ENTRYPOINT ["python3", "/root/hackingtool/hackingtool.py"]
\ No newline at end of file
+
+# Ensure the tools directory exists for installs performed at runtime
+RUN mkdir -p /root/.hackingtool/tools
+
+ENTRYPOINT ["python3", "/root/hackingtool/hackingtool.py"]
diff --git a/README.md b/README.md
index c951a54..8156b5d 100644
--- a/README.md
+++ b/README.md
@@ -1,296 +1,527 @@
-### All in One Hacking tool For Hackers🥇
-
-
-
-
-
-
-
-[](http://hits.dwyl.com/Z4nzu/hackingtool)
-
+
-#### Install Kali Linux in WIndows10 Without VirtualBox [YOUTUBE](https://youtu.be/BsFhpIDcd9I) or use Docker
+
-## Update Available V1.2.0 🚀
-- [✔] Installation Bug Fixed
-- [x] Added New Tools
- - [x] Reverse Engineering
- - [x] RAT Tools
- - [x] Web Crawling
- - [x] Payload Injector
-- [x] Multitor Tools update
-- [X] Added Tool in wifijamming
-- [X] Added Tool in steganography
+
All-in-One Hacking Tool for Security Researchers & Pentesters
-### !! RUN HACKINGTOOL AS ROOT !!
+### Open an Issue
+> **Title:** `[Tool Request] ToolName — Category`
-## Steps are given below :
+Use the [Tool Request](.github/ISSUE_TEMPLATE/tool_request.md) template.
+Required: tool name, GitHub URL, category, OS, install command, reason.
-## Step : 1 Download hackingtool
+
+
- git clone https://github.com/Z4nzu/hackingtool.git
+### Open a Pull Request
-## Step : 2 Give Permission to hackingtool
-
- chmod -R 755 hackingtool
+> **Title:** `[New Tool] ToolName — Category`
-## Step : 3 Move to hackingtool directory
+Use the [PR template](.github/PULL_REQUEST_TEMPLATE.md) checklist.
- cd hackingtool
+Required: class in `tools/*.py`, TITLE, DESCRIPTION, INSTALL/RUN commands, SUPPORTED_OS, test locally.
-## Step : 4 Run hackingtool
-
- sudo python install.py
+
+
+
-## Step : 5 For installing tools in directory
+> Issues or PRs that don't follow the title format will be closed without review.
- sudo hackingtool
+---
+## Installation
-## Use image with Docker
+
+
+
+### Docker
-- Get into the container
```bash
+# Build
+docker build -t hackingtool .
+
+# Run (direct)
+docker run -it --rm hackingtool
+
+# Run (Compose — recommended)
+docker compose up -d
docker exec -it hackingtool bash
+
+# Dev mode (live source mount)
+docker compose --profile dev up
+docker exec -it hackingtool-dev bash
+
+# Stop
+docker compose down # stop container
+docker compose down -v # also remove data volume
```
-**OUTPUT:**
+
+
+
+### Requirements
+
+| Dependency | Version | Needed for |
+|---|---|---|
+| Python | 3.10+ | Core |
+| Go | 1.21+ | nuclei, ffuf, amass, httpx, katana, dalfox, gobuster, subfinder |
+| Ruby | any | haiti, evil-winrm |
+| Docker | any | Mythic, MobSF (optional) |
+
```bash
-Select Best Option :
-
- [1] Kali Linux / Parrot-Os (apt)
- [2] Arch Linux (pacman)
- [0] Exit
+pip install -r requirements.txt
```
-Enter the options and continue.
-- If need open other ports you can edit the docker-compose.yml file
-- Volumes are mounted in the container to persist data and can share files between the host and the container
+---
+## Star History
-#### Thanks to original Author of the tools used in hackingtool
+
+
+
+
+
-
-
Please Don't Use for illegal Activity
+---
-### To do
-- [ ] Release Tool
-- [ ] Add Tools for CTF
-- [ ] Want to do automatic
+## Support
-## Social Media :mailbox_with_no_mail:
-[](https://twitter.com/_Zinzu07)
-[](https://github.com/Z4nzu/)
-##### Your Favourite Tool is not in hackingtool or Suggestions Please [CLICK HERE](https://forms.gle/b235JoCKyUq5iM3t8)
-
+If this project helps you, consider buying me a coffee:
-#### Don't Forgot to share with Your Friends
-### The new Update get will soon stay updated
-#### Thank you..!!
+
+
+## Social
+
+[](https://twitter.com/_Zinzu07)
+[](https://github.com/Z4nzu/)
+
+> **For authorized security testing only.**
+> Thanks to all original authors of the tools included in hackingtool.
+
+Your favourite tool is not listed? [Suggest it here](https://github.com/Z4nzu/hackingtool/issues/new?template=tool_request.md)
diff --git a/README_template.md b/README_template.md
index 58f2fff..09bfaf7 100644
--- a/README_template.md
+++ b/README_template.md
@@ -1,69 +1,179 @@
-### All in One Hacking tool For Hackers🥇
-
-
-
-
-
-
-
-[](http://hits.dwyl.com/Z4nzu/hackingtool)
-
+
-#### How to run the Kali Linux CLI on Windows 10 without running a VM [YOUTUBE](https://youtu.be/BsFhpIDcd9I)
+# HackingTool
-## Update available V1.1.0 🚀
-- [x] Added New Tools
- - [x] Reverse Engineering
- - [x] RAT Tools
- - [x] Web Crawling
- - [x] Payload Injector
-- [x] Multitor Tools update
-- [X] Added Tool in Wifi-Jamming
+**All-in-One Hacking Tool for Security Researchers & Pentesters**
+[](LICENSE)
+[](https://www.python.org/)
+[](#)
+[](#)
+[](https://github.com/Z4nzu/hackingtool/stargazers)
+[](https://github.com/Z4nzu/hackingtool/network/members)
+[](https://github.com/Z4nzu/hackingtool/issues)
+[](https://github.com/Z4nzu/hackingtool/commits/master)
-# Hackingtool Menu 🧰
+
-
-
-
-
-
+---
-## Installation guide for Linux
+## What's New in v2.0.0
-#### THIS TOOL MUST BE RUN AS ROOT !!! run these following commands below ONE AT A TIME
+- Python 3.10+ required — all Python 2 code removed
+- OS-aware menus — Linux-only tools are hidden automatically on macOS
+- Archived tools (Python 2, unmaintained) shown in a separate sub-menu
+- All `os.chdir()` bugs fixed — tools install to `~/.hackingtool/tools/`
+- No more `sudo git clone` — tools install to user home, no root needed
+- 22 new modern tools added across 6 categories
+- Rich terminal UI with shared theme — no more 32 different console instances
+- Iterative menus — no more recursion stack overflow on deep navigation
+- Docker image builds locally — no unverified external images
+- `requirements.txt` cleaned — removed unused flask/boxes/lolcat/requests
- git clone https://github.com/Z4nzu/hackingtool.git
-
- chmod -R 755 hackingtool
-
- cd hackingtool
-
- sudo pip3 install -r requirements.txt
-
- python install.py
-
- sudo hackingtool
+---
-After all steps are completed, run the following command ---> **root@kaliLinux:~** **hackingtool**
+## Menu
-#### Thanks to original Author of the tools used in hackingtool
+{{toc}}
-
-
Please Don't Use for illegal Activity
+---
-### To do
-- [ ] Fully release tool
-- [ ] Add Tools for CTF
-- [ ] Want to do automatic
+## Tools
-## Social Media :mailbox_with_no_mail:
-[](https://twitter.com/_Zinzu07)
+{{tools}}
+
+---
+
+## Contributing — Add a New Tool
+
+Want a tool included? **Raise an Issue or open a PR** using the templates below.
+
+### Issue (Tool Request)
+
+> Title format: `[Tool Request] ToolName — Category`
+> Example: `[Tool Request] Subfinder — Information Gathering`
+
+Use the **Tool Request** issue template and fill in all required fields:
+tool name, GitHub URL, category, supported OS, install command, and why it should be added.
+
+### Pull Request
+
+> Title format: `[New Tool] ToolName — Category`
+> Example: `[New Tool] Subfinder — Information Gathering`
+
+Use the **PR template** checklist. Key requirements:
+
+1. Add your tool class to the correct `tools/*.py` file
+2. Set `TITLE`, `DESCRIPTION`, `INSTALL_COMMANDS`, `RUN_COMMANDS`, `PROJECT_URL`
+3. Set `SUPPORTED_OS = ["linux"]` or `["linux", "macos"]` appropriately
+4. Add the instance to the `TOOLS` list in the collection class
+5. Test install and run locally before submitting
+
+Issues or PRs that don't follow the title format may be closed without review.
+
+---
+
+## Installation
+
+### One-liner (recommended)
+
+```bash
+curl -sSL https://raw.githubusercontent.com/Z4nzu/hackingtool/master/install.sh | sudo bash
+```
+
+This handles everything — installs prerequisites, clones the repo, sets up a venv, and creates the `hackingtool` command.
+
+### Manual install
+
+```bash
+git clone https://github.com/Z4nzu/hackingtool.git
+cd hackingtool
+sudo python3 install.py # detects local source, copies instead of re-cloning
+```
+
+Then run:
+```bash
+hackingtool
+```
+
+## Docker
+
+### Step 1 — Clone the repository
+
+```bash
+git clone https://github.com/Z4nzu/hackingtool.git
+cd hackingtool
+```
+
+### Step 2 — Build the image
+
+```bash
+docker build -t hackingtool .
+```
+
+> First build takes a few minutes (Kali base + apt packages). Subsequent builds are fast thanks to BuildKit layer caching.
+
+### Step 3 — Run
+
+**Option A — Direct (no Compose):**
+```bash
+docker run -it --rm hackingtool
+```
+
+**Option B — With Docker Compose (recommended):**
+```bash
+# Start in background
+docker compose up -d
+
+# Open an interactive shell
+docker exec -it hackingtool bash
+
+# Then launch the tool inside the container
+python3 hackingtool.py
+```
+
+**Option C — Dev mode (live source mount, changes reflected without rebuild):**
+```bash
+docker compose --profile dev up
+docker exec -it hackingtool-dev bash
+```
+
+### Stopping
+
+```bash
+docker compose down # stop and remove container
+docker compose down -v # also remove the tools data volume
+```
+
+## Requirements
+
+- Python 3.10+
+- Linux (Kali, Parrot, Ubuntu) or macOS
+- Go 1.21+ (for nuclei, ffuf, amass, httpx, katana, dalfox)
+- Ruby (for haiti)
+
+```bash
+pip install -r requirements.txt
+```
+
+---
+
+## Star History
+
+
+
+
+
+
+
+---
+
+## Social
+
+[](https://twitter.com/_Zinzu07)
[](https://github.com/Z4nzu/)
-##### If you favorite tool is not included, or you have any suggestions, please [CLICK HERE](https://forms.gle/b235JoCKyUq5iM3t8)
-
-
+> **Please don't use for illegal activity.**
+> Thanks to all original authors of the tools included in hackingtool.
-#### Don't forget to share this tool with your friends!
-#### Thank you!!!
+Your favourite tool is not listed? [Suggest it here](https://github.com/Z4nzu/hackingtool/issues/new?template=tool_request.md)
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..abc85ad
--- /dev/null
+++ b/config.py
@@ -0,0 +1,43 @@
+import json
+import logging
+from pathlib import Path
+from typing import Any
+
+from constants import USER_CONFIG_FILE, USER_TOOLS_DIR, DEFAULT_CONFIG
+
+logger = logging.getLogger(__name__)
+
+
+def load() -> dict[str, Any]:
+ """Load config from disk, merging with defaults for any missing keys."""
+ if USER_CONFIG_FILE.exists():
+ try:
+ on_disk = json.loads(USER_CONFIG_FILE.read_text())
+ return {**DEFAULT_CONFIG, **on_disk}
+ except (json.JSONDecodeError, OSError) as exc:
+ logger.warning("Config file unreadable (%s), using defaults.", exc)
+ return dict(DEFAULT_CONFIG)
+
+
+def save(cfg: dict[str, Any]) -> None:
+ """Write config to disk, creating parent directories if needed."""
+ USER_CONFIG_FILE.parent.mkdir(parents=True, exist_ok=True)
+ USER_CONFIG_FILE.write_text(json.dumps(cfg, indent=2, sort_keys=True))
+
+
+def get_tools_dir() -> Path:
+ """
+ Return the directory where external tools are stored.
+ Creates it if it does not exist.
+ Always an absolute path — never relies on process CWD.
+ """
+ cfg = load()
+ tools_dir = Path(cfg.get("tools_dir", str(USER_TOOLS_DIR))).expanduser().resolve()
+ tools_dir.mkdir(parents=True, exist_ok=True)
+ return tools_dir
+
+
+def get_sudo_cmd() -> str:
+ """Return 'doas' if available, else 'sudo'. Never hardcode 'sudo'."""
+ import shutil
+ return "doas" if shutil.which("doas") else "sudo"
\ No newline at end of file
diff --git a/constants.py b/constants.py
new file mode 100644
index 0000000..b52b400
--- /dev/null
+++ b/constants.py
@@ -0,0 +1,65 @@
+from pathlib import Path
+import platform
+import shutil as _shutil
+
+# ── Repository ────────────────────────────────────────────────────────────────
+REPO_OWNER = "Z4nzu"
+REPO_NAME = "hackingtool"
+REPO_URL = f"https://github.com/{REPO_OWNER}/{REPO_NAME}.git"
+REPO_WEB_URL = f"https://github.com/{REPO_OWNER}/{REPO_NAME}"
+
+# ── Versioning ────────────────────────────────────────────────────────────────
+VERSION = "2.0.0"
+VERSION_DISPLAY = f"v{VERSION}"
+
+# ── Python requirement ────────────────────────────────────────────────────────
+MIN_PYTHON = (3, 10)
+
+# ── User-scoped paths (cross-platform, always computed at runtime) ─────────────
+# NEVER hardcode /home/username — use Path.home() so it works for any user,
+# including root (/root), regular users (/home/alice), macOS (/Users/alice).
+USER_CONFIG_DIR = Path.home() / f".{REPO_NAME}"
+USER_TOOLS_DIR = USER_CONFIG_DIR / "tools"
+USER_CONFIG_FILE = USER_CONFIG_DIR / "config.json"
+USER_LOG_FILE = USER_CONFIG_DIR / f"{REPO_NAME}.log"
+
+# ── System install paths (set per OS) ─────────────────────────────────────────
+_system = platform.system()
+
+if _system == "Darwin":
+ # macOS — Homebrew convention
+ APP_INSTALL_DIR = Path("/usr/local/share") / REPO_NAME
+ APP_BIN_PATH = Path("/usr/local/bin") / REPO_NAME
+elif _system == "Linux":
+ APP_INSTALL_DIR = Path("/usr/share") / REPO_NAME
+ APP_BIN_PATH = Path("/usr/bin") / REPO_NAME
+else:
+ # Fallback (Windows, FreeBSD, etc.)
+ APP_INSTALL_DIR = USER_CONFIG_DIR / "app"
+ APP_BIN_PATH = USER_CONFIG_DIR / "bin" / REPO_NAME
+
+# ── UI theme ──────────────────────────────────────────────────────────────────
+THEME_PRIMARY = "bold magenta"
+THEME_BORDER = "bright_magenta"
+THEME_SUCCESS = "bold green"
+THEME_ERROR = "bold red"
+THEME_WARNING = "bold yellow"
+THEME_DIM = "dim white"
+THEME_ARCHIVED = "dim yellow"
+THEME_URL = "underline bright_blue"
+THEME_ACCENT = "bold cyan"
+
+# ── Default config values ──────────────────────────────────────────────────────
+DEFAULT_CONFIG: dict = {
+ "tools_dir": str(USER_TOOLS_DIR),
+ "version": VERSION,
+ "theme": "magenta",
+ "show_archived": False,
+ "sudo_binary": "sudo",
+ "go_bin_dir": str(Path.home() / "go" / "bin"),
+ "gem_bin_dir": str(Path.home() / ".gem" / "ruby"),
+}
+
+# ── Privilege escalation ───────────────────────────────────────────────────────
+# Prefer doas if present (OpenBSD/some Linux setups), else sudo
+PRIV_CMD = "doas" if _shutil.which("doas") else "sudo"
\ No newline at end of file
diff --git a/core.py b/core.py
index 9fb68ee..985d85a 100644
--- a/core.py
+++ b/core.py
@@ -1,20 +1,39 @@
-from rich.console import Console
-from rich.panel import Panel
-from rich.table import Table
-from rich import box
-from rich.traceback import install
-from rich.theme import Theme
-
import os
+import shutil
import sys
import webbrowser
+from collections.abc import Callable
from platform import system
-from traceback import print_exc
-from typing import Callable, List, Tuple
-# Enable rich tracebacks
+from rich import box
+from rich.console import Console
+from rich.panel import Panel
+from rich.prompt import Prompt
+from rich.table import Table
+from rich.text import Text
+from rich.theme import Theme
+from rich.traceback import install
+
+from constants import (
+ THEME_PRIMARY, THEME_BORDER, THEME_ACCENT,
+ THEME_SUCCESS, THEME_ERROR, THEME_WARNING,
+ THEME_DIM, THEME_ARCHIVED, THEME_URL,
+)
+
+# Enable rich tracebacks globally
install()
-_theme = Theme({"purple": "#7B61FF"})
+
+_theme = Theme({
+ "purple": "#7B61FF",
+ "success": THEME_SUCCESS,
+ "error": THEME_ERROR,
+ "warning": THEME_WARNING,
+ "archived": THEME_ARCHIVED,
+ "url": THEME_URL,
+ "dim": THEME_DIM,
+})
+
+# Single shared console — all tool files do: from core import console
console = Console(theme=_theme)
@@ -22,95 +41,182 @@ def clear_screen():
os.system("cls" if system() == "Windows" else "clear")
-def validate_input(ip, val_range):
- val_range = val_range or []
+def validate_input(ip, val_range: list) -> int | None:
+ """Return the integer if it is in val_range, else None."""
+ if not val_range:
+ return None
try:
ip = int(ip)
if ip in val_range:
return ip
- except Exception:
- return None
+ except (TypeError, ValueError):
+ pass
return None
-class HackingTool(object):
- TITLE: str = ""
- DESCRIPTION: str = ""
- INSTALL_COMMANDS: List[str] = []
- INSTALLATION_DIR: str = ""
- UNINSTALL_COMMANDS: List[str] = []
- RUN_COMMANDS: List[str] = []
- OPTIONS: List[Tuple[str, Callable]] = []
- PROJECT_URL: str = ""
+def _show_inline_help():
+ """Quick help available from any menu level."""
+ console.print(Panel(
+ Text.assemble(
+ (" Navigation\n", "bold white"),
+ (" ─────────────────────────────────\n", "dim"),
+ (" 1–N ", "bold cyan"), ("select item\n", "white"),
+ (" 97 ", "bold cyan"), ("install all (in category)\n", "white"),
+ ("\n Tool menu: Install, Run, Update, Open Folder\n", "dim"),
+ (" 99 ", "bold cyan"), ("go back\n", "white"),
+ (" 98 ", "bold cyan"), ("open project page / archived\n", "white"),
+ (" ? ", "bold cyan"), ("show this help\n", "white"),
+ (" q ", "bold cyan"), ("quit hackingtool\n", "white"),
+ ),
+ title="[bold magenta] ? Quick Help [/bold magenta]",
+ border_style="magenta",
+ box=box.ROUNDED,
+ padding=(0, 2),
+ ))
+ Prompt.ask("[dim]Press Enter to return[/dim]", default="")
+
+
+class HackingTool:
+ TITLE: str = ""
+ DESCRIPTION: str = ""
+ INSTALL_COMMANDS: list[str] = []
+ UNINSTALL_COMMANDS: list[str] = []
+ RUN_COMMANDS: list[str] = []
+ OPTIONS: list[tuple[str, Callable]] = []
+ PROJECT_URL: str = ""
+
+ # OS / capability metadata
+ SUPPORTED_OS: list[str] = ["linux", "macos"]
+ REQUIRES_ROOT: bool = False
+ REQUIRES_WIFI: bool = False
+ REQUIRES_GO: bool = False
+ REQUIRES_RUBY: bool = False
+ REQUIRES_JAVA: bool = False
+ REQUIRES_DOCKER: bool = False
+
+ # Tags for search/filter (e.g. ["osint", "web", "recon", "scanner"])
+ TAGS: list[str] = []
+
+ # Archived tool flags
+ ARCHIVED: bool = False
+ ARCHIVED_REASON: str = ""
def __init__(self, options=None, installable=True, runnable=True):
options = options or []
- if isinstance(options, list):
- self.OPTIONS = []
- if installable:
- self.OPTIONS.append(("Install", self.install))
- if runnable:
- self.OPTIONS.append(("Run", self.run))
- self.OPTIONS.extend(options)
- else:
- raise Exception("options must be a list of (option_name, option_fn) tuples")
+ if not isinstance(options, list):
+ raise TypeError("options must be a list of (option_name, option_fn) tuples")
+ self.OPTIONS = []
+ if installable:
+ self.OPTIONS.append(("Install", self.install))
+ if runnable:
+ self.OPTIONS.append(("Run", self.run))
+ self.OPTIONS.append(("Update", self.update))
+ self.OPTIONS.append(("Open Folder", self.open_folder))
+ self.OPTIONS.extend(options)
+
+ @property
+ def is_installed(self) -> bool:
+ """Check if the tool's binary is on PATH or its clone dir exists."""
+ if self.RUN_COMMANDS:
+ cmd = self.RUN_COMMANDS[0]
+ # Handle "cd foo && binary --help" pattern
+ if "&&" in cmd:
+ cmd = cmd.split("&&")[-1].strip()
+ if cmd.startswith("sudo "):
+ cmd = cmd[5:].strip()
+ binary = cmd.split()[0] if cmd else ""
+ if binary and binary not in (".", "echo", "cd"):
+ if shutil.which(binary):
+ return True
+ # Check if git clone target dir exists
+ if self.INSTALL_COMMANDS:
+ for ic in self.INSTALL_COMMANDS:
+ if "git clone" in ic:
+ parts = ic.split()
+ repo_url = [p for p in parts if p.startswith("http")]
+ if repo_url:
+ dirname = repo_url[0].rstrip("/").rsplit("/", 1)[-1].replace(".git", "")
+ if os.path.isdir(dirname):
+ return True
+ return False
def show_info(self):
desc = f"[cyan]{self.DESCRIPTION}[/cyan]"
if self.PROJECT_URL:
- desc += f"\n[green]🔗 {self.PROJECT_URL}[/green]"
- console.print(Panel(desc, title=f"[bold purple]{self.TITLE}[/bold purple]", border_style="purple", box=box.DOUBLE))
+ desc += f"\n[url]🔗 {self.PROJECT_URL}[/url]"
+ if self.ARCHIVED:
+ desc += f"\n[archived]⚠ ARCHIVED: {self.ARCHIVED_REASON}[/archived]"
+ console.print(Panel(
+ desc,
+ title=f"[{THEME_PRIMARY}]{self.TITLE}[/{THEME_PRIMARY}]",
+ border_style="purple",
+ box=box.DOUBLE,
+ ))
def show_options(self, parent=None):
- clear_screen()
- self.show_info()
+ """Iterative menu loop — no recursion, no stack growth."""
+ while True:
+ clear_screen()
+ self.show_info()
- table = Table(title="Options", box=box.SIMPLE_HEAVY)
- table.add_column("No.", style="bold cyan", justify="center")
- table.add_column("Action", style="bold yellow")
+ table = Table(title="Options", box=box.SIMPLE_HEAVY)
+ table.add_column("No.", style="bold cyan", justify="center")
+ table.add_column("Action", style="bold yellow")
- for index, option in enumerate(self.OPTIONS):
- table.add_row(str(index + 1), option[0])
+ for index, option in enumerate(self.OPTIONS):
+ table.add_row(str(index + 1), option[0])
- if self.PROJECT_URL:
- table.add_row("98", "Open Project Page")
- table.add_row("99", f"Back to {parent.TITLE if parent else 'Exit'}")
+ if self.PROJECT_URL:
+ table.add_row("98", "Open Project Page")
+ table.add_row("99", f"Back to {parent.TITLE if parent else 'Main Menu'}")
+ console.print(table)
+ console.print(
+ " [dim cyan]?[/dim cyan][dim]help "
+ "[/dim][dim cyan]q[/dim cyan][dim]uit "
+ "[/dim][dim cyan]99[/dim cyan][dim] back[/dim]"
+ )
- console.print(table)
+ raw = Prompt.ask("[bold cyan]╰─>[/bold cyan]", default="").strip().lower()
+ if not raw:
+ continue
+ if raw in ("?", "help"):
+ _show_inline_help()
+ continue
+ if raw in ("q", "quit", "exit"):
+ raise SystemExit(0)
- option_index = input("\n[?] Select an option: ").strip()
- try:
- option_index = int(option_index)
- if option_index - 1 in range(len(self.OPTIONS)):
- ret_code = self.OPTIONS[option_index - 1][1]()
- if ret_code != 99:
- input("\nPress [Enter] to continue...")
- elif option_index == 98:
+ try:
+ choice = int(raw)
+ except ValueError:
+ console.print("[error]⚠ Enter a number, ? for help, or q to quit.[/error]")
+ Prompt.ask("[dim]Press Enter to continue[/dim]", default="")
+ continue
+
+ if choice == 99:
+ return
+ elif choice == 98 and self.PROJECT_URL:
self.show_project_page()
- elif option_index == 99:
- if parent is None:
- sys.exit()
- return 99
- except (TypeError, ValueError):
- console.print("[red]⚠ Please enter a valid option.[/red]")
- input("\nPress [Enter] to continue...")
- except Exception:
- console.print_exception(show_locals=True)
- input("\nPress [Enter] to continue...")
- return self.show_options(parent=parent)
+ elif 1 <= choice <= len(self.OPTIONS):
+ try:
+ self.OPTIONS[choice - 1][1]()
+ except Exception:
+ console.print_exception(show_locals=True)
+ Prompt.ask("[dim]Press Enter to continue[/dim]", default="")
+ else:
+ console.print("[error]⚠ Invalid option.[/error]")
def before_install(self): pass
def install(self):
self.before_install()
if isinstance(self.INSTALL_COMMANDS, (list, tuple)):
- for INSTALL_COMMAND in self.INSTALL_COMMANDS:
- console.print(f"[yellow]→ {INSTALL_COMMAND}[/yellow]")
- os.system(INSTALL_COMMAND)
- self.after_install()
+ for cmd in self.INSTALL_COMMANDS:
+ console.print(f"[warning]→ {cmd}[/warning]")
+ os.system(cmd)
+ self.after_install()
def after_install(self):
- console.print("[green]✔ Successfully installed![/green]")
+ console.print("[success]✔ Successfully installed![/success]")
def before_uninstall(self) -> bool:
return True
@@ -118,75 +224,266 @@ class HackingTool(object):
def uninstall(self):
if self.before_uninstall():
if isinstance(self.UNINSTALL_COMMANDS, (list, tuple)):
- for UNINSTALL_COMMAND in self.UNINSTALL_COMMANDS:
- console.print(f"[red]→ {UNINSTALL_COMMAND}[/red]")
- os.system(UNINSTALL_COMMAND)
- self.after_uninstall()
+ for cmd in self.UNINSTALL_COMMANDS:
+ console.print(f"[error]→ {cmd}[/error]")
+ os.system(cmd)
+ self.after_uninstall()
def after_uninstall(self): pass
+ def update(self):
+ """Smart update — detects install method and runs the right update command."""
+ if not self.is_installed:
+ console.print("[warning]Tool is not installed yet. Install it first.[/warning]")
+ return
+
+ updated = False
+ for ic in (self.INSTALL_COMMANDS or []):
+ if "git clone" in ic:
+ # Extract repo dir name from clone command
+ parts = ic.split()
+ repo_urls = [p for p in parts if p.startswith("http")]
+ if repo_urls:
+ dirname = repo_urls[0].rstrip("/").rsplit("/", 1)[-1].replace(".git", "")
+ if os.path.isdir(dirname):
+ console.print(f"[cyan]→ git -C {dirname} pull[/cyan]")
+ os.system(f"git -C {dirname} pull")
+ updated = True
+ elif "pip install" in ic:
+ # Re-run pip install (--upgrade)
+ upgrade_cmd = ic.replace("pip install", "pip install --upgrade")
+ console.print(f"[cyan]→ {upgrade_cmd}[/cyan]")
+ os.system(upgrade_cmd)
+ updated = True
+ elif "go install" in ic:
+ # Re-run go install (fetches latest)
+ console.print(f"[cyan]→ {ic}[/cyan]")
+ os.system(ic)
+ updated = True
+ elif "gem install" in ic:
+ upgrade_cmd = ic.replace("gem install", "gem update")
+ console.print(f"[cyan]→ {upgrade_cmd}[/cyan]")
+ os.system(upgrade_cmd)
+ updated = True
+
+ if updated:
+ console.print("[success]✔ Update complete![/success]")
+ else:
+ console.print("[dim]No automatic update method available for this tool.[/dim]")
+
+ def _get_tool_dir(self) -> str | None:
+ """Find the tool's local directory — clone target, pip location, or binary path."""
+ # 1. Check git clone target dir
+ for ic in (self.INSTALL_COMMANDS or []):
+ if "git clone" in ic:
+ parts = ic.split()
+ # If last arg is not a URL, it's a custom dir name
+ repo_urls = [p for p in parts if p.startswith("http")]
+ if repo_urls:
+ dirname = repo_urls[0].rstrip("/").rsplit("/", 1)[-1].replace(".git", "")
+ # Check custom target dir (arg after URL)
+ url_idx = parts.index(repo_urls[0])
+ if url_idx + 1 < len(parts):
+ dirname = parts[url_idx + 1]
+ if os.path.isdir(dirname):
+ return os.path.abspath(dirname)
+
+ # 2. Check binary location via which
+ if self.RUN_COMMANDS:
+ cmd = self.RUN_COMMANDS[0]
+ if "&&" in cmd:
+ # "cd foo && bar" → check "foo"
+ cd_part = cmd.split("&&")[0].strip()
+ if cd_part.startswith("cd "):
+ d = cd_part[3:].strip()
+ if os.path.isdir(d):
+ return os.path.abspath(d)
+ binary = cmd.split()[0] if cmd else ""
+ if binary.startswith("sudo"):
+ binary = cmd.split()[1] if len(cmd.split()) > 1 else ""
+ path = shutil.which(binary) if binary else None
+ if path:
+ return os.path.dirname(os.path.realpath(path))
+
+ return None
+
+ def open_folder(self):
+ """Open the tool's directory in a new shell so the user can work manually."""
+ tool_dir = self._get_tool_dir()
+ if tool_dir:
+ console.print(f"[success]Opening folder: {tool_dir}[/success]")
+ console.print("[dim]Type 'exit' to return to hackingtool.[/dim]")
+ os.system(f'cd "{tool_dir}" && $SHELL')
+ else:
+ console.print("[warning]Tool directory not found.[/warning]")
+ if self.PROJECT_URL:
+ console.print(f"[dim]You can clone it manually:[/dim]")
+ console.print(f"[cyan] git clone {self.PROJECT_URL}.git[/cyan]")
+
def before_run(self): pass
def run(self):
self.before_run()
if isinstance(self.RUN_COMMANDS, (list, tuple)):
- for RUN_COMMAND in self.RUN_COMMANDS:
- console.print(f"[cyan]⚙ Running:[/cyan] [bold]{RUN_COMMAND}[/bold]")
- os.system(RUN_COMMAND)
- self.after_run()
+ for cmd in self.RUN_COMMANDS:
+ console.print(f"[cyan]⚙ Running:[/cyan] [bold]{cmd}[/bold]")
+ os.system(cmd)
+ self.after_run()
def after_run(self): pass
- def is_installed(self, dir_to_check=None):
- console.print("[yellow]⚠ Unimplemented: DO NOT USE[/yellow]")
- return "?"
-
def show_project_page(self):
- console.print(f"[blue]🌐 Opening project page: {self.PROJECT_URL}[/blue]")
+ console.print(f"[url]🌐 Opening: {self.PROJECT_URL}[/url]")
webbrowser.open_new_tab(self.PROJECT_URL)
-class HackingToolsCollection(object):
- TITLE: str = ""
+class HackingToolsCollection:
+ TITLE: str = ""
DESCRIPTION: str = ""
- TOOLS: List = []
+ TOOLS: list = []
def __init__(self):
pass
def show_info(self):
- console.rule(f"[bold purple]{self.TITLE}[/bold purple]", style="purple")
- console.print(f"[italic cyan]{self.DESCRIPTION}[/italic cyan]\n")
+ console.rule(f"[{THEME_PRIMARY}]{self.TITLE}[/{THEME_PRIMARY}]", style="purple")
+ if self.DESCRIPTION:
+ console.print(f"[italic cyan]{self.DESCRIPTION}[/italic cyan]\n")
+
+ def _active_tools(self) -> list:
+ """Return tools that are not archived and are OS-compatible."""
+ from os_detect import CURRENT_OS
+ return [
+ t for t in self.TOOLS
+ if not getattr(t, "ARCHIVED", False)
+ and CURRENT_OS.system in getattr(t, "SUPPORTED_OS", ["linux", "macos"])
+ ]
+
+ def _archived_tools(self) -> list:
+ return [t for t in self.TOOLS if getattr(t, "ARCHIVED", False)]
+
+ def _incompatible_tools(self) -> list:
+ from os_detect import CURRENT_OS
+ return [
+ t for t in self.TOOLS
+ if not getattr(t, "ARCHIVED", False)
+ and CURRENT_OS.system not in getattr(t, "SUPPORTED_OS", ["linux", "macos"])
+ ]
+
+ def _show_archived_tools(self):
+ """Show archived tools sub-menu (option 98)."""
+ archived = self._archived_tools()
+ if not archived:
+ console.print("[dim]No archived tools in this category.[/dim]")
+ Prompt.ask("[dim]Press Enter to return[/dim]", default="")
+ return
+
+ while True:
+ clear_screen()
+ console.rule(f"[archived]Archived Tools — {self.TITLE}[/archived]", style="yellow")
+
+ table = Table(box=box.MINIMAL_DOUBLE_HEAD, show_lines=True)
+ table.add_column("No.", justify="center", style="bold yellow")
+ table.add_column("Tool", style="dim yellow")
+ table.add_column("Reason", style="dim white")
+
+ for i, tool in enumerate(archived):
+ reason = getattr(tool, "ARCHIVED_REASON", "No reason given")
+ table.add_row(str(i + 1), tool.TITLE, reason)
+
+ table.add_row("99", "Back", "")
+ console.print(table)
+
+ raw = Prompt.ask("[bold yellow][?] Select[/bold yellow]", default="99")
+ try:
+ choice = int(raw)
+ except ValueError:
+ continue
+
+ if choice == 99:
+ return
+ elif 1 <= choice <= len(archived):
+ archived[choice - 1].show_options(parent=self)
def show_options(self, parent=None):
- clear_screen()
- self.show_info()
+ """Iterative menu loop — no recursion, no stack growth."""
+ while True:
+ clear_screen()
+ self.show_info()
- table = Table(title="Available Tools", box=box.MINIMAL_DOUBLE_HEAD)
- table.add_column("No.", justify="center", style="bold cyan")
- table.add_column("Tool Name", style="bold yellow")
+ active = self._active_tools()
+ incompatible = self._incompatible_tools()
+ archived = self._archived_tools()
- for index, tool in enumerate(self.TOOLS):
- table.add_row(str(index), tool.TITLE)
+ table = Table(title="Available Tools", box=box.SIMPLE_HEAD, show_lines=True)
+ table.add_column("No.", justify="center", style="bold cyan", width=6)
+ table.add_column("", width=2) # installed indicator
+ table.add_column("Tool", style="bold yellow", min_width=24)
+ table.add_column("Description", style="white", overflow="fold")
- table.add_row("99", f"Back to {parent.TITLE if parent else 'Exit'}")
- console.print(table)
+ for index, tool in enumerate(active, start=1):
+ desc = getattr(tool, "DESCRIPTION", "") or "—"
+ desc = desc.splitlines()[0] if desc != "—" else "—"
+ has_status = hasattr(tool, "is_installed")
+ status = ("[green]✔[/green]" if tool.is_installed else "[dim]✘[/dim]") if has_status else ""
+ table.add_row(str(index), status, tool.TITLE, desc)
- tool_index = input("\n[?] Choose a tool: ").strip()
- try:
- tool_index = int(tool_index)
- if tool_index in range(len(self.TOOLS)):
- ret_code = self.TOOLS[tool_index].show_options(parent=self)
- if ret_code != 99:
- input("\nPress [Enter] to continue...")
- elif tool_index == 99:
- if parent is None:
- sys.exit()
- return 99
- except (TypeError, ValueError):
- console.print("[red]⚠ Please enter a valid option.[/red]")
- input("\nPress [Enter] to continue...")
- except Exception:
- console.print_exception(show_locals=True)
- input("\nPress [Enter] to continue...")
- return self.show_options(parent=parent)
+ # Count not-installed tools for "Install All" label (skip sub-collections)
+ not_installed = [t for t in active if hasattr(t, "is_installed") and not t.is_installed]
+ if not_installed:
+ table.add_row(
+ "[bold green]97[/bold green]", "",
+ f"[bold green]Install all ({len(not_installed)} not installed)[/bold green]", "",
+ )
+ if archived:
+ table.add_row("[dim]98[/dim]", "", f"[archived]Archived tools ({len(archived)})[/archived]", "")
+ if incompatible:
+ console.print(f"[dim]({len(incompatible)} tools hidden — not supported on current OS)[/dim]")
+
+ table.add_row("99", "", f"Back to {parent.TITLE if parent else 'Main Menu'}", "")
+ console.print(table)
+ console.print(
+ " [dim cyan]?[/dim cyan][dim]help "
+ "[/dim][dim cyan]q[/dim cyan][dim]uit "
+ "[/dim][dim cyan]99[/dim cyan][dim] back[/dim]"
+ )
+
+ raw = Prompt.ask("[bold cyan]╰─>[/bold cyan]", default="").strip().lower()
+ if not raw:
+ continue
+ if raw in ("?", "help"):
+ _show_inline_help()
+ continue
+ if raw in ("q", "quit", "exit"):
+ raise SystemExit(0)
+
+ try:
+ choice = int(raw)
+ except ValueError:
+ console.print("[error]⚠ Enter a number, ? for help, or q to quit.[/error]")
+ continue
+
+ if choice == 99:
+ return
+ elif choice == 97 and not_installed:
+ console.print(Panel(
+ f"[bold]Installing {len(not_installed)} tools...[/bold]",
+ border_style="green", box=box.ROUNDED,
+ ))
+ for i, tool in enumerate(not_installed, start=1):
+ console.print(f"\n[bold cyan]({i}/{len(not_installed)})[/bold cyan] {tool.TITLE}")
+ try:
+ tool.install()
+ except Exception:
+ console.print(f"[error]✘ Failed: {tool.TITLE}[/error]")
+ Prompt.ask("\n[dim]Press Enter to continue[/dim]", default="")
+ elif choice == 98 and archived:
+ self._show_archived_tools()
+ elif 1 <= choice <= len(active):
+ try:
+ active[choice - 1].show_options(parent=self)
+ except Exception:
+ console.print_exception(show_locals=True)
+ Prompt.ask("[dim]Press Enter to continue[/dim]", default="")
+ else:
+ console.print("[error]⚠ Invalid option.[/error]")
diff --git a/docker-compose.yml b/docker-compose.yml
index 301548b..94802ab 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,11 +1,40 @@
-version: "3.9"
+# docker-compose.yml
+# Use: docker compose up -d then docker exec -it hackingtool bash
+#
+# Profiles:
+# (default) — runs the built image; code is embedded at build time
+# dev — mounts source directory for live editing without rebuilding
+# docker compose --profile dev up
+
services:
hackingtool:
- image: vgpastor/hackingtool
+ build:
+ context: .
+ dockerfile: Dockerfile
+ image: hackingtool:latest
container_name: hackingtool
stdin_open: true
tty: true
+ # Persist tools installed at runtime across container restarts
volumes:
+ - hackingtool_data:/root/.hackingtool
+ restart: unless-stopped
+
+ hackingtool-dev:
+ build:
+ context: .
+ dockerfile: Dockerfile
+ image: hackingtool:latest
+ container_name: hackingtool-dev
+ stdin_open: true
+ tty: true
+ profiles:
+ - dev
+ volumes:
+ # Live source mount — code changes are visible without rebuilding
- .:/root/hackingtool
- ports:
- - 22:22
\ No newline at end of file
+ - hackingtool_data:/root/.hackingtool
+ restart: "no"
+
+volumes:
+ hackingtool_data:
diff --git a/hackingtool.py b/hackingtool.py
index 9db5a93..d2278f3 100755
--- a/hackingtool.py
+++ b/hackingtool.py
@@ -1,75 +1,85 @@
#!/usr/bin/env python3
-# Version 1.1.0 (rich UI - purple theme)
-import os
import sys
+
+# ── Python version guard (must be before any other local import) ───────────────
+if sys.version_info < (3, 10):
+ print(
+ f"[ERROR] Python 3.10 or newer is required.\n"
+ f"You are running Python {sys.version_info.major}.{sys.version_info.minor}.\n"
+ f"Upgrade with: sudo apt install python3.10"
+ )
+ sys.exit(1)
+
+import os
+import platform
+import socket
+import datetime
+import random
import webbrowser
-from platform import system
-from time import sleep
+from itertools import zip_longest
from rich.console import Console
from rich.panel import Panel
from rich.table import Table
-from rich.prompt import Prompt, IntPrompt, Confirm
+from rich.prompt import Prompt, Confirm
from rich.align import Align
from rich.text import Text
from rich import box
-from rich.columns import Columns
from rich.rule import Rule
-from rich.padding import Padding
+from rich.columns import Columns
-from core import HackingToolsCollection
+from core import HackingToolsCollection, clear_screen, console
+from constants import VERSION_DISPLAY, REPO_WEB_URL
+from config import get_tools_dir
from tools.anonsurf import AnonSurfTools
from tools.ddos import DDOSTools
from tools.exploit_frameworks import ExploitFrameworkTools
-from tools.forensic_tools import ForensicTools
-from tools.information_gathering_tools import InformationGatheringTools
+from tools.forensics import ForensicTools
+from tools.information_gathering import InformationGatheringTools
from tools.other_tools import OtherTools
from tools.payload_creator import PayloadCreatorTools
-from tools.phising_attack import PhishingAttackTools
+from tools.phishing_attack import PhishingAttackTools
from tools.post_exploitation import PostExploitationTools
from tools.remote_administration import RemoteAdministrationTools
from tools.reverse_engineering import ReverseEngineeringTools
-from tools.sql_tools import SqlInjectionTools
+from tools.sql_injection import SqlInjectionTools
from tools.steganography import SteganographyTools
from tools.tool_manager import ToolManager
-from tools.webattack import WebAttackTools
-from tools.wireless_attack_tools import WirelessAttackTools
+from tools.web_attack import WebAttackTools
+from tools.wireless_attack import WirelessAttackTools
from tools.wordlist_generator import WordlistGeneratorTools
from tools.xss_attack import XSSAttackTools
+from tools.active_directory import ActiveDirectoryTools
+from tools.cloud_security import CloudSecurityTools
+from tools.mobile_security import MobileSecurityTools
-console = Console()
-
-ASCII_LOGO = r"""
- ▄█ █▄ ▄████████ ▄████████ ▄█ ▄█▄ ▄█ ███▄▄▄▄ ▄██████▄ ███ ▄██████▄ ▄██████▄ ▄█
- ███ ███ ███ ███ ███ ███ ███ ▄███▀ ███ ███▀▀▀██▄ ███ ███ ▀█████████▄ ███ ███ ███ ███ ███
- ███ ███ ███ ███ ███ █▀ ███▐██▀ ███▌ ███ ███ ███ █▀ ▀███▀▀██ ███ ███ ███ ███ ███
- ▄███▄▄▄▄███▄▄ ███ ███ ███ ▄█████▀ ███▌ ███ ███ ▄███ ███ ▀ ███ ███ ███ ███ ███
-▀▀███▀▀▀▀███▀ ▀███████████ ███ ▀▀█████▄ ███▌ ███ ███ ▀▀███ ████▄ ███ ███ ███ ███ ███ ███
- ███ ███ ███ ███ ███ █▄ ███▐██▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
- ███ ███ ███ ███ ███ ███ ███ ▀███▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███▌ ▄
- ███ █▀ ███ █▀ ████████▀ ███ ▀█▀ █▀ ▀█ █▀ ████████▀ ▄████▀ ▀██████▀ ▀██████▀ █████▄▄██
- ▀ ▀
-"""
+# ── Tool registry ──────────────────────────────────────────────────────────────
+# (full_title, icon, menu_label)
+# menu_label is the concise name shown in the 2-column main menu grid.
+# full_title is shown when entering the category.
tool_definitions = [
- ("Anonymously Hiding Tools", "🛡️"),
- ("Information gathering tools", "🔍"),
- ("Wordlist Generator", "📚"),
- ("Wireless attack tools", "📶"),
- ("SQL Injection Tools", "🧩"),
- ("Phishing attack tools", "🎣"),
- ("Web Attack tools", "🌐"),
- ("Post exploitation tools", "🔧"),
- ("Forensic tools", "🕵️"),
- ("Payload creation tools", "📦"),
- ("Exploit framework", "🧰"),
- ("Reverse engineering tools", "🔁"),
- ("DDOS Attack Tools", "⚡"),
- ("Remote Administrator Tools (RAT)", "🖥️"),
- ("XSS Attack Tools", "💥"),
- ("Steganograhy tools", "🖼️"),
- ("Other tools", "✨"),
- ("Update or Uninstall | Hackingtool", "♻️"),
+ ("Anonymously Hiding Tools", "🛡 ", "Anonymously Hiding"),
+ ("Information gathering tools", "🔍", "Information Gathering"),
+ ("Wordlist Generator", "📚", "Wordlist Generator"),
+ ("Wireless attack tools", "📶", "Wireless Attack"),
+ ("SQL Injection Tools", "🧩", "SQL Injection"),
+ ("Phishing attack tools", "🎣", "Phishing Attack"),
+ ("Web Attack tools", "🌐", "Web Attack"),
+ ("Post exploitation tools", "🔧", "Post Exploitation"),
+ ("Forensic tools", "🕵 ", "Forensics"),
+ ("Payload creation tools", "📦", "Payload Creation"),
+ ("Exploit framework", "🧰", "Exploit Framework"),
+ ("Reverse engineering tools", "🔁", "Reverse Engineering"),
+ ("DDOS Attack Tools", "⚡", "DDOS Attack"),
+ ("Remote Administrator Tools (RAT)", "🖥 ", "Remote Admin (RAT)"),
+ ("XSS Attack Tools", "💥", "XSS Attack"),
+ ("Steganography tools", "🖼 ", "Steganography"),
+ ("Active Directory Tools", "🏢", "Active Directory"),
+ ("Cloud Security Tools", "☁ ", "Cloud Security"),
+ ("Mobile Security Tools", "📱", "Mobile Security"),
+ ("Other tools", "✨", "Other Tools"),
+ ("Update or Uninstall | Hackingtool", "♻ ", "Update / Uninstall"),
]
all_tools = [
@@ -89,138 +99,588 @@ all_tools = [
RemoteAdministrationTools(),
XSSAttackTools(),
SteganographyTools(),
+ ActiveDirectoryTools(),
+ CloudSecurityTools(),
+ MobileSecurityTools(),
OtherTools(),
- ToolManager()
+ ToolManager(),
]
-
+# Used by generate_readme.py
class AllTools(HackingToolsCollection):
TITLE = "All tools"
TOOLS = all_tools
- def show_info(self):
- header = Text()
- header.append(ASCII_LOGO, style="bold magenta")
- header.append("\n\n",)
- footer = Text.assemble(
- (" https://github.com/Z4nzu/hackingtool ", "bold bright_black"),
- (" | ",),
- ("Version 1.1.0", "bold green"),
- )
- warning = Text(" Please Don't Use For illegal Activity ", style="bold red")
- panel = Panel(
- Align.center(header + Text("\n") + footer + Text("\n") + warning),
- box=box.DOUBLE,
- padding=(1, 2),
- border_style="magenta"
- )
- console.print(panel)
+# ── Help overlay ───────────────────────────────────────────────────────────────
+
+def show_help():
+ console.print(Panel(
+ Text.assemble(
+ (" Main menu\n", "bold white"),
+ (" ─────────────────────────────────────\n", "dim"),
+ (" 1–20 ", "bold cyan"), ("open a category\n", "white"),
+ (" 21 ", "bold cyan"), ("Update / Uninstall hackingtool\n", "white"),
+ (" / or s ", "bold cyan"), ("search tools by name or keyword\n", "white"),
+ (" t ", "bold cyan"), ("filter tools by tag (osint, web, c2, ...)\n", "white"),
+ (" r ", "bold cyan"), ("recommend tools for a task\n", "white"),
+ (" ? ", "bold cyan"), ("show this help\n", "white"),
+ (" q ", "bold cyan"), ("quit hackingtool\n\n", "white"),
+ (" Inside a category\n", "bold white"),
+ (" ─────────────────────────────────────\n", "dim"),
+ (" 1–N ", "bold cyan"), ("select a tool\n", "white"),
+ (" 99 ", "bold cyan"), ("back to main menu\n", "white"),
+ (" 98 ", "bold cyan"), ("open project page (if available)\n\n", "white"),
+ (" Inside a tool\n", "bold white"),
+ (" ─────────────────────────────────────\n", "dim"),
+ (" 1 ", "bold cyan"), ("install tool\n", "white"),
+ (" 2 ", "bold cyan"), ("run tool\n", "white"),
+ (" 99 ", "bold cyan"), ("back to category\n", "white"),
+ ),
+ title="[bold magenta] ? Quick Help [/bold magenta]",
+ border_style="magenta",
+ box=box.ROUNDED,
+ padding=(0, 2),
+ ))
+ Prompt.ask("[dim]Press Enter to return[/dim]", default="")
+
+
+# ── Header: ASCII art + live system info ──────────────────────────────────────
+
+# Full "HACKING TOOL" block-letter art — 12 lines, split layout with stats
+_BANNER_ART = [
+ " ██╗ ██╗ █████╗ ██████╗██╗ ██╗██╗███╗ ██╗ ██████╗ ",
+ " ██║ ██║██╔══██╗██╔════╝██║ ██╔╝██║████╗ ██║██╔════╝ ",
+ " ███████║███████║██║ █████╔╝ ██║██╔██╗ ██║██║ ███╗",
+ " ██╔══██║██╔══██║██║ ██╔═██╗ ██║██║╚██╗██║██║ ██║",
+ " ██║ ██║██║ ██║╚██████╗██║ ██╗██║██║ ╚████║╚██████╔╝",
+ " ╚═╝ ╚═╝╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ",
+ " ████████╗ ██████╗ ██████╗ ██╗",
+ " ╚══██╔══╝██╔═══██╗██╔═══██╗██║",
+ " ██║ ██║ ██║██║ ██║██║",
+ " ██║ ██║ ██║██║ ██║██║",
+ " ██║ ╚██████╔╝╚██████╔╝███████╗",
+ " ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝",
+]
+
+_QUOTES = [
+ '"The quieter you become, the more you can hear."',
+ '"Offense informs defense."',
+ '"There is no patch for human stupidity."',
+ '"In God we trust. All others we monitor."',
+ '"Hackers are the immune system of the internet."',
+ '"Every system is hackable — know yours before others do."',
+ '"Enumerate before you exploit."',
+ '"A scope defines your playground."',
+ '"The more you sweat in training, the less you bleed in battle."',
+ '"Security is a process, not a product."',
+]
+
+
+def _sys_info() -> dict:
+ """Collect live system info for the header panel."""
+ info: dict = {}
+
+ # OS pretty name
+ try:
+ info["os"] = platform.freedesktop_os_release().get("PRETTY_NAME", "")
+ except Exception:
+ info["os"] = ""
+ if not info["os"]:
+ info["os"] = f"{platform.system()} {platform.release()}"
+
+ info["kernel"] = platform.release()
+
+ # Current user
+ try:
+ info["user"] = os.getlogin()
+ except Exception:
+ info["user"] = os.environ.get("USER", os.environ.get("LOGNAME", "root"))
+
+ info["host"] = socket.gethostname()
+
+ # Local IP — connect to a routable address without sending data
+ try:
+ s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
+ s.settimeout(0)
+ s.connect(("10.254.254.254", 1))
+ info["ip"] = s.getsockname()[0]
+ s.close()
+ except Exception:
+ info["ip"] = "127.0.0.1"
+
+ info["time"] = datetime.datetime.now().strftime("%Y-%m-%d %H:%M")
+ return info
+
+
+def _build_header() -> Panel:
+ info = _sys_info()
+
+ # 12 stat lines paired with the 12 art lines
+ stat_lines = [
+ (" os › ", info["os"][:34]),
+ (" kernel › ", info["kernel"][:34]),
+ (" user › ", f"{info['user']} @ {info['host'][:20]}"),
+ (" ip › ", info["ip"]),
+ (" tools › ", f"{len(all_tools)} categories · 185+ modules"),
+ (" session › ", info["time"]),
+ ("", ""),
+ (" python › ", f"{sys.version_info.major}.{sys.version_info.minor}.{sys.version_info.micro}"),
+ (" arch › ", platform.machine()),
+ (" status › ", "✔ READY"),
+ ("", ""),
+ ("", ""),
+ ]
+
+ grid = Table.grid(padding=0)
+ grid.add_column("art", no_wrap=True)
+ grid.add_column("sep", no_wrap=True)
+ grid.add_column("lbl", no_wrap=True)
+ grid.add_column("val", no_wrap=True)
+
+ for art_line, (lbl_text, val_text) in zip(_BANNER_ART, stat_lines):
+ grid.add_row(
+ Text(art_line, style="bold bright_green"),
+ Text(" │ ", style="dim green"),
+ Text(lbl_text, style="dim green"),
+ Text(val_text, style="bright_green"),
+ )
+
+ # Quote + warning below the split row
+ quote = random.choice(_QUOTES)
+ body = Table.grid(padding=(0, 0))
+ body.add_column()
+ body.add_row(grid)
+ body.add_row(Text(""))
+ body.add_row(Text(f" {quote}", style="italic dim"))
+ body.add_row(Text(" ⚠ For authorized security testing only",
+ style="bold dim red"))
+
+ return Panel(
+ body,
+ title=f"[bold bright_magenta][ HackingTool {VERSION_DISPLAY} ][/bold bright_magenta]",
+ title_align="left",
+ subtitle=f"[dim][ {info['time']} ][/dim]",
+ subtitle_align="right",
+ border_style="bright_magenta",
+ box=box.HEAVY,
+ padding=(0, 1),
+ )
+
+
+# ── Main menu renderer ─────────────────────────────────────────────────────────
def build_menu():
- table = Table.grid(expand=True)
- table.add_column("idx", width=6, justify="right")
- table.add_column("name", justify="left")
+ clear_screen()
+ console.print(_build_header())
- for idx, (title, icon) in enumerate(tool_definitions):
- if idx == 17:
- label = "[bold magenta]99[/bold magenta]"
- name = f"[bold magenta]{icon} {title}[/bold magenta]"
+ # ── 2-column category grid ──
+ # Items 1-17 in two columns, item 18 (ToolManager) shown separately
+ categories = tool_definitions[:-1] # 17 items
+ update_def = tool_definitions[-1] # ToolManager
+
+ mid = (len(categories) + 1) // 2 # 9 (left), 8 (right)
+ left = list(enumerate(categories[:mid], start=1))
+ right = list(enumerate(categories[mid:], start=mid + 1))
+
+ grid = Table.grid(padding=(0, 1), expand=True)
+ grid.add_column("ln", justify="right", style="bold magenta", width=5)
+ grid.add_column("li", width=3)
+ grid.add_column("lt", style="magenta", ratio=1, no_wrap=True)
+ grid.add_column("gap", width=3)
+ grid.add_column("rn", justify="right", style="bold magenta", width=5)
+ grid.add_column("ri", width=3)
+ grid.add_column("rt", style="magenta", ratio=1, no_wrap=True)
+
+ for (li, (_, lic, ll)), r in zip_longest(left, right, fillvalue=None):
+ if r:
+ ri, (_, ric, rl) = r
+ grid.add_row(str(li), lic, ll, "", str(ri), ric, rl)
else:
- label = f"[bold magenta]{idx}[/bold magenta]"
- name = f"[white]{icon}[/white] [magenta]{title}[/magenta]"
- table.add_row(label, name)
+ grid.add_row(str(li), lic, ll, "", "", "", "")
- top_panel = Panel(
- Align.center(Text("HackingTool — Main Menu", style="bold white on magenta"), vertical="middle"),
- style="magenta",
- padding=(0, 1),
- box=box.ROUNDED
- )
- menu_panel = Panel.fit(
- table,
- title="[bold magenta]Select a tool[/bold magenta]",
+ console.print(Panel(
+ grid,
+ title="[bold magenta] Select a Category [/bold magenta]",
border_style="bright_magenta",
- box=box.SQUARE
+ box=box.ROUNDED,
+ padding=(0, 1),
+ ))
+
+ # ── ToolManager row ──
+ tm_num = len(categories) + 1
+ console.print(
+ f" [bold magenta] {tm_num}[/bold magenta] {update_def[1]} "
+ f"[magenta]{update_def[2]}[/magenta]"
+ )
+
+ # ── Claude-style dual-line prompt area ──
+ console.print(Rule(style="dim magenta"))
+ console.print(
+ " [dim cyan]/[/dim cyan][dim]search[/dim] "
+ "[dim cyan]t[/dim cyan] [dim]tags[/dim] "
+ "[dim cyan]r[/dim cyan] [dim]recommend[/dim] "
+ "[dim cyan]?[/dim cyan] [dim]help[/dim] "
+ "[dim cyan]q[/dim cyan] [dim]quit[/dim]"
)
- footer = Align.center(Text("Choose number and press Enter — 99 to exit", style="italic bright_black"))
- console.print(top_panel)
- console.print(menu_panel)
- console.print(Rule(style="bright_black"))
- console.print(footer)
- console.print("")
-def choose_path():
- fpath = os.path.expanduser("~/hackingtoolpath.txt")
- if not os.path.exists(fpath):
- os.system("clear" if system() == "Linux" else "cls")
- build_menu()
- console.print(Panel("Setup path for tool installations", border_style="magenta"))
- choice = Prompt.ask("[magenta]Set Path[/magenta]", choices=["1", "2"], default="2")
- if choice == "1":
- inpath = Prompt.ask("[magenta]Enter Path (with Directory Name)[/magenta]")
- with open(fpath, "w") as f:
- f.write(inpath)
- console.print(f"[green]Successfully Set Path to:[/green] {inpath}")
- else:
- autopath = "/home/hackingtool/"
- with open(fpath, "w") as f:
- f.write(autopath)
- console.print(f"[green]Your Default Path Is:[/green] {autopath}")
- sleep(1)
- return fpath
+# ── Search ─────────────────────────────────────────────────────────────────────
+def _collect_all_tools() -> list[tuple]:
+ """Walk all collections and return (tool_instance, category_name) pairs."""
+ from core import HackingTool, HackingToolsCollection
+ results = []
+
+ def _walk(items, parent_title=""):
+ for item in items:
+ if isinstance(item, HackingToolsCollection):
+ _walk(item.TOOLS, item.TITLE)
+ elif isinstance(item, HackingTool):
+ results.append((item, parent_title))
+
+ _walk(all_tools)
+ return results
+
+
+def _get_all_tags() -> dict[str, list[tuple]]:
+ """Build tag → [(tool, category)] index from all tools."""
+ import re
+ _rules = {
+ r'(osint|harvester|maigret|holehe|spiderfoot|sherlock|recon)': 'osint',
+ r'(subdomain|subfinder|amass|sublist|subdomainfinder)': 'recon',
+ r'(scanner|scan|nmap|masscan|rustscan|nikto|nuclei|trivy)': 'scanner',
+ r'(brute|gobuster|ffuf|dirb|dirsearch|ferox|hashcat|john|kerbrute)': 'bruteforce',
+ r'(web|http|proxy|zap|xss|sql|wafw00f|arjun|caido|mitmproxy)': 'web',
+ r'(wireless|wifi|wlan|airgeddon|bettercap|wifite|fluxion|deauth)': 'wireless',
+ r'(phish|social.media|evilginx|setoolkit|social.fish|social.engineer)': 'social-engineering',
+ r'(c2|sliver|havoc|mythic|pwncat|reverse.shell|pyshell)': 'c2',
+ r'(privesc|peass|linpeas|winpeas)': 'privesc',
+ r'(tunnel|pivot|ligolo|chisel|proxy|anon)': 'network',
+ r'(password|credential|hash|crack|secret|trufflehog|gitleaks)': 'credentials',
+ r'(forensic|memory|volatility|binwalk|autopsy|wireshark|pspy)': 'forensics',
+ r'(reverse.eng|ghidra|radare|jadx|androguard|apk)': 'reversing',
+ r'(cloud|aws|azure|gcp|kubernetes|prowler|scout|pacu)': 'cloud',
+ r'(mobile|android|ios|frida|mobsf|objection|droid)': 'mobile',
+ r'(active.directory|bloodhound|netexec|impacket|responder|certipy|kerberos|winrm|smb|ldap)': 'active-directory',
+ r'(ddos|dos|slowloris|goldeneye|ufonet)': 'ddos',
+ r'(payload|msfvenom|fatrat|venom|stitch|enigma)': 'payload',
+ r'(crawler|spider|katana|gospider)': 'crawler',
+ }
+ tag_index: dict[str, list[tuple]] = {}
+ for tool, cat in _collect_all_tools():
+ combined = f"{tool.TITLE} {tool.DESCRIPTION}".lower()
+ # Manual tags first
+ tool_tags = set(getattr(tool, "TAGS", []) or [])
+ # Auto-derive tags from title/description
+ for pattern, tag in _rules.items():
+ if re.search(pattern, combined, re.IGNORECASE):
+ tool_tags.add(tag)
+ for t in tool_tags:
+ tag_index.setdefault(t, []).append((tool, cat))
+ return tag_index
+
+
+def filter_by_tag():
+ """Show available tags, user picks one, show matching tools."""
+ tag_index = _get_all_tags()
+ sorted_tags = sorted(tag_index.keys())
+
+ # Show tags in a compact grid
+ console.print(Panel(
+ " ".join(f"[bold cyan]{t}[/bold cyan]([dim]{len(tag_index[t])}[/dim])" for t in sorted_tags),
+ title="[bold magenta] Available Tags [/bold magenta]",
+ border_style="magenta", box=box.ROUNDED, padding=(0, 2),
+ ))
+
+ tag = Prompt.ask("[bold cyan]Enter tag[/bold cyan]", default="").strip().lower()
+ if not tag or tag not in tag_index:
+ if tag:
+ console.print(f"[dim]Tag '{tag}' not found.[/dim]")
+ Prompt.ask("[dim]Press Enter to return[/dim]", default="")
+ return
+
+ matches = tag_index[tag]
+ table = Table(
+ title=f"Tools tagged '{tag}'",
+ box=box.SIMPLE_HEAD, show_lines=True,
+ )
+ table.add_column("No.", justify="center", style="bold cyan", width=5)
+ table.add_column("", width=2)
+ table.add_column("Tool", style="bold yellow", min_width=20)
+ table.add_column("Category", style="magenta", min_width=15)
+
+ for i, (tool, cat) in enumerate(matches, start=1):
+ status = "[green]✔[/green]" if tool.is_installed else "[dim]✘[/dim]"
+ table.add_row(str(i), status, tool.TITLE, cat)
+
+ table.add_row("99", "", "Back to main menu", "")
+ console.print(table)
+
+ raw = Prompt.ask("[bold cyan]>[/bold cyan]", default="").strip()
+ if not raw or raw == "99":
+ return
+ try:
+ idx = int(raw)
+ except ValueError:
+ return
+ if 1 <= idx <= len(matches):
+ tool, cat = matches[idx - 1]
+ tool.show_options()
+
+
+_RECOMMENDATIONS = {
+ "scan a network": ["scanner", "port-scanner"],
+ "find subdomains": ["recon"],
+ "scan for vulnerabilities": ["scanner", "web"],
+ "crack passwords": ["bruteforce", "credentials"],
+ "find leaked secrets": ["credentials"],
+ "phishing campaign": ["social-engineering"],
+ "post exploitation": ["c2", "privesc"],
+ "pivot through network": ["network"],
+ "pentest active directory": ["active-directory"],
+ "pentest web application": ["web", "scanner"],
+ "pentest cloud": ["cloud"],
+ "pentest mobile app": ["mobile"],
+ "reverse engineer binary": ["reversing"],
+ "capture wifi handshake": ["wireless"],
+ "intercept http traffic": ["web", "network"],
+ "forensic analysis": ["forensics"],
+ "ddos testing": ["ddos"],
+ "create payloads": ["payload"],
+ "find xss vulnerabilities": ["web"],
+ "brute force directories": ["bruteforce", "web"],
+ "osint / recon a target": ["osint", "recon"],
+ "hide my identity": ["network"],
+}
+
+
+def recommend_tools():
+ """Show common tasks, user picks one, show matching tools."""
+ table = Table(
+ title="What do you want to do?",
+ box=box.SIMPLE_HEAD,
+ )
+ table.add_column("No.", justify="center", style="bold cyan", width=5)
+ table.add_column("Task", style="bold yellow")
+
+ tasks = list(_RECOMMENDATIONS.keys())
+ for i, task in enumerate(tasks, start=1):
+ table.add_row(str(i), task.title())
+
+ table.add_row("99", "Back to main menu")
+ console.print(table)
+
+ raw = Prompt.ask("[bold cyan]>[/bold cyan]", default="").strip()
+ if not raw or raw == "99":
+ return
+
+ try:
+ idx = int(raw)
+ except ValueError:
+ return
+
+ if 1 <= idx <= len(tasks):
+ task = tasks[idx - 1]
+ tag_names = _RECOMMENDATIONS[task]
+ tag_index = _get_all_tags()
+
+ # Collect unique tools across all matching tags
+ seen = set()
+ matches = []
+ for tag in tag_names:
+ for tool, cat in tag_index.get(tag, []):
+ if id(tool) not in seen:
+ seen.add(id(tool))
+ matches.append((tool, cat))
+
+ if not matches:
+ console.print("[dim]No tools found for this task.[/dim]")
+ Prompt.ask("[dim]Press Enter to return[/dim]", default="")
+ return
+
+ console.print(Panel(
+ f"[bold]Recommended tools for: {task.title()}[/bold]",
+ border_style="green", box=box.ROUNDED,
+ ))
+
+ rtable = Table(box=box.SIMPLE_HEAD, show_lines=True)
+ rtable.add_column("No.", justify="center", style="bold cyan", width=5)
+ rtable.add_column("", width=2)
+ rtable.add_column("Tool", style="bold yellow", min_width=20)
+ rtable.add_column("Category", style="magenta")
+
+ for i, (tool, cat) in enumerate(matches, start=1):
+ status = "[green]✔[/green]" if tool.is_installed else "[dim]✘[/dim]"
+ rtable.add_row(str(i), status, tool.TITLE, cat)
+
+ rtable.add_row("99", "", "Back", "")
+ console.print(rtable)
+
+ raw2 = Prompt.ask("[bold cyan]>[/bold cyan]", default="").strip()
+ if raw2 and raw2 != "99":
+ try:
+ ridx = int(raw2)
+ if 1 <= ridx <= len(matches):
+ matches[ridx - 1][0].show_options()
+ except ValueError:
+ pass
+
+
+def search_tools(query: str | None = None):
+ """Search tools — accepts inline query or prompts for one."""
+ if query is None:
+ query = Prompt.ask("[bold cyan]/ Search[/bold cyan]", default="").strip().lower()
+ else:
+ query = query.lower()
+ if not query:
+ return
+
+ all_tool_list = _collect_all_tools()
+
+ # Match against title + description + tags
+ matches = []
+ for tool, category in all_tool_list:
+ title = (tool.TITLE or "").lower()
+ desc = (tool.DESCRIPTION or "").lower()
+ tags = " ".join(getattr(tool, "TAGS", []) or []).lower()
+ if query in title or query in desc or query in tags:
+ matches.append((tool, category))
+
+ if not matches:
+ console.print(f"[dim]No tools found matching '{query}'[/dim]")
+ Prompt.ask("[dim]Press Enter to return[/dim]", default="")
+ return
+
+ # Display results
+ table = Table(
+ title=f"Search results for '{query}'",
+ box=box.SIMPLE_HEAD, show_lines=True,
+ )
+ table.add_column("No.", justify="center", style="bold cyan", width=5)
+ table.add_column("Tool", style="bold yellow", min_width=20)
+ table.add_column("Category", style="magenta", min_width=15)
+ table.add_column("Description", style="white", overflow="fold")
+
+ for i, (tool, cat) in enumerate(matches, start=1):
+ desc = (tool.DESCRIPTION or "—").splitlines()[0]
+ table.add_row(str(i), tool.TITLE, cat, desc)
+
+ table.add_row("99", "Back to main menu", "", "")
+ console.print(table)
+
+ raw = Prompt.ask("[bold cyan]>[/bold cyan]", default="").strip().lower()
+ if not raw or raw == "99":
+ return
+
+ try:
+ idx = int(raw)
+ except ValueError:
+ return
+
+ if 1 <= idx <= len(matches):
+ tool, cat = matches[idx - 1]
+ console.print(Panel(
+ f"[bold magenta]{tool.TITLE}[/bold magenta] [dim]({cat})[/dim]",
+ border_style="magenta", box=box.ROUNDED,
+ ))
+ tool.show_options()
+
+
+# ── Main interaction loop ──────────────────────────────────────────────────────
def interact_menu():
while True:
try:
build_menu()
- choice = IntPrompt.ask("[magenta]Choose a tool to proceed[/magenta]", default=0)
- if choice == 99:
- console.print(Panel("[bold white on magenta]Goodbye — Come Back Safely[/bold white on magenta]"))
+ raw = Prompt.ask(
+ "[bold magenta]╰─>[/bold magenta]", default=""
+ ).strip()
+
+ if not raw:
+ continue
+
+ raw_lower = raw.lower()
+
+ if raw_lower in ("?", "help"):
+ show_help()
+ continue
+
+ if raw.startswith("/"):
+ # Inline search: /subdomain → search immediately
+ query = raw[1:].strip()
+ search_tools(query=query if query else None)
+ continue
+
+ if raw_lower in ("s", "search"):
+ search_tools()
+ continue
+
+ if raw_lower in ("t", "tag", "tags", "filter"):
+ filter_by_tag()
+ continue
+
+ if raw_lower in ("r", "rec", "recommend"):
+ recommend_tools()
+ continue
+
+ if raw_lower in ("q", "quit", "exit"):
+ console.print(Panel(
+ "[bold white on magenta] Goodbye — Come Back Safely [/bold white on magenta]",
+ box=box.HEAVY, border_style="magenta",
+ ))
break
- if 0 <= choice < len(all_tools):
- tool = all_tools[choice]
- name = tool_definitions[choice][0]
- console.print(Panel(f"[bold magenta]{tool_definitions[choice][1]} Selected:[/bold magenta] [white]{name}"))
+
+ try:
+ choice = int(raw_lower)
+ except ValueError:
+ console.print("[red]⚠ Invalid input — enter a number, /query to search, or q to quit.[/red]")
+ Prompt.ask("[dim]Press Enter to continue[/dim]", default="")
+ continue
+
+ if 1 <= choice <= len(all_tools):
+ title, icon, _ = tool_definitions[choice - 1]
+ console.print(Panel(
+ f"[bold magenta]{icon} {title}[/bold magenta]",
+ border_style="magenta", box=box.ROUNDED,
+ ))
try:
- fn = getattr(tool, "show_options", None)
- if callable(fn):
- fn()
- else:
- console.print(f"[yellow]Tool '{name}' has no interactive menu (show_options).[/yellow]")
+ all_tools[choice - 1].show_options()
except Exception as e:
- console.print(Panel(f"[red]Error while opening {name}[/red]\n{e}", border_style="red"))
- if not Confirm.ask("[magenta]Return to main menu?[/magenta]", default=True):
- console.print(Panel("[bold white on magenta]Exiting...[/bold white on magenta]"))
- break
+ console.print(Panel(
+ f"[red]Error while opening {title}[/red]\n{e}",
+ border_style="red",
+ ))
+ Prompt.ask("[dim]Press Enter to return to main menu[/dim]", default="")
else:
- console.print("[red]Invalid selection. Pick a number from the menu.[/red]")
+ console.print(f"[red]⚠ Choose 1–{len(all_tools)}, ? for help, or q to quit.[/red]")
+ Prompt.ask("[dim]Press Enter to continue[/dim]", default="")
+
except KeyboardInterrupt:
- console.print("\n[bold red]Interrupted by user — exiting[/bold red]")
+ console.print("\n[bold red]Interrupted — exiting[/bold red]")
break
+
+# ── Entry point ────────────────────────────────────────────────────────────────
+
def main():
try:
- if system() == "Linux":
- fpath = choose_path()
- with open(fpath) as f:
- archive = f.readline().strip()
- os.makedirs(archive, exist_ok=True)
- os.chdir(archive)
- AllTools().show_info()
- interact_menu()
- elif system() == "Windows":
- console.print(Panel("[bold red]Please run this tool on a Debian/Linux system for best results[/bold red]"))
+ from os_detect import CURRENT_OS
+
+ if CURRENT_OS.system == "windows":
+ console.print(Panel("[bold red]Please run this tool on Linux or macOS.[/bold red]"))
if Confirm.ask("Open guidance link in your browser?", default=True):
- webbrowser.open_new_tab("https://tinyurl.com/y522modc")
- sleep(2)
- else:
- console.print("[yellow]Please Check Your System or Open New Issue ...[/yellow]")
+ webbrowser.open_new_tab(f"{REPO_WEB_URL}#windows")
+ return
+
+ if CURRENT_OS.system not in ("linux", "macos"):
+ console.print(f"[yellow]Unsupported OS: {CURRENT_OS.system}. Proceeding anyway...[/yellow]")
+
+ get_tools_dir() # ensures ~/.hackingtool/tools/ exists
+ interact_menu()
+
except KeyboardInterrupt:
- console.print("\n[bold red]Exiting ..!!![/bold red]")
- sleep(1)
+ console.print("\n[bold red]Exiting...[/bold red]")
if __name__ == "__main__":
diff --git a/images/logo.svg b/images/logo.svg
new file mode 100644
index 0000000..4f3708f
--- /dev/null
+++ b/images/logo.svg
@@ -0,0 +1,106 @@
+
diff --git a/install.py b/install.py
index d7c328f..241ff2f 100755
--- a/install.py
+++ b/install.py
@@ -1,207 +1,272 @@
#!/usr/bin/env python3
-# install_hackingtool.py (rich-based installer UI)
import os
import sys
import shutil
import subprocess
from pathlib import Path
+# ── Python version check (must be before any other local import) ──────────────
+if sys.version_info < (3, 10):
+ print(
+ f"[ERROR] Python 3.10 or newer is required.\n"
+ f"You are running Python {sys.version_info.major}.{sys.version_info.minor}.\n"
+ f"Install with: sudo apt install python3.10"
+ )
+ sys.exit(1)
+
from rich.console import Console
from rich.panel import Panel
-from rich.prompt import Prompt, Confirm, IntPrompt
-from rich.table import Table
-from rich.align import Align
+from rich.prompt import Confirm
from rich.progress import Progress, SpinnerColumn, TextColumn
from rich.text import Text
from rich import box
-from random import choice
+
+from constants import (
+ REPO_URL, APP_INSTALL_DIR, APP_BIN_PATH,
+ VERSION, VERSION_DISPLAY,
+ USER_CONFIG_DIR, USER_TOOLS_DIR, USER_CONFIG_FILE,
+ DEFAULT_CONFIG,
+)
+from os_detect import CURRENT_OS, REQUIRED_PACKAGES, PACKAGE_UPDATE_CMDS, PACKAGE_INSTALL_CMDS
console = Console()
-REPO_URL = "https://github.com/Z4nzu/hackingtool.git"
-INSTALL_DIR = Path("/usr/share/hackingtool")
-BIN_PATH = Path("/usr/bin/hackingtool")
VENV_DIR_NAME = "venv"
-REQUIREMENTS = "requirements.txt"
+REQUIREMENTS = "requirements.txt"
+# ── Privilege check ────────────────────────────────────────────────────────────
+
def check_root():
if os.geteuid() != 0:
- console.print(Panel("[red]This installer must be run as root. Use: sudo python3 install_hackingtool.py[/red]"))
+ console.print(Panel(
+ "[error]This installer must be run as root.\n"
+ "Use: [bold]sudo python3 install.py[/bold][/error]",
+ border_style="red",
+ ))
sys.exit(1)
-def run_cmd(cmd, check=True, capture=False, env=None):
- return subprocess.run(cmd, shell=True, check=check, capture_output=capture, text=True, env=env)
+# ── OS compatibility check ─────────────────────────────────────────────────────
+
+def check_os_compatibility():
+ """Print detected OS info and exit on unsupported systems."""
+ info = CURRENT_OS
+ console.print(
+ f"[dim]Detected: OS={info.system} | distro={info.distro_id or 'n/a'} | "
+ f"pkg_mgr={info.pkg_manager or 'none'} | arch={info.arch}[/dim]"
+ )
+
+ if info.system == "windows":
+ console.print(Panel(
+ "[error]Windows is not supported natively.[/error]\n"
+ "Use WSL2 with a Kali or Ubuntu image.",
+ border_style="red",
+ ))
+ sys.exit(1)
+
+ if info.is_wsl:
+ console.print("[warning]WSL detected. Wireless tools will NOT work in WSL.[/warning]")
+
+ if info.system == "macos":
+ console.print(Panel(
+ "[warning]macOS support is partial.[/warning]\n"
+ "Network/wireless tools require Linux. OSINT and web tools work.",
+ border_style="yellow",
+ ))
+ if not shutil.which("brew"):
+ console.print("[error]Homebrew not found. Install it first: https://brew.sh[/error]")
+ sys.exit(1)
+
+ if not info.pkg_manager:
+ console.print("[warning]No supported package manager found.[/warning]")
+ console.print("[dim]Supported: apt-get, pacman, dnf, zypper, apk, brew[/dim]")
-def colorful_logo():
- logos = ["magenta", "bright_magenta", "cyan", "blue", "green", "yellow"]
- style = choice(logos)
- logo_lines = r"""
- ▄█ █▄ ▄████████ ▄████████ ▄█ ▄█▄ ▄█ ███▄▄▄▄ ▄██████▄ ███ ▄██████▄ ▄██████▄ ▄█
- ███ ███ ███ ███ ███ ███ ███ ▄███▀ ███ ███▀▀▀██▄ ███ ███ ▀█████████▄ ███ ███ ███ ███ ███
- ███ ███ ███ ███ ███ █▀ ███▐██▀ ███▌ ███ ███ ███ █▀ ▀███▀▀██ ███ ███ ███ ███ ███
- ▄███▄▄▄▄███▄▄ ███ ███ ███ ▄█████▀ ███▌ ███ ███ ▄███ ███ ▀ ███ ███ ███ ███ ███
-▀▀███▀▀▀▀███▀ ▀███████████ ███ ▀▀█████▄ ███▌ ███ ███ ▀▀███ ████▄ ███ ███ ███ ███ ███ ███
- ███ ███ ███ ███ ███ █▄ ███▐██▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
- ███ ███ ███ ███ ███ ███ ███ ▀███▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███▌ ▄
- ███ █▀ ███ █▀ ████████▀ ███ ▀█▀ █▀ ▀█ █▀ ████████▀ ▄████▀ ▀██████▀ ▀██████▀ █████▄▄██
- ▀ ▀
-"""
- panel = Panel(Text(logo_lines, style=style), box=box.DOUBLE, border_style=style)
- console.print(panel)
- console.print(f"[bold {style}]https://github.com/Z4nzu/hackingtool[/bold {style}]\n")
+# ── Internet check ─────────────────────────────────────────────────────────────
-
-def choose_distro():
- console.print(Panel("[bold magenta]Select installation target[/bold magenta]\n\n[1] Kali / Parrot (apt)\n[2] Arch (pacman)\n[0] Exit", border_style="bright_magenta"))
- choice = IntPrompt.ask("Choice", choices=["0", "1", "2"], default=1)
- return choice
-
-
-def check_internet():
- console.print("[yellow]* Checking internet connectivity...[/yellow]")
- try:
- run_cmd("curl -sSf --max-time 10 https://www.google.com > /dev/null", check=True)
- console.print("[green][✔] Internet connection OK[/green]")
- return True
- except Exception:
- try:
- run_cmd("curl -sSf --max-time 10 https://github.com > /dev/null", check=True)
- console.print("[green][✔] Internet connection OK[/green]")
+def check_internet() -> bool:
+ console.print("[dim]Checking internet...[/dim]")
+ for host in ("https://github.com", "https://www.google.com"):
+ r = subprocess.run(
+ ["curl", "-sSf", "--max-time", "8", host],
+ capture_output=True,
+ )
+ if r.returncode == 0:
+ console.print("[success]✔ Internet connection OK[/success]")
return True
- except Exception:
- console.print("[red][✘] Internet connection not available[/red]")
- return False
+ console.print("[error]✘ No internet connection[/error]")
+ return False
-def system_update_and_install(choice):
- if choice == 1:
- console.print("[yellow]* Running apt update/upgrade...[/yellow]")
- try:
- run_cmd("apt update -y && apt upgrade -y")
- except subprocess.CalledProcessError as e:
- console.print(f"[red][!][/red] apt update/upgrade failed (non-fatal). Continuing installation. Error: {e}")
- console.print("[yellow]* Installing required packages (apt)...[/yellow]")
- try:
- run_cmd("apt-get install -y git python3-pip python3-venv figlet boxes php curl xdotool wget")
- except subprocess.CalledProcessError as e:
- console.print(f"[red][!][/red] apt-get install failed (non-fatal). You may need to install some packages manually. Error: {e}")
- elif choice == 2:
- console.print("[yellow]* Running pacman update...[/yellow]")
- try:
- run_cmd("pacman -Syu --noconfirm")
- except subprocess.CalledProcessError as e:
- console.print(f"[red][!][/red] pacman update failed (non-fatal). Continuing installation. Error: {e}")
- console.print("[yellow]* Installing required packages (pacman)...[/yellow]")
- try:
- run_cmd("pacman -S --noconfirm git python-pip")
- except subprocess.CalledProcessError as e:
- console.print(f"[red][!][/red] pacman install failed (non-fatal). You may need to install some packages manually. Error: {e}")
- else:
- console.print("[red]Invalid package manager choice[/red]")
+# ── System packages ────────────────────────────────────────────────────────────
+
+def install_system_packages():
+ mgr = CURRENT_OS.pkg_manager
+ if not mgr:
+ console.print("[warning]Skipping system packages — no package manager found.[/warning]")
+ return
+
+ # Use sudo only when not already root (uid != 0).
+ # Inside Docker we run as root and sudo is not installed.
+ priv = "" if os.geteuid() == 0 else "sudo "
+
+ # Update index first (skip for brew — not needed)
+ if mgr != "brew":
+ update_cmd = PACKAGE_UPDATE_CMDS.get(mgr, "")
+ if update_cmd:
+ console.print(f"[dim]Updating package index ({mgr})...[/dim]")
+ subprocess.run(f"{priv}{update_cmd}", shell=True, check=False)
+
+ packages = REQUIRED_PACKAGES.get(mgr, [])
+ if not packages:
+ return
+
+ install_tpl = PACKAGE_INSTALL_CMDS[mgr]
+ cmd = install_tpl.format(packages=" ".join(packages))
+ console.print(f"[dim]Installing system dependencies ({mgr})...[/dim]")
+ result = subprocess.run(f"{priv}{cmd}", shell=True, check=False)
+ if result.returncode != 0:
+ console.print("[warning]Some packages failed — you may need to install them manually.[/warning]")
+
+
+# ── App directory ──────────────────────────────────────────────────────────────
+
+def _is_source_dir() -> bool:
+ """Check if install.py is being run from a local clone (hackingtool.py exists alongside it)."""
+ return (Path(__file__).resolve().parent / "hackingtool.py").exists()
def prepare_install_dir():
- if INSTALL_DIR.exists():
- console.print(f"[red]The directory {INSTALL_DIR} already exists.[/red]")
- if Confirm.ask("Replace it? This will remove the existing directory", default=False):
- run_cmd(f"rm -rf {str(INSTALL_DIR)}")
- else:
- console.print("[red]Installation aborted by user.[/red]")
+ if APP_INSTALL_DIR.exists():
+ console.print(f"[warning]{APP_INSTALL_DIR} already exists.[/warning]")
+ if not Confirm.ask("Replace it? This removes the existing installation.", default=False):
+ console.print("[error]Installation aborted.[/error]")
sys.exit(1)
- INSTALL_DIR.mkdir(parents=True, exist_ok=True)
+ subprocess.run(["rm", "-rf", str(APP_INSTALL_DIR)], check=True)
+ APP_INSTALL_DIR.mkdir(parents=True, exist_ok=True)
-def git_clone():
- console.print("[yellow]* Cloning hackingtool repository...[/yellow]")
- try:
- run_cmd(f"git clone {REPO_URL} {str(INSTALL_DIR)}")
- console.print("[green][✔] Repository cloned[/green]")
+def install_source() -> bool:
+ """Clone the repo or copy from local source if already in a clone."""
+ source_dir = Path(__file__).resolve().parent
+
+ if _is_source_dir() and source_dir != APP_INSTALL_DIR:
+ # Already in a local clone — copy instead of re-cloning
+ console.print(f"[dim]Copying source from {source_dir}...[/dim]")
+ # Remove first to ensure clean copy (prepare_install_dir may have created it)
+ if APP_INSTALL_DIR.exists():
+ subprocess.run(["rm", "-rf", str(APP_INSTALL_DIR)], check=True)
+ subprocess.run(["cp", "-a", str(source_dir), str(APP_INSTALL_DIR)], check=True)
+ # Fix ownership so git doesn't complain about "dubious ownership"
+ subprocess.run(["chown", "-R", "root:root", str(APP_INSTALL_DIR)], check=False)
+ console.print("[success]✔ Source copied (no re-clone needed)[/success]")
return True
- except Exception as e:
- console.print(f"[red][✘] Failed to clone repository: {e}[/red]")
- return False
+
+ # Not running from source — clone from GitHub
+ console.print(f"[dim]Cloning {REPO_URL}...[/dim]")
+ r = subprocess.run(["git", "clone", "--depth", "1", REPO_URL, str(APP_INSTALL_DIR)], check=False)
+ if r.returncode == 0:
+ console.print("[success]✔ Repository cloned[/success]")
+ return True
+ console.print("[error]✘ Failed to clone repository[/error]")
+ return False
-def create_venv_and_install(choice):
- venv_path = INSTALL_DIR / VENV_DIR_NAME
- console.print("[yellow]* Creating virtual environment...[/yellow]")
- run_cmd(f"python3 -m venv {str(venv_path)}")
- activate = venv_path / "bin" / "activate"
+# ── Python venv ────────────────────────────────────────────────────────────────
+
+def create_venv_and_install():
+ venv_path = APP_INSTALL_DIR / VENV_DIR_NAME
+ console.print("[dim]Creating virtual environment...[/dim]")
+ subprocess.run([sys.executable, "-m", "venv", str(venv_path)], check=True)
+
pip = str(venv_path / "bin" / "pip")
- if (INSTALL_DIR / REQUIREMENTS).exists():
- console.print("[yellow]* Installing Python requirements...[/yellow]")
- run_cmd(f"{pip} install -r {str(INSTALL_DIR / REQUIREMENTS)}")
+ req = APP_INSTALL_DIR / REQUIREMENTS
+ if req.exists():
+ console.print("[dim]Installing Python requirements...[/dim]")
+ subprocess.run([pip, "install", "--quiet", "-r", str(req)], check=False)
else:
- console.print("[yellow]requirements.txt not found, skipping pip install.[/yellow]")
- if choice == 1:
- run_cmd("apt install figlet -y")
- elif choice == 2:
- # try pacman and fallback to AUR instructions
- try:
- run_cmd("pacman -S --noconfirm figlet")
- except Exception:
- console.print("[yellow]figlet not available in pacman automatically. Consider installing from AUR.[/yellow]")
+ console.print("[warning]requirements.txt not found — skipping pip install.[/warning]")
+# ── Launcher script ────────────────────────────────────────────────────────────
+
def create_launcher():
- console.print("[yellow]* Creating launcher script...[/yellow]")
- launcher = INSTALL_DIR / "hackingtool.sh"
- with open(launcher, "w") as f:
- f.write("#!/bin/bash\n")
- f.write(f"source {str(INSTALL_DIR / VENV_DIR_NAME)}/bin/activate\n")
- f.write(f"python3 {str(INSTALL_DIR / 'hackingtool.py')} \"$@\"\n")
- os.chmod(launcher, 0o755)
- # move to /usr/bin/hackingtool
- if BIN_PATH.exists():
- BIN_PATH.unlink()
- shutil.move(str(launcher), str(BIN_PATH))
- console.print(f"[green][✔] Launcher installed at {str(BIN_PATH)}[/green]")
-
-
-def final_messages():
- panel = Panel(
- "[bold magenta]Installation complete[/bold magenta]\n\nType [bold cyan]hackingtool[/bold cyan] in terminal to start.",
- border_style="magenta",
+ launcher = APP_INSTALL_DIR / "hackingtool.sh"
+ launcher.write_text(
+ "#!/bin/bash\n"
+ f'source "{APP_INSTALL_DIR / VENV_DIR_NAME}/bin/activate"\n'
+ f'python3 "{APP_INSTALL_DIR / "hackingtool.py"}" "$@"\n'
)
- console.print(panel)
+ launcher.chmod(0o755)
+ if APP_BIN_PATH.exists():
+ APP_BIN_PATH.unlink()
+ shutil.move(str(launcher), str(APP_BIN_PATH))
+ console.print(f"[success]✔ Launcher installed at {APP_BIN_PATH}[/success]")
+
+
+# ── User directories ───────────────────────────────────────────────────────────
+
+def create_user_directories():
+ """
+ Create ~/.hackingtool/ and write initial config.json.
+ Uses Path.home() — always correct regardless of username or OS.
+ Safe to run as root (creates /root/.hackingtool/) or as a normal user.
+ """
+ import json
+ USER_CONFIG_DIR.mkdir(parents=True, exist_ok=True)
+ USER_TOOLS_DIR.mkdir(parents=True, exist_ok=True)
+ if not USER_CONFIG_FILE.exists():
+ USER_CONFIG_FILE.write_text(json.dumps(DEFAULT_CONFIG, indent=2, sort_keys=True))
+ console.print(f"[success]✔ Config created at {USER_CONFIG_FILE}[/success]")
+ console.print(f"[success]✔ Tools directory: {USER_TOOLS_DIR}[/success]")
+
+
+# ── Entry point ────────────────────────────────────────────────────────────────
def main():
check_root()
console.clear()
- colorful_logo()
- choice = choose_distro()
- if choice == 0:
- console.print("[red]Exiting...[/red]")
- sys.exit(0)
+
+ console.print(Panel(
+ Text(f"HackingTool Installer {VERSION_DISPLAY}", style="bold magenta"),
+ box=box.DOUBLE, border_style="bright_magenta",
+ ))
+
+ check_os_compatibility()
+
if not check_internet():
sys.exit(1)
- with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
- progress.add_task(description="Preparing system...", total=None)
- system_update_and_install(choice)
+ with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as p:
+ p.add_task("Installing system packages...", total=None)
+ install_system_packages()
prepare_install_dir()
- ok = git_clone()
- if not ok:
+
+ if not install_source():
sys.exit(1)
- with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as progress:
- progress.add_task(description="Setting up virtualenv & requirements...", total=None)
- create_venv_and_install(choice)
+ with Progress(SpinnerColumn(), TextColumn("[progress.description]{task.description}")) as p:
+ p.add_task("Setting up virtualenv & requirements...", total=None)
+ create_venv_and_install()
create_launcher()
- final_messages()
+ create_user_directories()
+
+ console.print(Panel(
+ "[bold magenta]Installation complete![/bold magenta]\n\n"
+ "Type [bold cyan]hackingtool[/bold cyan] in a terminal to start.",
+ border_style="magenta",
+ ))
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
- console.print("\n[red]Installation interrupted by user[/red]")
+ console.print("\n[error]Installation interrupted.[/error]")
sys.exit(1)
except subprocess.CalledProcessError as e:
- console.print(f"[red]Command failed: {e}[/red]")
+ console.print(f"[error]Command failed: {e}[/error]")
sys.exit(1)
diff --git a/install.sh b/install.sh
new file mode 100755
index 0000000..7387c9a
--- /dev/null
+++ b/install.sh
@@ -0,0 +1,153 @@
+#!/usr/bin/env bash
+# ──────────────────────────────────────────────────────────────────────────────
+# HackingTool — One-liner installer
+#
+# Usage:
+# curl -sSL https://raw.githubusercontent.com/Z4nzu/hackingtool/master/install.sh | sudo bash
+#
+# What it does:
+# 1. Checks prerequisites (Python 3.10+, git, pip, venv)
+# 2. Clones the repository to /usr/share/hackingtool
+# 3. Creates a Python venv and installs requirements
+# 4. Creates a launcher at /usr/bin/hackingtool
+# 5. Creates user directories at ~/.hackingtool/
+# ──────────────────────────────────────────────────────────────────────────────
+set -euo pipefail
+
+REPO_URL="https://github.com/Z4nzu/hackingtool.git"
+INSTALL_DIR="/usr/share/hackingtool"
+BIN_PATH="/usr/bin/hackingtool"
+CONFIG_DIR="${SUDO_USER:+$(eval echo ~"$SUDO_USER")}/.hackingtool"
+# Fallback if not run via sudo
+: "${CONFIG_DIR:=$HOME/.hackingtool}"
+
+RED='\033[0;31m'
+GREEN='\033[0;32m'
+YELLOW='\033[1;33m'
+CYAN='\033[0;36m'
+BOLD='\033[1m'
+RESET='\033[0m'
+
+info() { echo -e "${CYAN}[*]${RESET} $1"; }
+ok() { echo -e "${GREEN}[✔]${RESET} $1"; }
+warn() { echo -e "${YELLOW}[!]${RESET} $1"; }
+fail() { echo -e "${RED}[✘]${RESET} $1"; exit 1; }
+
+# ── Root check ────────────────────────────────────────────────────────────────
+if [ "$(id -u)" -ne 0 ]; then
+ fail "This installer must be run as root.\n Usage: curl -sSL | ${BOLD}sudo${RESET} bash"
+fi
+
+echo ""
+echo -e "${BOLD}${CYAN} ⚔ HackingTool Installer${RESET}"
+echo -e " ─────────────────────────────────────"
+echo ""
+
+# ── Detect package manager ────────────────────────────────────────────────────
+if command -v apt-get &>/dev/null; then
+ PKG_MGR="apt-get"
+ PKG_UPDATE="apt-get update -qq"
+ PKG_INSTALL="apt-get install -y -qq"
+elif command -v pacman &>/dev/null; then
+ PKG_MGR="pacman"
+ PKG_UPDATE="pacman -Sy --noconfirm"
+ PKG_INSTALL="pacman -S --noconfirm --needed"
+elif command -v dnf &>/dev/null; then
+ PKG_MGR="dnf"
+ PKG_UPDATE="true"
+ PKG_INSTALL="dnf install -y -q"
+elif command -v brew &>/dev/null; then
+ PKG_MGR="brew"
+ PKG_UPDATE="true"
+ PKG_INSTALL="brew install"
+else
+ fail "No supported package manager found (need apt-get, pacman, dnf, or brew)."
+fi
+info "Package manager: ${BOLD}$PKG_MGR${RESET}"
+
+# ── Install system prerequisites ──────────────────────────────────────────────
+info "Installing prerequisites..."
+$PKG_UPDATE 2>/dev/null || true
+
+for pkg in git curl python3 python3-pip python3-venv; do
+ if [ "$PKG_MGR" = "pacman" ]; then
+ case "$pkg" in
+ python3) pkg="python" ;;
+ python3-pip) pkg="python-pip" ;;
+ python3-venv) continue ;; # included in python on Arch
+ esac
+ elif [ "$PKG_MGR" = "brew" ]; then
+ case "$pkg" in
+ python3-pip|python3-venv) continue ;; # included in python3 on macOS
+ esac
+ elif [ "$PKG_MGR" = "dnf" ]; then
+ case "$pkg" in
+ python3-venv) continue ;; # included in python3 on Fedora
+ esac
+ fi
+ $PKG_INSTALL "$pkg" 2>/dev/null || warn "Could not install $pkg — may already be present"
+done
+
+# ── Python version check ─────────────────────────────────────────────────────
+PYTHON_VERSION=$(python3 -c 'import sys; print(f"{sys.version_info.major}.{sys.version_info.minor}")' 2>/dev/null || echo "0.0")
+PYTHON_MAJOR=$(echo "$PYTHON_VERSION" | cut -d. -f1)
+PYTHON_MINOR=$(echo "$PYTHON_VERSION" | cut -d. -f2)
+
+if [ "$PYTHON_MAJOR" -lt 3 ] || { [ "$PYTHON_MAJOR" -eq 3 ] && [ "$PYTHON_MINOR" -lt 10 ]; }; then
+ fail "Python 3.10+ required. Found: Python $PYTHON_VERSION"
+fi
+ok "Python $PYTHON_VERSION"
+
+# ── Clone repository ──────────────────────────────────────────────────────────
+if [ -d "$INSTALL_DIR" ]; then
+ warn "$INSTALL_DIR already exists."
+ read -rp " Replace it? [y/N] " answer
+ if [[ "$answer" =~ ^[Yy] ]]; then
+ rm -rf "$INSTALL_DIR"
+ else
+ fail "Installation aborted."
+ fi
+fi
+
+info "Cloning repository..."
+git clone --depth 1 "$REPO_URL" "$INSTALL_DIR" 2>/dev/null
+ok "Cloned to $INSTALL_DIR"
+
+# ── Python venv + requirements ────────────────────────────────────────────────
+info "Creating virtual environment..."
+python3 -m venv "$INSTALL_DIR/venv"
+
+info "Installing Python dependencies..."
+"$INSTALL_DIR/venv/bin/pip" install --quiet -r "$INSTALL_DIR/requirements.txt" 2>/dev/null
+ok "Dependencies installed"
+
+# ── Create launcher ──────────────────────────────────────────────────────────
+cat > "$BIN_PATH" << 'LAUNCHER'
+#!/bin/bash
+source "/usr/share/hackingtool/venv/bin/activate"
+python3 "/usr/share/hackingtool/hackingtool.py" "$@"
+LAUNCHER
+chmod 755 "$BIN_PATH"
+ok "Launcher installed at $BIN_PATH"
+
+# ── User directories ─────────────────────────────────────────────────────────
+mkdir -p "$CONFIG_DIR/tools"
+if [ ! -f "$CONFIG_DIR/config.json" ]; then
+ cat > "$CONFIG_DIR/config.json" << CONF
+{
+ "tools_dir": "$CONFIG_DIR/tools",
+ "version": "2.0.0"
+}
+CONF
+fi
+# Fix ownership if run via sudo
+if [ -n "${SUDO_USER:-}" ]; then
+ chown -R "$SUDO_USER:$SUDO_USER" "$CONFIG_DIR"
+fi
+ok "User config: $CONFIG_DIR"
+
+# ── Done ──────────────────────────────────────────────────────────────────────
+echo ""
+echo -e "${GREEN}${BOLD} ✔ Installation complete!${RESET}"
+echo -e " Type ${BOLD}${CYAN}hackingtool${RESET} to start."
+echo ""
\ No newline at end of file
diff --git a/os_detect.py b/os_detect.py
new file mode 100644
index 0000000..1efca02
--- /dev/null
+++ b/os_detect.py
@@ -0,0 +1,131 @@
+import platform
+import shutil
+from dataclasses import dataclass, field
+from pathlib import Path
+
+
+@dataclass
+class OSInfo:
+ system: str # "linux", "macos", "windows", "unknown"
+ distro_id: str = "" # "kali", "ubuntu", "arch", "fedora", etc.
+ distro_like: str = "" # "debian", "rhel", etc. (from ID_LIKE)
+ distro_version: str = "" # "2024.1", "22.04", etc.
+ pkg_manager: str = "" # "apt-get", "pacman", "dnf", "brew", etc.
+ is_root: bool = False
+ home_dir: Path = field(default_factory=Path.home)
+ is_wsl: bool = False # Windows Subsystem for Linux
+ arch: str = "" # "x86_64", "aarch64", "arm64"
+
+
+def detect() -> OSInfo:
+ """
+ Fully detect the current OS, distro, and available package manager.
+ Never asks the user — entirely automatic.
+ """
+ import os
+
+ system_raw = platform.system()
+ system = system_raw.lower()
+ if system == "darwin":
+ system = "macos"
+
+ info = OSInfo(
+ system = system,
+ is_root = (os.geteuid() == 0) if hasattr(os, "geteuid") else False,
+ home_dir = Path.home(),
+ arch = platform.machine(),
+ )
+
+ # ── Linux-specific ─────────────────────────────────────────────────────────
+ if system == "linux":
+ # Detect WSL
+ try:
+ info.is_wsl = "microsoft" in Path("/proc/version").read_text().lower()
+ except (FileNotFoundError, PermissionError):
+ pass
+
+ # Read /etc/os-release (standard on all modern distros)
+ os_release: dict[str, str] = {}
+ for path in ("/etc/os-release", "/usr/lib/os-release"):
+ try:
+ for line in Path(path).read_text().splitlines():
+ k, _, v = line.partition("=")
+ os_release[k.strip()] = v.strip().strip('"')
+ break
+ except FileNotFoundError:
+ continue
+
+ info.distro_id = os_release.get("ID", "").lower()
+ info.distro_like = os_release.get("ID_LIKE", "").lower()
+ info.distro_version = os_release.get("VERSION_ID", "")
+
+ # ── Package manager detection (in priority order) ──────────────────────────
+ for mgr in ("apt-get", "pacman", "dnf", "zypper", "apk", "brew", "pkg"):
+ if shutil.which(mgr):
+ info.pkg_manager = mgr
+ break
+
+ return info
+
+
+# Module-level singleton — computed once on import
+CURRENT_OS: OSInfo = detect()
+
+
+# ── Per-OS package manager commands ────────────────────────────────────────────
+PACKAGE_INSTALL_CMDS: dict[str, str] = {
+ "apt-get": "apt-get install -y {packages}",
+ "pacman": "pacman -S --noconfirm {packages}",
+ "dnf": "dnf install -y {packages}",
+ "zypper": "zypper install -y {packages}",
+ "apk": "apk add {packages}",
+ "brew": "brew install {packages}",
+ "pkg": "pkg install -y {packages}",
+}
+
+PACKAGE_UPDATE_CMDS: dict[str, str] = {
+ "apt-get": "apt-get update -qq && apt-get upgrade -y",
+ "pacman": "pacman -Syu --noconfirm",
+ "dnf": "dnf upgrade -y",
+ "zypper": "zypper update -y",
+ "apk": "apk update && apk upgrade",
+ "brew": "brew update && brew upgrade",
+ "pkg": "pkg update && pkg upgrade -y",
+}
+
+# Core system packages needed per package manager
+REQUIRED_PACKAGES: dict[str, list[str]] = {
+ "apt-get": ["git", "python3-pip", "python3-venv", "curl", "wget",
+ "ruby", "ruby-dev", "golang-go", "php", "default-jre-headless"],
+ "pacman": ["git", "python-pip", "curl", "wget",
+ "ruby", "go", "php", "jre-openjdk-headless"],
+ "dnf": ["git", "python3-pip", "curl", "wget",
+ "ruby", "golang", "php", "java-17-openjdk-headless"],
+ "zypper": ["git", "python3-pip", "curl", "wget", "ruby", "go", "php"],
+ "brew": ["git", "python3", "curl", "wget", "ruby", "go", "php"],
+ "pkg": ["git", "python3", "py39-pip", "curl", "wget", "ruby", "go", "php83"],
+}
+
+
+def install_packages(packages: list[str], os_info: OSInfo | None = None) -> bool:
+ """Install system packages using the detected package manager."""
+ import subprocess
+ if os_info is None:
+ os_info = CURRENT_OS
+
+ mgr = os_info.pkg_manager
+ if mgr not in PACKAGE_INSTALL_CMDS:
+ print(f"[warning] Unknown package manager. Install manually: {packages}")
+ return False
+
+ cmd_template = PACKAGE_INSTALL_CMDS[mgr]
+ pkg_str = " ".join(packages)
+ cmd = cmd_template.format(packages=pkg_str)
+
+ # Prepend privilege escalation only on Linux (brew on macOS doesn't need sudo)
+ if os_info.system == "linux" and not os_info.is_root:
+ from constants import PRIV_CMD
+ cmd = f"{PRIV_CMD} {cmd}"
+
+ result = subprocess.run(cmd, shell=True, check=False)
+ return result.returncode == 0
\ No newline at end of file
diff --git a/requirements.txt b/requirements.txt
index 5fd2515..fd89c76 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,5 +1,5 @@
-boxes
-flask
-lolcat
-requests
-rich
\ No newline at end of file
+# Python dependencies for hackingtool
+# boxes and lolcat are system CLI tools, not pip packages — install via apt/brew
+# flask is unused — removed
+# requests is unused at runtime — removed
+rich>=13.0.0
diff --git a/tools/__init__.py b/tools/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tools/active_directory.py b/tools/active_directory.py
new file mode 100644
index 0000000..f1368e6
--- /dev/null
+++ b/tools/active_directory.py
@@ -0,0 +1,75 @@
+from core import HackingTool
+from core import HackingToolsCollection
+
+
+class BloodHound(HackingTool):
+ TITLE = "BloodHound (AD Attack Paths)"
+ DESCRIPTION = "Uses graph theory to reveal hidden attack paths in Active Directory/Azure environments."
+ INSTALL_COMMANDS = [
+ "pip install --user bloodhound",
+ "sudo apt-get install -y neo4j",
+ ]
+ RUN_COMMANDS = ["bloodhound-python --help"]
+ PROJECT_URL = "https://github.com/BloodHoundAD/BloodHound"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class NetExec(HackingTool):
+ TITLE = "NetExec — nxc (Network Pentesting)"
+ DESCRIPTION = "Swiss army knife for pentesting Windows/AD networks. Successor to CrackMapExec."
+ INSTALL_COMMANDS = ["pip install --user netexec"]
+ RUN_COMMANDS = ["nxc --help"]
+ PROJECT_URL = "https://github.com/Pennyw0rth/NetExec"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Impacket(HackingTool):
+ TITLE = "Impacket (Network Protocol Tools)"
+ DESCRIPTION = "Python classes for working with SMB, MSRPC, Kerberos, LDAP, and more."
+ INSTALL_COMMANDS = ["pip install --user impacket"]
+ RUN_COMMANDS = ["impacket-smbclient --help"]
+ PROJECT_URL = "https://github.com/fortra/impacket"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Responder(HackingTool):
+ TITLE = "Responder (LLMNR/NBT-NS Poisoner)"
+ DESCRIPTION = "LLMNR/NBT-NS/MDNS poisoner with rogue authentication servers for credential capture."
+ INSTALL_COMMANDS = ["git clone https://github.com/lgandx/Responder.git"]
+ RUN_COMMANDS = ["cd Responder && sudo python3 Responder.py --help"]
+ PROJECT_URL = "https://github.com/lgandx/Responder"
+ SUPPORTED_OS = ["linux"]
+
+
+class Certipy(HackingTool):
+ TITLE = "Certipy (AD Certificate Abuse)"
+ DESCRIPTION = "Active Directory Certificate Services enumeration and abuse tool."
+ INSTALL_COMMANDS = ["pip install --user certipy-ad"]
+ RUN_COMMANDS = ["certipy --help"]
+ PROJECT_URL = "https://github.com/ly4k/Certipy"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Kerbrute(HackingTool):
+ TITLE = "Kerbrute (Kerberos Brute Force)"
+ DESCRIPTION = "Kerberos pre-auth brute-forcer for username enumeration and password spraying."
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install github.com/ropnop/kerbrute@latest",
+ ]
+ RUN_COMMANDS = ["kerbrute --help"]
+ PROJECT_URL = "https://github.com/ropnop/kerbrute"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class ActiveDirectoryTools(HackingToolsCollection):
+ TITLE = "Active Directory Tools"
+ DESCRIPTION = "Tools for AD enumeration, attack path discovery, and credential attacks."
+ TOOLS = [
+ BloodHound(),
+ NetExec(),
+ Impacket(),
+ Responder(),
+ Certipy(),
+ Kerbrute(),
+ ]
\ No newline at end of file
diff --git a/tools/anonsurf.py b/tools/anonsurf.py
index 93884db..96ea134 100644
--- a/tools/anonsurf.py
+++ b/tools/anonsurf.py
@@ -1,129 +1,59 @@
-# coding=utf-8
import os
-from rich.console import Console
-from rich.panel import Panel
-from rich.prompt import Prompt
-from rich.text import Text
-from rich.table import Table
-
-from core import HackingTool
-from core import HackingToolsCollection
-
-console = Console()
-P_COLOR = "magenta"
+from core import HackingTool, HackingToolsCollection, console
class AnonymouslySurf(HackingTool):
TITLE = "Anonymously Surf"
DESCRIPTION = (
- "It automatically overwrites the RAM when\n"
- "the system is shutting down and also change Ip."
+ "It automatically overwrites the RAM when the system shuts down\n"
+ "and also changes your IP address."
)
+ # Bug 28 fix: was "cd kali-anonsurf && ./installer.sh && cd .. && sudo rm -r kali-anonsurf"
+ # Deleting the source on install means there is no retry if install fails.
+ # Now kept in a separate step so failure does not destroy the source.
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Und3rf10w/kali-anonsurf.git",
- "cd kali-anonsurf && sudo ./installer.sh && cd .. && sudo rm -r kali-anonsurf",
+ "git clone https://github.com/Und3rf10w/kali-anonsurf.git",
+ "cd kali-anonsurf && sudo ./installer.sh",
]
RUN_COMMANDS = ["sudo anonsurf start"]
PROJECT_URL = "https://github.com/Und3rf10w/kali-anonsurf"
+ SUPPORTED_OS = ["linux"]
def __init__(self):
- super(AnonymouslySurf, self).__init__([("Stop", self.stop)])
+ super().__init__([("Stop", self.stop)])
def stop(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=f"bold {P_COLOR}"))
- console.print("Stopping Anonsurf...", style=f"bold {P_COLOR}")
- os.system("sudo anonsurf stop")
+ import subprocess
+ console.print("[bold magenta]Stopping Anonsurf...[/bold magenta]")
+ subprocess.run(["sudo", "anonsurf", "stop"])
class Multitor(HackingTool):
TITLE = "Multitor"
- DESCRIPTION = "How to stay in multi places at the same time"
+ DESCRIPTION = "How to stay in multi places at the same time."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/trimstray/multitor.git",
- "cd multitor;sudo bash setup.sh install",
+ "git clone https://github.com/trimstray/multitor.git",
+ "cd multitor && sudo bash setup.sh install",
]
RUN_COMMANDS = [
"multitor --init 2 --user debian-tor --socks-port 9000 --control-port 9900 --proxy privoxy --haproxy"
]
PROJECT_URL = "https://github.com/trimstray/multitor"
+ SUPPORTED_OS = ["linux"]
def __init__(self):
- # keep original behavior (non-runnable) while still initializing
- super(Multitor, self).__init__(runnable=False)
+ super().__init__(runnable=False)
class AnonSurfTools(HackingToolsCollection):
TITLE = "Anonymously Hiding Tools"
- DESCRIPTION = ""
TOOLS = [
AnonymouslySurf(),
Multitor(),
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Anonymously Hiding Tools", show_lines=True, expand=True)
- table.add_column("Title", style="magenta", no_wrap=True)
- table.add_column("Description", style="magenta")
- table.add_column("Project URL", style="magenta", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc).strip().replace("\n", " "), str(url))
-
- panel = Panel(table, title=f"[{P_COLOR}]Available Tools[/ {P_COLOR}]", border_style=P_COLOR)
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- console.print(Panel.fit(
- "[bold magenta]Anonymously Hiding Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style=P_COLOR
- ))
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # delegate if collection-style interface exists
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # otherwise, if the tool has actions or a run method, prefer those
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
if __name__ == "__main__":
tools = AnonSurfTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/cloud_security.py b/tools/cloud_security.py
new file mode 100644
index 0000000..adbc738
--- /dev/null
+++ b/tools/cloud_security.py
@@ -0,0 +1,51 @@
+from core import HackingTool
+from core import HackingToolsCollection
+
+
+class Prowler(HackingTool):
+ TITLE = "Prowler (Cloud Security Scanner)"
+ DESCRIPTION = "Open-source security tool for AWS, Azure, GCP, and Kubernetes assessments."
+ INSTALL_COMMANDS = ["pip install --user prowler"]
+ RUN_COMMANDS = ["prowler --help"]
+ PROJECT_URL = "https://github.com/prowler-cloud/prowler"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class ScoutSuite(HackingTool):
+ TITLE = "ScoutSuite (Multi-Cloud Auditing)"
+ DESCRIPTION = "Multi-cloud security auditing tool for AWS, Azure, GCP, Alibaba, and Oracle."
+ INSTALL_COMMANDS = ["pip install --user scoutsuite"]
+ RUN_COMMANDS = ["scout --help"]
+ PROJECT_URL = "https://github.com/nccgroup/ScoutSuite"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Pacu(HackingTool):
+ TITLE = "Pacu (AWS Exploitation Framework)"
+ DESCRIPTION = "AWS exploitation framework for offensive security testing of AWS environments."
+ INSTALL_COMMANDS = ["pip install --user pacu"]
+ RUN_COMMANDS = ["pacu --help"]
+ PROJECT_URL = "https://github.com/RhinoSecurityLabs/pacu"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Trivy(HackingTool):
+ TITLE = "Trivy (Container/K8s Scanner)"
+ DESCRIPTION = "Comprehensive vulnerability scanner for containers, Kubernetes, IaC, and code."
+ INSTALL_COMMANDS = [
+ "curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin",
+ ]
+ RUN_COMMANDS = ["trivy --help"]
+ PROJECT_URL = "https://github.com/aquasecurity/trivy"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class CloudSecurityTools(HackingToolsCollection):
+ TITLE = "Cloud Security Tools"
+ DESCRIPTION = "Tools for cloud infrastructure security assessment and exploitation."
+ TOOLS = [
+ Prowler(),
+ ScoutSuite(),
+ Pacu(),
+ Trivy(),
+ ]
diff --git a/tools/ddos.py b/tools/ddos.py
index b8a1bbc..c24e71b 100644
--- a/tools/ddos.py
+++ b/tools/ddos.py
@@ -1,218 +1,143 @@
-# coding=utf-8
-import os
import subprocess
-from rich.console import Console
from rich.prompt import Prompt
-from rich.panel import Panel
-from rich.text import Text
-from rich.table import Table
-from core import HackingTool
-from core import HackingToolsCollection
-
-console = Console()
-P_COLOR = "magenta" # primary purple/magenta theme for styling
+from core import HackingTool, HackingToolsCollection, console
-class ddos(HackingTool):
- TITLE = "ddos"
+class DDoSTool(HackingTool):
+ TITLE = "DDoS"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = (
- "Best DDoS Attack Script With 36 Plus Methods."
- "DDoS attacks\n\b "
- "for SECURITY TESTING PURPOSES ONLY! "
+ "Best DDoS Attack Script With 36 Plus Methods. "
+ "DDoS attacks for SECURITY TESTING PURPOSES ONLY!"
)
-
INSTALL_COMMANDS = [
"git clone https://github.com/the-deepnet/ddos.git",
- "cd ddos;sudo pip3 install -r requirements.txt",
+ "cd ddos && sudo pip3 install -r requirements.txt",
]
- PROJECT_URL = "https://github.com/the-deepnet/ddos.git"
+ PROJECT_URL = "https://github.com/the-deepnet/ddos"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=f"bold {P_COLOR}"))
- method = Prompt.ask("Enter Method >>")
- url = Prompt.ask("Enter URL >>")
- threads = Prompt.ask("Enter Threads >>")
- proxylist = Prompt.ask("Enter ProxyList >>")
- multiple = Prompt.ask("Enter Multiple >>")
- timer = Prompt.ask("Enter Timer >>")
- os.system("cd ddos;")
+ from config import get_tools_dir
+ method = Prompt.ask("Enter Method")
+ url = Prompt.ask("Enter URL")
+ threads = Prompt.ask("Enter Threads")
+ proxylist = Prompt.ask("Enter ProxyList")
+ multiple = Prompt.ask("Enter Multiple")
+ timer = Prompt.ask("Enter Timer")
+ # Bug 4 fix: removed os.system("cd ddos;") — use cwd= instead
subprocess.run(
- [
- "sudo",
- "python3 ddos",
- method,
- url,
- "socks_type5.4.1",
- threads,
- proxylist,
- multiple,
- timer,
- ]
+ ["sudo", "python3", "ddos.py", method, url,
+ "socks_type5.4.1", threads, proxylist, multiple, timer],
+ cwd=str(get_tools_dir() / "ddos"),
)
class SlowLoris(HackingTool):
TITLE = "SlowLoris"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = (
- "Slowloris is basically an HTTP Denial of Service attack."
- "It send lots of HTTP Request"
+ "Slowloris is basically an HTTP Denial of Service attack. "
+ "It sends lots of HTTP requests."
)
INSTALL_COMMANDS = ["sudo pip3 install slowloris"]
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=f"bold {P_COLOR}"))
- target_site = Prompt.ask("Enter Target Site:-")
+ target_site = Prompt.ask("Enter Target Site")
subprocess.run(["slowloris", target_site])
class Asyncrone(HackingTool):
TITLE = "Asyncrone | Multifunction SYN Flood DDoS Weapon"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = (
- "aSYNcrone is a C language based, mulltifunction SYN Flood "
- "DDoS Weapon.\nDisable the destination system by sending a "
- "SYN packet intensively to the destination."
+ "aSYNcrone is a C language based, multifunction SYN Flood DDoS Weapon.\n"
+ "Disable the destination system by sending SYN packets intensively."
)
INSTALL_COMMANDS = [
"git clone https://github.com/fatih4842/aSYNcrone.git",
- "cd aSYNcrone;sudo gcc aSYNcrone.c -o aSYNcrone -lpthread",
+ "cd aSYNcrone && sudo gcc aSYNcrone.c -o aSYNcrone -lpthread",
]
PROJECT_URL = "https://github.com/fatihsnsy/aSYNcrone"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=f"bold {P_COLOR}"))
- source_port = Prompt.ask("Enter Source Port >>")
- target_ip = Prompt.ask("Enter Target IP >>")
- target_port = Prompt.ask("Enter Target port >>")
- os.system("cd aSYNcrone;")
+ from config import get_tools_dir
+ source_port = Prompt.ask("Enter Source Port")
+ target_ip = Prompt.ask("Enter Target IP")
+ target_port = Prompt.ask("Enter Target Port")
+ # Bug 5 fix: 1000 was int — subprocess requires all args str
+ # Bug 4 fix: removed os.system("cd aSYNcrone;") — use cwd= instead
subprocess.run(
- ["sudo", "./aSYNcrone", source_port, target_ip, target_port, 1000]
+ ["sudo", "./aSYNcrone", str(source_port), str(target_ip), str(target_port), "1000"],
+ cwd=str(get_tools_dir() / "aSYNcrone"),
)
class UFONet(HackingTool):
TITLE = "UFOnet"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = (
- "UFONet - is a free software, P2P and cryptographic "
- "-disruptive \n toolkit- that allows to perform DoS and "
- "DDoS attacks\n\b "
- "More Usage Visit"
+ "UFONet is a free software, P2P and cryptographic disruptive toolkit "
+ "that allows performing DoS and DDoS attacks."
)
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/epsylon/ufonet.git",
- "cd ufonet;sudo python3 setup.py install;sudo pip3 install GeoIP;sudo pip3 install python-geoip;sudo pip3 install pygeoip;sudo pip3 install requests;sudo pip3 install pycrypto;sudo pip3 install pycurl;sudo pip3 install whois;sudo pip3 install scapy-python3",
+ "git clone https://github.com/epsylon/ufonet.git",
+ "cd ufonet && pip install --user .",
]
- RUN_COMMANDS = ["sudo python3 ufonet --gui"]
+ RUN_COMMANDS = ["python3 ufonet --gui"]
PROJECT_URL = "https://github.com/epsylon/ufonet"
class GoldenEye(HackingTool):
TITLE = "GoldenEye"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = (
"GoldenEye is a python3 app for SECURITY TESTING PURPOSES ONLY!\n"
- "GoldenEye is a HTTP DoS Test Tool."
+ "GoldenEye is a HTTP DoS Test Tool.\n"
+ "Usage: ./goldeneye.py [OPTIONS]"
)
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/jseidl/GoldenEye.git;"
- "chmod -R 755 GoldenEye"
+ "git clone https://github.com/jseidl/GoldenEye.git",
+ "chmod -R 755 GoldenEye",
]
PROJECT_URL = "https://github.com/jseidl/GoldenEye"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=f"bold {P_COLOR}"))
- os.system("cd GoldenEye ;sudo ./goldeneye.py")
- console.print("Go to Directory\n[*] USAGE: ./goldeneye.py [OPTIONS]")
+ from config import get_tools_dir
+ # Bug 4 fix: removed os.system("cd GoldenEye; ...") — no-op cd subshell
+ url = Prompt.ask("Enter target URL")
+ subprocess.run(["sudo", "./goldeneye.py", url],
+ cwd=str(get_tools_dir() / "GoldenEye"))
class Saphyra(HackingTool):
TITLE = "SaphyraDDoS"
- DESCRIPTION = "A complex python code to DDoS any website with a very easy usage.!\n"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "A Python DDoS script for SECURITY TESTING PURPOSES ONLY."
INSTALL_COMMANDS = [
- "sudo su",
+ # Bug 7 fix: removed "sudo su" (first step was dropping into interactive root shell)
"git clone https://github.com/anonymous24x7/Saphyra-DDoS.git",
- "cd Saphyra-DDoS",
- "chmod +x saphyra.py",
- "python saphyra.py",
+ "chmod +x Saphyra-DDoS/saphyra.py",
]
PROJECT_URL = "https://github.com/anonymous24x7/Saphyra-DDoS"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=f"bold {P_COLOR}"))
- url = Prompt.ask("Enter url>>>")
- try:
- os.system("python saphyra.py " + url)
- except Exception:
- console.print("Enter a valid url.", style="bold red")
+ from config import get_tools_dir
+ url = Prompt.ask("Enter URL")
+ # Vuln 1 fix: was os.system("python saphyra.py " + url) — command injection
+ # Now uses subprocess list form — url is never interpolated into a shell string
+ subprocess.run(
+ ["python3", "saphyra.py", url],
+ cwd=str(get_tools_dir() / "Saphyra-DDoS"),
+ )
class DDOSTools(HackingToolsCollection):
TITLE = "DDOS Attack Tools"
- TOOLS = [SlowLoris(), Asyncrone(), UFONet(), GoldenEye(), Saphyra()]
-
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="DDOS Attack Tools", show_lines=True, expand=True)
- table.add_column("Title", style="magenta", no_wrap=True)
- table.add_column("Description", style="magenta")
- table.add_column("Project URL", style="magenta", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc).strip().replace("\n", " "), str(url))
-
- panel = Panel(table, title=f"[{P_COLOR}]Available Tools[/ {P_COLOR}]", border_style=P_COLOR)
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- console.print(Panel.fit(
- "[bold magenta]DDOS Attack Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style=P_COLOR
- ))
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # If tool exposes show_options (collection-style), delegate to it
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # Otherwise, if runnable, call its run method
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
+ TOOLS = [DDoSTool(), SlowLoris(), Asyncrone(), UFONet(), GoldenEye(), Saphyra()]
if __name__ == "__main__":
tools = DDOSTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/exploit_frameworks.py b/tools/exploit_frameworks.py
index 22f4fe7..39c91c1 100644
--- a/tools/exploit_frameworks.py
+++ b/tools/exploit_frameworks.py
@@ -1,24 +1,17 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
-from tools.webattack import Web2Attack
+from core import HackingTool, HackingToolsCollection, console
+from tools.web_attack import Web2Attack
-from rich.console import Console
-from rich.table import Table
from rich.panel import Panel
from rich.text import Text
from rich.prompt import Prompt
-console = Console()
-PURPLE_STYLE = "bold magenta"
-
class RouterSploit(HackingTool):
TITLE = "RouterSploit"
DESCRIPTION = "The RouterSploit Framework is an open-source exploitation " \
"framework dedicated to embedded devices"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/threat9/routersploit.git",
+ "git clone https://github.com/threat9/routersploit.git",
"cd routersploit && sudo python3 -m pip install -r requirements.txt"
]
RUN_COMMANDS = ["cd routersploit && sudo python3 rsf.py"]
@@ -27,9 +20,10 @@ class RouterSploit(HackingTool):
class WebSploit(HackingTool):
TITLE = "WebSploit"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "Websploit is an advanced MITM framework."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/The404Hacking/websploit.git;cd websploit/Setup;sudo chmod +x install.sh && sudo bash install.sh"
+ "git clone https://github.com/The404Hacking/websploit.git;cd websploit/Setup;sudo chmod +x install.sh && sudo bash install.sh"
]
RUN_COMMANDS = ["sudo websploit"]
PROJECT_URL = "https://github.com/The404Hacking/websploit "
@@ -45,13 +39,16 @@ class Commix(HackingTool):
"attacks.\n Usage: python commix.py [option(s)]"
INSTALL_COMMANDS = [
"git clone https://github.com/commixproject/commix.git commix",
- "cd commix;sudo python setup.py install"
+ # Bug 26 fix: was "sudo python setup.py install" (Python 2)
+ "cd commix && pip install --user .",
]
- RUN_COMMANDS = ["sudo python commix.py --wizard"]
+ # Bug 26 fix: was "sudo python commix.py --wizard" (Python 2)
+ RUN_COMMANDS = ["cd commix && sudo python3 commix.py --wizard"]
PROJECT_URL = "https://github.com/commixproject/commix"
def __init__(self):
- super(Commix, self).__init__(runnable=False)
+ # Py3-4 fix: super(Commix, self) → super()
+ super().__init__(runnable=False)
class ExploitFrameworkTools(HackingToolsCollection):
@@ -63,90 +60,6 @@ class ExploitFrameworkTools(HackingToolsCollection):
Web2Attack()
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Exploit framework", show_lines=True, expand=True)
- table.add_column("Title", style="magenta", no_wrap=True)
- table.add_column("Description", style="magenta")
- table.add_column("Project URL", style="magenta", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc).strip().replace("\n", " "), str(url))
-
- panel = Panel(table, title=f"[magenta]Available Tools[/magenta]", border_style=PURPLE_STYLE)
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- console.print(Panel.fit(
- "[bold magenta]Exploit Framework Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style=PURPLE_STYLE
- ))
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # If tool exposes show_options (collection-style), delegate to it
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # Otherwise, if runnable, call its run method
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
-# --- Optional helper: pretty-print the tools list into a magenta-styled table.
-# This helper is non-invasive and does not change tool logic.
-def render_tools_table(tools, title: str | None = None):
- """
- Render a list of HackingTool instances (or objects with TITLE/DESCRIPTION/PROJECT_URL)
- as a rich table in magenta style.
- """
- tbl = Table(title=title or "Tools", show_lines=False, header_style=PURPLE_STYLE)
- tbl.add_column("Name", style=PURPLE_STYLE, no_wrap=True)
- tbl.add_column("Description")
- tbl.add_column("Project URL", overflow="fold")
-
- for t in tools:
- name = getattr(t, "TITLE", "")
- desc = getattr(t, "DESCRIPTION", "")
- url = getattr(t, "PROJECT_URL", "")
- tbl.add_row(name, desc, url)
-
- console.print(Panel(tbl, border_style=PURPLE_STYLE, title=Text(title or "Toolset", style=PURPLE_STYLE)))
-
-
if __name__ == "__main__":
tools = ExploitFrameworkTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/forensic_tools.py b/tools/forensic_tools.py
deleted file mode 100644
index 29b1af1..0000000
--- a/tools/forensic_tools.py
+++ /dev/null
@@ -1,179 +0,0 @@
-# coding=utf-8
-import os
-import sys
-
-# Fetching parent directory for importing core.py
-current_dir = os.path.dirname(__file__)
-parent_dir = os.path.dirname(current_dir)
-sys.path.append(parent_dir)
-
-from core import HackingTool
-from core import HackingToolsCollection
-
-from rich.console import Console
-from rich.panel import Panel
-from rich.text import Text
-from rich.table import Table
-from rich.prompt import Prompt
-
-console = Console()
-PURPLE_STYLE = "bold magenta"
-
-
-class Autopsy(HackingTool):
- TITLE = "Autopsy"
- DESCRIPTION = "Autopsy is a platform that is used by Cyber Investigators.\n" \
- "[!] Works in any OS\n" \
- "[!] Recover Deleted Files from any OS & Media \n" \
- "[!] Extract Image Metadata"
- RUN_COMMANDS = ["sudo autopsy"]
-
- def __init__(self):
- super(Autopsy, self).__init__(installable=False)
-
-
-class Wireshark(HackingTool):
- TITLE = "Wireshark"
- DESCRIPTION = "Wireshark is a network capture and analyzer \n" \
- "tool to see what’s happening in your network.\n " \
- "And also investigate Network related incident"
- RUN_COMMANDS = ["sudo wireshark"]
-
- def __init__(self):
- super(Wireshark, self).__init__(installable=False)
-
-
-class BulkExtractor(HackingTool):
- TITLE = "Bulk extractor"
- DESCRIPTION = "Extract useful information without parsing the file system"
- PROJECT_URL = "https://github.com/simsong/bulk_extractor"
-
- def __init__(self):
- super(BulkExtractor, self).__init__([
- ('GUI Mode (Download required)', self.gui_mode),
- ('CLI Mode', self.cli_mode)
- ], installable=False, runnable=False)
-
- def gui_mode(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=PURPLE_STYLE))
- console.print("[bold magenta]Cloning repository and attempting to run GUI...[/]")
- os.system("sudo git clone https://github.com/simsong/bulk_extractor.git")
- os.system("ls src/ && cd .. && cd java_gui && ./BEViewer")
- console.print(
- "[magenta]If you get an error after clone go to /java_gui/src/ and compile the .jar file && run ./BEViewer[/]")
- console.print(
- "[magenta]Please visit for more details about installation: https://github.com/simsong/bulk_extractor[/]")
-
- def cli_mode(self):
- console.print(Panel(Text(self.TITLE + " - CLI Mode", justify="center"), style=PURPLE_STYLE))
- os.system("sudo apt install bulk-extractor")
- console.print("[magenta]Showing bulk_extractor help and options:[/]")
- os.system("bulk_extractor -h")
- os.system('echo "bulk_extractor [options] imagefile" | boxes -d headline | lolcat')
-
-
-class Guymager(HackingTool):
- TITLE = "Disk Clone and ISO Image Acquire"
- DESCRIPTION = "Guymager is a free forensic imager for media acquisition."
- INSTALL_COMMANDS = ["sudo apt install guymager"]
- RUN_COMMANDS = ["sudo guymager"]
- PROJECT_URL = "https://guymager.sourceforge.io/"
-
- def __init__(self):
- super(Guymager, self).__init__(installable=False)
-
-
-class Toolsley(HackingTool):
- TITLE = "Toolsley"
- DESCRIPTION = "Toolsley got more than ten useful tools for investigation.\n" \
- "[+]File signature verifier\n" \
- "[+]File identifier \n" \
- "[+]Hash & Validate \n" \
- "[+]Binary inspector \n " \
- "[+]Encode text \n" \
- "[+]Data URI generator \n" \
- "[+]Password generator"
- PROJECT_URL = "https://www.toolsley.com/"
-
- def __init__(self):
- super(Toolsley, self).__init__(installable=False, runnable=False)
-
-
-class ForensicTools(HackingToolsCollection):
- TITLE = "Forensic tools"
- TOOLS = [
- Autopsy(),
- Wireshark(),
- BulkExtractor(),
- Guymager(),
- Toolsley()
- ]
-
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Forensic Tools", show_lines=True, expand=True)
- table.add_column("Title", style=PURPLE_STYLE, no_wrap=True)
- table.add_column("Description", style=PURPLE_STYLE)
- table.add_column("Project URL", style=PURPLE_STYLE, no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc).replace("\n", " "), str(url))
-
- console.print(Panel(table, title=f"[magenta]Available Tools[/magenta]", border_style=PURPLE_STYLE))
-
- def show_options(self, parent=None):
- console.print("\n")
- console.print(Panel.fit(
- "[bold magenta]Forensic Tools Collection[/bold magenta]\n"
- "Select a tool to run or view options.",
- border_style=PURPLE_STYLE
- ))
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # delegate to collection-like tools if available
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # if tool exposes actions (like BulkExtractor) and has a menu, try to show it
- elif hasattr(selected, "show_actions"):
- selected.show_actions(parent=self)
- # otherwise try to call run if present
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
-if __name__ == "__main__":
- tools = ForensicTools()
- tools.pretty_print()
- tools.show_options()
diff --git a/tools/forensics.py b/tools/forensics.py
new file mode 100644
index 0000000..9fe0b76
--- /dev/null
+++ b/tools/forensics.py
@@ -0,0 +1,156 @@
+import os
+
+from core import HackingTool, HackingToolsCollection, console
+
+from rich.panel import Panel
+from rich.text import Text
+from rich.prompt import Prompt
+
+
+class Autopsy(HackingTool):
+ TITLE = "Autopsy"
+ DESCRIPTION = "Autopsy is a platform that is used by Cyber Investigators.\n" \
+ "[!] Works in any OS\n" \
+ "[!] Recover Deleted Files from any OS & Media \n" \
+ "[!] Extract Image Metadata"
+ RUN_COMMANDS = ["sudo autopsy"]
+
+ def __init__(self):
+ super().__init__(installable=False)
+
+
+class Wireshark(HackingTool):
+ TITLE = "Wireshark"
+ DESCRIPTION = "Wireshark is a network capture and analyzer \n" \
+ "tool to see what’s happening in your network.\n " \
+ "And also investigate Network related incident"
+ RUN_COMMANDS = ["sudo wireshark"]
+
+ def __init__(self):
+ super().__init__(installable=False)
+
+
+class BulkExtractor(HackingTool):
+ TITLE = "Bulk extractor"
+ DESCRIPTION = "Extract useful information without parsing the file system"
+ PROJECT_URL = "https://github.com/simsong/bulk_extractor"
+ SUPPORTED_OS = ["linux"]
+
+ def __init__(self):
+ super().__init__([
+ ('GUI Mode (Download required)', self.gui_mode),
+ ('CLI Mode', self.cli_mode)
+ ], installable=False, runnable=False)
+
+ def gui_mode(self):
+ import subprocess
+ from config import get_tools_dir
+ console.print(Panel(Text(self.TITLE, justify="center"), style="bold magenta"))
+ console.print("[bold magenta]Cloning repository and attempting to run GUI...[/]")
+ tools_dir = get_tools_dir()
+ subprocess.run(["git", "clone", "https://github.com/simsong/bulk_extractor.git"],
+ cwd=str(tools_dir))
+ be_dir = tools_dir / "bulk_extractor"
+ subprocess.run(["./BEViewer"], cwd=str(be_dir / "java_gui"))
+ console.print(
+ "[magenta]If you get an error after clone go to /java_gui/src/ and compile the .jar file && run ./BEViewer[/]")
+ console.print(
+ "[magenta]Please visit for more details about installation: https://github.com/simsong/bulk_extractor[/]")
+
+ def cli_mode(self):
+ import subprocess
+ console.print(Panel(Text(self.TITLE + " - CLI Mode", justify="center"), style="bold magenta"))
+ subprocess.run(["sudo", "apt", "install", "-y", "bulk-extractor"])
+ console.print("[magenta]bulk_extractor [options] imagefile[/]")
+ subprocess.run(["bulk_extractor", "-h"])
+
+
+class Guymager(HackingTool):
+ TITLE = "Disk Clone and ISO Image Acquire"
+ DESCRIPTION = "Guymager is a free forensic imager for media acquisition."
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt install guymager"]
+ RUN_COMMANDS = ["sudo guymager"]
+ PROJECT_URL = "https://guymager.sourceforge.io/"
+
+
+
+class Toolsley(HackingTool):
+ TITLE = "Toolsley"
+ DESCRIPTION = "Toolsley got more than ten useful tools for investigation.\n" \
+ "[+]File signature verifier\n" \
+ "[+]File identifier \n" \
+ "[+]Hash & Validate \n" \
+ "[+]Binary inspector \n " \
+ "[+]Encode text \n" \
+ "[+]Data URI generator \n" \
+ "[+]Password generator"
+ PROJECT_URL = "https://www.toolsley.com/"
+
+ def __init__(self):
+ super().__init__(installable=False, runnable=False)
+
+
+class Volatility3(HackingTool):
+ TITLE = "Volatility 3 (Memory Forensics)"
+ DESCRIPTION = (
+ "The world's most widely used memory forensics framework.\n"
+ "Usage: python3 vol.py -f memory.dmp windows.pslist"
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/volatilityfoundation/volatility3.git",
+ "cd volatility3 && pip install --user -r requirements.txt",
+ ]
+ PROJECT_URL = "https://github.com/volatilityfoundation/volatility3"
+
+ def run(self):
+ from config import get_tools_dir
+ import subprocess
+ from rich.prompt import Prompt
+ dump = Prompt.ask("Enter path to memory dump")
+ plugin = Prompt.ask("Enter plugin", default="windows.pslist")
+ subprocess.run(
+ ["python3", "vol.py", "-f", dump, plugin],
+ cwd=str(get_tools_dir() / "volatility3"),
+ )
+
+
+class Binwalk(HackingTool):
+ TITLE = "Binwalk (Firmware Analysis)"
+ DESCRIPTION = (
+ "Analyze, reverse engineer, and extract firmware images.\n"
+ "Usage: binwalk -e firmware.bin"
+ )
+ INSTALL_COMMANDS = ["pip install --user binwalk"]
+ RUN_COMMANDS = ["binwalk --help"]
+ PROJECT_URL = "https://github.com/ReFirmLabs/binwalk"
+
+
+class Pspy(HackingTool):
+ TITLE = "pspy (Process Monitor — No Root)"
+ DESCRIPTION = "Monitor Linux processes without root — detects cron jobs, scheduled tasks, other users' commands."
+ INSTALL_COMMANDS = [
+ "curl -sSL https://github.com/DominicBreuker/pspy/releases/latest/download/pspy64 -o pspy",
+ "chmod +x pspy",
+ ]
+ RUN_COMMANDS = ["./pspy --help"]
+ PROJECT_URL = "https://github.com/DominicBreuker/pspy"
+ SUPPORTED_OS = ["linux"]
+
+
+class ForensicTools(HackingToolsCollection):
+ TITLE = "Forensic tools"
+ TOOLS = [
+ Autopsy(),
+ Wireshark(),
+ BulkExtractor(),
+ Guymager(),
+ Toolsley(),
+ Volatility3(),
+ Binwalk(),
+ Pspy(),
+ ]
+
+if __name__ == "__main__":
+ tools = ForensicTools()
+ tools.show_options()
diff --git a/tools/information_gathering_tools.py b/tools/information_gathering.py
similarity index 50%
rename from tools/information_gathering_tools.py
rename to tools/information_gathering.py
index 14f9bc7..e773839 100644
--- a/tools/information_gathering_tools.py
+++ b/tools/information_gathering.py
@@ -1,35 +1,28 @@
-# coding=utf-8
import os
import socket
import subprocess
import webbrowser
import sys
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
from core import clear_screen
-from rich.console import Console
from rich.panel import Panel
from rich.text import Text
from rich.prompt import Prompt
-from rich.table import Table
-
-console = Console()
-PURPLE_STYLE = "bold magenta"
class NMAP(HackingTool):
TITLE = "Network Map (nmap)"
DESCRIPTION = "Free and open source utility for network discovery and security auditing"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/nmap/nmap.git",
+ "git clone https://github.com/nmap/nmap.git",
"sudo chmod -R 755 nmap && cd nmap && sudo ./configure && make && sudo make install"
]
PROJECT_URL = "https://github.com/nmap/nmap"
def __init__(self):
- super(NMAP, self).__init__(runnable=False)
+ super().__init__(runnable=False)
class Dracnmap(HackingTool):
@@ -37,7 +30,7 @@ class Dracnmap(HackingTool):
DESCRIPTION = "Dracnmap is an open source program which is using to \n" \
"exploit the network and gathering information with nmap help."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Screetsec/Dracnmap.git",
+ "git clone https://github.com/Screetsec/Dracnmap.git",
"cd Dracnmap && chmod +x dracnmap-v2.2-dracOs.sh dracnmap-v2.2.sh"
]
RUN_COMMANDS = ["cd Dracnmap;sudo ./dracnmap-v2.2.sh"]
@@ -48,12 +41,12 @@ class PortScan(HackingTool):
TITLE = "Port scanning"
def __init__(self):
- super(PortScan, self).__init__(installable=False)
+ super().__init__(installable=False)
def run(self):
clear_screen()
- console.print(Panel(Text(self.TITLE, justify="center"), style=PURPLE_STYLE))
- target = Prompt.ask("[bold]Select a Target IP[/]", default="", show_default=False)
+ console.print(Panel(Text(self.TITLE, justify="center"), style="bold magenta"))
+ target = Prompt.ask("[bold]Select a Target IP[/bold magenta]", default="", show_default=False)
subprocess.run(["sudo", "nmap", "-O", "-Pn", target])
@@ -61,14 +54,14 @@ class Host2IP(HackingTool):
TITLE = "Host to IP "
def __init__(self):
- super(Host2IP, self).__init__(installable=False)
+ super().__init__(installable=False)
def run(self):
clear_screen()
- console.print(Panel(Text(self.TITLE, justify="center"), style=PURPLE_STYLE))
+ console.print(Panel(Text(self.TITLE, justify="center"), style="bold magenta"))
host = Prompt.ask("Enter host name (e.g. www.google.com):- ")
ips = socket.gethostbyname(host)
- console.print(f"[{PURPLE_STYLE}]{host} -> {ips}[/]")
+ console.print("[bold magenta]{host} -> {ips}[/bold magenta]")
class XeroSploit(HackingTool):
@@ -99,8 +92,8 @@ class ReconSpider(HackingTool):
"Websites, Organizations and find out information from" \
" different sources.\n"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/bhavsec/reconspider.git",
- "sudo apt install python3 python3-pip && cd reconspider && sudo python3 setup.py install"
+ "git clone https://github.com/bhavsec/reconspider.git",
+ "sudo apt install -y python3 python3-pip && cd reconspider && pip install --user ."
]
RUN_COMMANDS = ["cd reconspider;python3 reconspider.py"]
PROJECT_URL = "https://github.com/bhavsec/reconspider"
@@ -111,11 +104,11 @@ class IsItDown(HackingTool):
DESCRIPTION = "Check Website Is Online or Not"
def __init__(self):
- super(IsItDown, self).__init__(
+ super().__init__(
[('Open', self.open)], installable=False, runnable=False)
def open(self):
- console.print(Panel("Opening isitdownrightnow.com", style=PURPLE_STYLE))
+ console.print(Panel("Opening isitdownrightnow.com", style="bold magenta"))
webbrowser.open_new_tab("https://www.isitdownrightnow.com/")
@@ -125,7 +118,7 @@ class Infoga(HackingTool):
"(ip, hostname, country,...) from different public source"
INSTALL_COMMANDS = [
"git clone https://github.com/m4ll0k/Infoga.git",
- "cd Infoga;sudo python3 setup.py install"
+ "cd Infoga && pip install --user ."
]
RUN_COMMANDS = ["cd Infoga;python3 infoga.py"]
PROJECT_URL = "https://github.com/m4ll0k/Infoga"
@@ -149,10 +142,13 @@ class Striker(HackingTool):
PROJECT_URL = "https://github.com/s0md3v/Striker"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=PURPLE_STYLE))
- site = Prompt.ask("Enter Site Name (example.com) >> ")
- os.chdir("Striker")
- subprocess.run(["sudo", "python3", "striker.py", site])
+ from config import get_tools_dir
+ site = Prompt.ask("Enter Site Name (example.com)")
+ # Bug 3 fix: os.chdir() corrupts the process CWD permanently — use cwd= instead
+ subprocess.run(
+ ["sudo", "python3", "striker.py", site],
+ cwd=str(get_tools_dir() / "Striker"),
+ )
class SecretFinder(HackingTool):
@@ -168,7 +164,7 @@ class SecretFinder(HackingTool):
PROJECT_URL = "https://github.com/m4ll0k/SecretFinder"
def __init__(self):
- super(SecretFinder, self).__init__(runnable=False)
+ super().__init__(runnable=False)
class Shodan(HackingTool):
@@ -180,7 +176,7 @@ class Shodan(HackingTool):
PROJECT_URL = "https://github.com/m4ll0k/Shodanfy.py"
def __init__(self):
- super(Shodan, self).__init__(runnable=False)
+ super().__init__(runnable=False)
class PortScannerRanger(HackingTool):
@@ -189,14 +185,17 @@ class PortScannerRanger(HackingTool):
"all alive hosts within your range that you specify."
INSTALL_COMMANDS = [
"git clone https://github.com/floriankunushevci/rang3r.git;"
- "sudo pip install termcolor"]
+ "pip install --user termcolor"]
PROJECT_URL = "https://github.com/floriankunushevci/rang3r"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=PURPLE_STYLE))
- ip = Prompt.ask("Enter Ip >> ")
- os.chdir("rang3r")
- subprocess.run(["sudo", "python", "rang3r.py", "--ip", ip])
+ from config import get_tools_dir
+ ip = Prompt.ask("Enter IP")
+ # Bug 3 fix: os.chdir() replaced with cwd= parameter
+ subprocess.run(
+ ["sudo", "python3", "rang3r.py", "--ip", ip],
+ cwd=str(get_tools_dir() / "rang3r"),
+ )
class Breacher(HackingTool):
@@ -206,10 +205,143 @@ class Breacher(HackingTool):
PROJECT_URL = "https://github.com/s0md3v/Breacher"
def run(self):
- console.print(Panel(Text(self.TITLE, justify="center"), style=PURPLE_STYLE))
- domain = Prompt.ask("Enter domain (example.com) >> ")
- os.chdir("Breacher")
- subprocess.run(["python3", "breacher.py", "-u", domain])
+ from config import get_tools_dir
+ domain = Prompt.ask("Enter domain (example.com)")
+ # Bug 3 fix: os.chdir() replaced with cwd= parameter
+ subprocess.run(
+ ["python3", "breacher.py", "-u", domain],
+ cwd=str(get_tools_dir() / "Breacher"),
+ )
+
+
+class TheHarvester(HackingTool):
+ TITLE = "theHarvester (OSINT)"
+ DESCRIPTION = (
+ "Gather emails, names, subdomains, IPs and URLs from public sources.\n"
+ "Usage: theHarvester -d example.com -b all"
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/laramies/theHarvester.git",
+ "cd theHarvester && pip install --user -r requirements/base.txt",
+ ]
+ RUN_COMMANDS = ["cd theHarvester && python3 theHarvester.py -h"]
+ PROJECT_URL = "https://github.com/laramies/theHarvester"
+
+
+class Amass(HackingTool):
+ TITLE = "Amass (Attack Surface Mapping)"
+ DESCRIPTION = (
+ "In-depth subdomain enumeration and attack surface mapping.\n"
+ "Usage: amass enum -d example.com"
+ )
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install -v github.com/owasp-amass/amass/v4/...@master",
+ ]
+ RUN_COMMANDS = ["amass -h"]
+ PROJECT_URL = "https://github.com/owasp-amass/amass"
+
+
+class Masscan(HackingTool):
+ TITLE = "Masscan (Fast Port Scanner)"
+ DESCRIPTION = (
+ "Fastest internet port scanner — 10 million packets/sec.\n"
+ "Usage: masscan -p1-65535 --rate=1000"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt-get install -y masscan"]
+ RUN_COMMANDS = ["masscan --help"]
+ PROJECT_URL = "https://github.com/robertdavidgraham/masscan"
+
+
+class RustScan(HackingTool):
+ TITLE = "RustScan (Modern Port Scanner)"
+ DESCRIPTION = (
+ "Scans all 65k ports in 3 seconds, passes results to nmap automatically.\n"
+ "Usage: rustscan -a -- -sV"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = [
+ "curl -sLO https://github.com/RustScan/RustScan/releases/latest/download/rustscan_2.3.0_amd64.deb",
+ "sudo dpkg -i rustscan_2.3.0_amd64.deb",
+ ]
+ RUN_COMMANDS = ["rustscan --help"]
+ PROJECT_URL = "https://github.com/RustScan/RustScan"
+
+
+class Holehe(HackingTool):
+ TITLE = "Holehe (Email → Social Accounts)"
+ DESCRIPTION = (
+ "Check if an email address is registered on 120+ websites.\n"
+ "Usage: holehe user@example.com"
+ )
+ INSTALL_COMMANDS = ["pip install --user holehe"]
+ RUN_COMMANDS = ["holehe --help"]
+ PROJECT_URL = "https://github.com/megadose/holehe"
+
+
+class Maigret(HackingTool):
+ TITLE = "Maigret (Username OSINT)"
+ DESCRIPTION = (
+ "Collect a dossier on a person by username across 3000+ sites.\n"
+ "Usage: maigret "
+ )
+ INSTALL_COMMANDS = ["pip install --user maigret"]
+ RUN_COMMANDS = ["maigret --help"]
+ PROJECT_URL = "https://github.com/soxoj/maigret"
+
+
+class Httpx(HackingTool):
+ TITLE = "httpx (HTTP Toolkit)"
+ DESCRIPTION = (
+ "Fast multi-purpose HTTP probing tool.\n"
+ "Usage: httpx -l urls.txt -status-code -title -tech-detect"
+ )
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install -v github.com/projectdiscovery/httpx/cmd/httpx@latest",
+ ]
+ RUN_COMMANDS = ["httpx -h"]
+ PROJECT_URL = "https://github.com/projectdiscovery/httpx"
+
+
+class SpiderFoot(HackingTool):
+ TITLE = "SpiderFoot (OSINT Automation)"
+ DESCRIPTION = "Automates OSINT collection for threat intelligence and attack surface mapping."
+ INSTALL_COMMANDS = ["pip install --user spiderfoot"]
+ RUN_COMMANDS = ["spiderfoot -h"]
+ PROJECT_URL = "https://github.com/smicallef/spiderfoot"
+
+
+class Subfinder(HackingTool):
+ TITLE = "Subfinder (Subdomain Enumeration)"
+ DESCRIPTION = "Fast passive subdomain enumeration using multiple sources."
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest",
+ ]
+ RUN_COMMANDS = ["subfinder -h"]
+ PROJECT_URL = "https://github.com/projectdiscovery/subfinder"
+
+
+class TruffleHog(HackingTool):
+ TITLE = "TruffleHog (Secret Scanner)"
+ DESCRIPTION = "Find, verify, and analyze leaked credentials across git repos, S3 buckets, filesystems."
+ INSTALL_COMMANDS = ["pip install --user trufflehog"]
+ RUN_COMMANDS = ["trufflehog --help"]
+ PROJECT_URL = "https://github.com/trufflesecurity/trufflehog"
+
+
+class Gitleaks(HackingTool):
+ TITLE = "Gitleaks (Git Secret Scanner)"
+ DESCRIPTION = "Fast secret scanner for git repos — detects hardcoded passwords, API keys, tokens."
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install github.com/gitleaks/gitleaks/v8@latest",
+ ]
+ RUN_COMMANDS = ["gitleaks --help"]
+ PROJECT_URL = "https://github.com/gitleaks/gitleaks"
class InformationGatheringTools(HackingToolsCollection):
@@ -229,74 +361,20 @@ class InformationGatheringTools(HackingToolsCollection):
SecretFinder(),
Shodan(),
PortScannerRanger(),
- Breacher()
+ Breacher(),
+ TheHarvester(),
+ Amass(),
+ Masscan(),
+ RustScan(),
+ Holehe(),
+ Maigret(),
+ Httpx(),
+ SpiderFoot(),
+ Subfinder(),
+ TruffleHog(),
+ Gitleaks(),
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Information Gathering Tools", show_lines=True, expand=True)
- table.add_column("Title", style=PURPLE_STYLE, no_wrap=True)
- table.add_column("Description", style=PURPLE_STYLE)
- table.add_column("Project URL", style=PURPLE_STYLE, no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc).replace("\n", " "), str(url))
-
- console.print(Panel(table, title=f"[magenta]Available Tools[/magenta]", border_style=PURPLE_STYLE))
-
- def show_options(self, parent=None):
- console.print("\n")
- console.print(Panel.fit(
- "[bold magenta]Information Gathering Collection[/bold magenta]\n"
- "Select a tool to view/run it or return to the previous menu.",
- border_style=PURPLE_STYLE
- ))
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # delegate to collection-style tools if available
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # if tool exposes actions/menu, try to call it
- elif hasattr(selected, "show_actions"):
- selected.show_actions(parent=self)
- # otherwise try to call run if present
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = InformationGatheringTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/mobile_security.py b/tools/mobile_security.py
new file mode 100644
index 0000000..ee9518f
--- /dev/null
+++ b/tools/mobile_security.py
@@ -0,0 +1,42 @@
+from core import HackingTool
+from core import HackingToolsCollection
+
+
+class MobSF(HackingTool):
+ TITLE = "MobSF (Mobile Security Framework)"
+ DESCRIPTION = "All-in-one mobile app pentesting, malware analysis, and security assessment."
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/MobSF/Mobile-Security-Framework-MobSF.git",
+ "cd Mobile-Security-Framework-MobSF && ./setup.sh",
+ ]
+ RUN_COMMANDS = ["cd Mobile-Security-Framework-MobSF && ./run.sh"]
+ PROJECT_URL = "https://github.com/MobSF/Mobile-Security-Framework-MobSF"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Frida(HackingTool):
+ TITLE = "Frida (Dynamic Instrumentation)"
+ DESCRIPTION = "Dynamic instrumentation toolkit for runtime hooking on Android, iOS, Windows, macOS, Linux."
+ INSTALL_COMMANDS = ["pip install --user frida-tools"]
+ RUN_COMMANDS = ["frida --help"]
+ PROJECT_URL = "https://github.com/frida/frida"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Objection(HackingTool):
+ TITLE = "Objection (Mobile Runtime Exploration)"
+ DESCRIPTION = "Runtime mobile exploration toolkit powered by Frida — no jailbreak/root required."
+ INSTALL_COMMANDS = ["pip install --user objection"]
+ RUN_COMMANDS = ["objection --help"]
+ PROJECT_URL = "https://github.com/sensepost/objection"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class MobileSecurityTools(HackingToolsCollection):
+ TITLE = "Mobile Security Tools"
+ DESCRIPTION = "Tools for Android/iOS application security testing and analysis."
+ TOOLS = [
+ MobSF(),
+ Frida(),
+ Objection(),
+ ]
\ No newline at end of file
diff --git a/tools/other_tools.py b/tools/other_tools.py
index c72d5d2..4e9f3ea 100644
--- a/tools/other_tools.py
+++ b/tools/other_tools.py
@@ -1,9 +1,7 @@
-# coding=utf-8
import os
import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
from tools.others.android_attack import AndroidAttackTools
from tools.others.email_verifier import EmailVerifyTools
from tools.others.hash_crack import HashCrackingTools
@@ -15,15 +13,9 @@ from tools.others.socialmedia_finder import SocialMediaFinderTools
from tools.others.web_crawling import WebCrawlingTools
from tools.others.wifi_jamming import WifiJammingTools
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class HatCloud(HackingTool):
TITLE = "HatCloud(Bypass CloudFlare for IP)"
@@ -33,9 +25,14 @@ class HatCloud(HackingTool):
PROJECT_URL = "https://github.com/HatBashBR/HatCloud"
def run(self):
- site = input("Enter Site >> ")
- os.chdir("HatCloud")
- subprocess.run(["sudo", "ruby", "hatcloud.rb", "-b", site])
+ from config import get_tools_dir
+ from rich.prompt import Prompt
+ site = Prompt.ask("Enter Site")
+ # Bug 3 fix: os.chdir() replaced with cwd= parameter
+ subprocess.run(
+ ["sudo", "ruby", "hatcloud.rb", "-b", site],
+ cwd=str(get_tools_dir() / "HatCloud"),
+ )
class OtherTools(HackingToolsCollection):
@@ -54,68 +51,6 @@ class OtherTools(HackingToolsCollection):
MixTools()
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Other Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc).strip().replace("\n", " "), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Other Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # If tool exposes show_options (collection-style), delegate to it
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # Otherwise, if runnable, call its run method
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = OtherTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/others/__init__.py b/tools/others/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/tools/others/android_attack.py b/tools/others/android_attack.py
index 8e536ef..c540fac 100644
--- a/tools/others/android_attack.py
+++ b/tools/others/android_attack.py
@@ -1,24 +1,17 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class Keydroid(HackingTool):
TITLE = "Keydroid"
DESCRIPTION = "Android Keylogger + Reverse Shell\n" \
"[!] You have to install Some Manually Refer Below Link:\n " \
"[+] https://github.com/F4dl0/keydroid"
- INSTALL_COMMANDS = ["sudo git clone https://github.com/F4dl0/keydroid.git"]
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["git clone https://github.com/F4dl0/keydroid.git"]
RUN_COMMANDS = ["cd keydroid && bash keydroid.sh"]
PROJECT_URL = "https://github.com/F4dl0/keydroid"
@@ -28,8 +21,9 @@ class MySMS(HackingTool):
DESCRIPTION = "Script that generates an Android App to hack SMS through WAN \n" \
"[!] You have to install Some Manually Refer Below Link:\n\t " \
"[+] https://github.com/papusingh2sms/mysms"
+ SUPPORTED_OS = ["linux"]
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/papusingh2sms/mysms.git"]
+ "git clone https://github.com/papusingh2sms/mysms.git"]
RUN_COMMANDS = ["cd mysms && bash mysms.sh"]
PROJECT_URL = "https://github.com/papusingh2sms/mysms"
@@ -39,8 +33,9 @@ class LockPhish(HackingTool):
DESCRIPTION = "Lockphish it's the first tool for phishing attacks on the " \
"lock screen, designed to\n Grab Windows credentials,Android" \
" PIN and iPhone Passcode using a https link."
+ SUPPORTED_OS = ["linux"]
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/JasonJerry/lockphish.git"]
+ "git clone https://github.com/JasonJerry/lockphish.git"]
RUN_COMMANDS = ["cd lockphish && bash lockphish.sh"]
PROJECT_URL = "https://github.com/JasonJerry/lockphish"
@@ -48,9 +43,11 @@ class LockPhish(HackingTool):
class Droidcam(HackingTool):
TITLE = "DroidCam (Capture Image)"
DESCRIPTION = "Powerful Tool For Grab Front Camera Snap Using A Link"
+ SUPPORTED_OS = ["linux"]
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/kinghacker0/WishFish.git;"
- "sudo apt install php wget openssh-client"
+ # Bug 16 fix: missing comma caused two strings to be implicitly concatenated into one
+ "git clone https://github.com/kinghacker0/WishFish.git",
+ "sudo apt install -y php wget openssh-client",
]
RUN_COMMANDS = ["cd WishFish && sudo bash wishfish.sh"]
PROJECT_URL = "https://github.com/kinghacker0/WishFish"
@@ -60,8 +57,9 @@ class EvilApp(HackingTool):
TITLE = "EvilApp (Hijack Session)"
DESCRIPTION = "EvilApp is a script to generate Android App that can " \
"hijack authenticated sessions in cookies."
+ SUPPORTED_OS = ["linux"]
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/crypticterminal/EvilApp.git"]
+ "git clone https://github.com/crypticterminal/EvilApp.git"]
RUN_COMMANDS = ["cd EvilApp && bash evilapp.sh"]
PROJECT_URL = "https://github.com/crypticterminal/EvilApp"
@@ -76,61 +74,6 @@ class AndroidAttackTools(HackingToolsCollection):
EvilApp()
]
- def pretty_print(self):
- table = Table(title="Android Attack Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Android Attack Tools Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = AndroidAttackTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/email_verifier.py b/tools/others/email_verifier.py
index 672df51..50d6edc 100644
--- a/tools/others/email_verifier.py
+++ b/tools/others/email_verifier.py
@@ -1,16 +1,8 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class KnockMail(HackingTool):
TITLE = "Knockmail"
@@ -27,61 +19,6 @@ class EmailVerifyTools(HackingToolsCollection):
TITLE = "Email Verify tools"
TOOLS = [KnockMail()]
- def pretty_print(self):
- table = Table(title="Email Verify Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Email Verify Tools Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = EmailVerifyTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/hash_crack.py b/tools/others/hash_crack.py
index 96651e7..390470c 100644
--- a/tools/others/hash_crack.py
+++ b/tools/others/hash_crack.py
@@ -1,17 +1,9 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class HashBuster(HackingTool):
TITLE = "Hash Buster"
@@ -30,61 +22,6 @@ class HashCrackingTools(HackingToolsCollection):
TITLE = "Hash cracking tools"
TOOLS = [HashBuster()]
- def pretty_print(self):
- table = Table(title="Hash Cracking Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Hash Cracking Tools Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = HashCrackingTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/others/homograph_attacks.py b/tools/others/homograph_attacks.py
index 4d9943d..9984366 100644
--- a/tools/others/homograph_attacks.py
+++ b/tools/others/homograph_attacks.py
@@ -1,17 +1,9 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class EvilURL(HackingTool):
TITLE = "EvilURL"
@@ -26,61 +18,6 @@ class IDNHomographAttackTools(HackingToolsCollection):
TITLE = "IDN Homograph Attack"
TOOLS = [EvilURL()]
- def pretty_print(self):
- table = Table(title="IDN Homograph Attack Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]IDN Homograph Attack Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = IDNHomographAttackTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/mix_tools.py b/tools/others/mix_tools.py
index 5f54f92..37c5dd4 100644
--- a/tools/others/mix_tools.py
+++ b/tools/others/mix_tools.py
@@ -1,43 +1,42 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class TerminalMultiplexer(HackingTool):
TITLE = "Terminal Multiplexer"
- DESCRIPTION = "Terminal Multiplexer is a tiling terminal emulator that " \
- "allows us to open \n several terminal sessions inside one " \
- "single window."
- INSTALL_COMMANDS = ["sudo apt-get install tilix"]
+ DESCRIPTION = (
+ "Terminal Multiplexer (tilix) is a tiling terminal emulator that "
+ "allows opening several terminal sessions inside one window."
+ )
+ # Bug 19 fix: tilix is a Debian/Ubuntu package only — mark Linux-only
+ INSTALL_COMMANDS = ["sudo apt-get install -y tilix"]
+ SUPPORTED_OS = ["linux"]
def __init__(self):
- super(TerminalMultiplexer, self).__init__(runnable = False)
+ # Py3-4 fix: super(TerminalMultiplexer, self) → super()
+ super().__init__(runnable=False)
class Crivo(HackingTool):
TITLE = "Crivo"
- DESCRIPTION = "A tool for extracting and filtering URLs, IPs, domains, " \
- "\n and subdomains from web pages or text, " \
- "with built-in web scraping capabilities.\n" \
- "See: python3 crivo_cli.py -h"
+ DESCRIPTION = (
+ "A tool for extracting and filtering URLs, IPs, domains, and subdomains\n"
+ "from web pages or text, with built-in web scraping capabilities.\n"
+ "See: python3 crivo_cli.py -h"
+ )
INSTALL_COMMANDS = [
"git clone https://github.com/GMDSantana/crivo.git",
- "cd crivo;pip install -r requirements.txt"
+ # Bug 18 verify: this is correct — cd and pip in same string works
+ "cd crivo && pip install --user -r requirements.txt",
]
PROJECT_URL = "https://github.com/GMDSantana/crivo"
def __init__(self):
- super(Crivo, self).__init__(runnable = False)
+ # Py3-4 fix: super(Crivo, self) → super()
+ super().__init__(runnable=False)
class MixTools(HackingToolsCollection):
@@ -47,61 +46,6 @@ class MixTools(HackingToolsCollection):
Crivo()
]
- def pretty_print(self):
- table = Table(title="Mix Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Mix Tools Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = MixTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/payload_injection.py b/tools/others/payload_injection.py
index b5c89b2..922e166 100644
--- a/tools/others/payload_injection.py
+++ b/tools/others/payload_injection.py
@@ -1,23 +1,15 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class DebInject(HackingTool):
TITLE = "Debinject"
DESCRIPTION = "Debinject is a tool that inject malicious code into *.debs"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/UndeadSec/Debinject.git"]
+ "git clone https://github.com/UndeadSec/Debinject.git"]
RUN_COMMANDS = ["cd Debinject;python debinject.py"]
PROJECT_URL = "https://github.com/UndeadSec/Debinject"
@@ -28,12 +20,12 @@ class Pixload(HackingTool):
"Pixload is Set of tools for creating/injecting payload into images."
INSTALL_COMMANDS = [
"sudo apt install libgd-perl libimage-exiftool-perl libstring-crc32-perl",
- "sudo git clone https://github.com/chinarulezzz/pixload.git"
+ "git clone https://github.com/chinarulezzz/pixload.git"
]
PROJECT_URL = "https://github.com/chinarulezzz/pixload"
def __init__(self):
- super(Pixload, self).__init__(runnable = False)
+ super().__init__(runnable = False)
class PayloadInjectorTools(HackingToolsCollection):
@@ -43,61 +35,6 @@ class PayloadInjectorTools(HackingToolsCollection):
Pixload()
]
- def pretty_print(self):
- table = Table(title="Payload Injector Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Payload Injector Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = PayloadInjectorTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/socialmedia.py b/tools/others/socialmedia.py
index 542f73a..b52e11b 100644
--- a/tools/others/socialmedia.py
+++ b/tools/others/socialmedia.py
@@ -1,38 +1,26 @@
-# coding=utf-8
import contextlib
import os
import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class InstaBrute(HackingTool):
TITLE = "Instagram Attack"
DESCRIPTION = "Brute force attack against Instagram"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/chinoogawa/instaBrute.git",
- "cd instaBrute;sudo pip2.7 install -r requirements.txt"
- ]
PROJECT_URL = "https://github.com/chinoogawa/instaBrute"
+ # Py3-7: Python 2 only (pip2.7); also violates Instagram ToS
+ ARCHIVED = True
+ ARCHIVED_REASON = "Python 2 only — EOL January 2020. Repo unmaintained since 2017."
+ INSTALL_COMMANDS = []
+ RUN_COMMANDS = []
- def run(self):
- name = input("Enter Username >> ")
- wordlist = input("Enter wordword list >> ")
- os.chdir("instaBrute")
- subprocess.run(
- ["sudo", "python", "instaBrute.py", "-u", f"{name}", "-d",
- f"{wordlist}"])
+ def __init__(self):
+ super().__init__(installable=False, runnable=False)
class BruteForce(HackingTool):
@@ -40,7 +28,7 @@ class BruteForce(HackingTool):
DESCRIPTION = "Brute_Force_Attack Gmail Hotmail Twitter Facebook Netflix \n" \
"[!] python3 Brute_Force.py -g -l "
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Matrix07ksa/Brute_Force.git",
+ "git clone https://github.com/Matrix07ksa/Brute_Force.git",
"cd Brute_Force;sudo pip3 install proxylist;pip3 install mechanize"
]
RUN_COMMANDS = ["cd Brute_Force;python3 Brute_Force.py -h"]
@@ -51,25 +39,27 @@ class Faceshell(HackingTool):
TITLE = "Facebook Attack"
DESCRIPTION = "Facebook BruteForcer"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Matrix07ksa/Brute_Force.git",
+ "git clone https://github.com/Matrix07ksa/Brute_Force.git",
"cd Brute_Force;sudo pip3 install proxylist;pip3 install mechanize"
]
PROJECT_URL = "https://github.com/Matrix07ksa/Brute_Force"
def run(self):
- name = input("Enter Username >> ")
- wordlist = input("Enter Wordlist >> ")
- with contextlib.suppress(FileNotFoundError):
- os.chdir("Brute_Force")
+ from config import get_tools_dir
+ name = Prompt.ask("Enter Username")
+ wordlist = Prompt.ask("Enter Wordlist path")
+ # Bug 3 fix: os.chdir() replaced with cwd= parameter
subprocess.run(
- ["python3", "Brute_Force.py", "-f", f"{name}", "-l", f"{wordlist}"])
+ ["python3", "Brute_Force.py", "-f", name, "-l", wordlist],
+ cwd=str(get_tools_dir() / "Brute_Force"),
+ )
class AppCheck(HackingTool):
TITLE = "Application Checker"
DESCRIPTION = "Tool to check if an app is installed on the target device through a link."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/jakuta-tech/underhanded.git",
+ "git clone https://github.com/jakuta-tech/underhanded.git",
"cd underhanded && sudo chmod +x underhanded.sh"
]
RUN_COMMANDS = ["cd underhanded;sudo bash underhanded.sh"]
@@ -85,61 +75,6 @@ class SocialMediaBruteforceTools(HackingToolsCollection):
AppCheck()
]
- def pretty_print(self):
- table = Table(title="Social Media Bruteforce Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Social Media Bruteforce Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = SocialMediaBruteforceTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/socialmedia_finder.py b/tools/others/socialmedia_finder.py
index 8172086..7645934 100644
--- a/tools/others/socialmedia_finder.py
+++ b/tools/others/socialmedia_finder.py
@@ -1,20 +1,12 @@
-# coding=utf-8
import os
import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class FacialFind(HackingTool):
TITLE = "Find SocialMedia By Facial Recognation System"
@@ -23,7 +15,7 @@ class FacialFind(HackingTool):
INSTALL_COMMANDS = [
"sudo apt install -y software-properties-common",
"sudo add-apt-repository ppa:mozillateam/firefox-next && sudo apt update && sudo apt upgrade",
- "sudo git clone https://github.com/Greenwolf/social_mapper.git",
+ "git clone https://github.com/Greenwolf/social_mapper.git",
"sudo apt install -y build-essential cmake libgtk-3-dev libboost-all-dev",
"cd social_mapper/setup",
"sudo python3 -m pip install --no-cache-dir -r requirements.txt",
@@ -36,21 +28,21 @@ class FacialFind(HackingTool):
PROJECT_URL = "https://github.com/Greenwolf/social_mapper"
def run(self):
- os.system("cd social_mapper/setup")
- os.system("sudo python social_mapper.py -h")
- print("""\033[95m
- You have to set Username and password of your AC Or Any Fack Account
- [#] Type in Terminal nano social_mapper.py
- """)
- os.system(
- 'echo "python social_mapper.py -f [] -i [] -m fast [] -fb -tw"| boxes | lolcat')
+ from config import get_tools_dir
+ import subprocess
+ setup_dir = get_tools_dir() / "social_mapper" / "setup"
+ subprocess.run(["python3", "social_mapper.py", "-h"], cwd=str(setup_dir))
+ console.print(
+ "[bold magenta]Set username and password in social_mapper.py before running.[/]\n"
+ "[magenta]Usage: python social_mapper.py -f -i -m fast -fb -tw[/]"
+ )
class FindUser(HackingTool):
TITLE = "Find SocialMedia By UserName"
DESCRIPTION = "Find usernames across over 75 social networks"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/xHak9x/finduser.git",
+ "git clone https://github.com/xHak9x/finduser.git",
"cd finduser && sudo chmod +x finduser.sh"
]
RUN_COMMANDS = ["cd finduser && sudo bash finduser.sh"]
@@ -69,16 +61,21 @@ class Sherlock(HackingTool):
PROJECT_URL = "https://github.com/sherlock-project/sherlock"
def run(self):
- name = input("Enter Username >> ")
- os.chdir('sherlock')
- subprocess.run(["sudo", "python3", "sherlock", f"{name}"])
+ from config import get_tools_dir
+ from rich.prompt import Prompt
+ name = Prompt.ask("Enter Username")
+ # Bug 3 fix: os.chdir() replaced with cwd= parameter
+ subprocess.run(
+ ["python3", "sherlock", name],
+ cwd=str(get_tools_dir() / "sherlock"),
+ )
class SocialScan(HackingTool):
TITLE = "SocialScan | Username or Email"
DESCRIPTION = "Check email address and username availability on online " \
"platforms with 100% accuracy"
- INSTALL_COMMANDS = ["sudo pip install socialscan"]
+ INSTALL_COMMANDS = ["pip install --user socialscan"]
PROJECT_URL = "https://github.com/iojw/socialscan"
def run(self):
@@ -96,61 +93,6 @@ class SocialMediaFinderTools(HackingToolsCollection):
SocialScan()
]
- def pretty_print(self):
- table = Table(title="Social Media Finder Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Social Media Finder Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = SocialMediaFinderTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/web_crawling.py b/tools/others/web_crawling.py
index 7cb610f..a55f721 100644
--- a/tools/others/web_crawling.py
+++ b/tools/others/web_crawling.py
@@ -1,17 +1,9 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class GoSpider(HackingTool):
TITLE = "Gospider"
@@ -20,68 +12,13 @@ class GoSpider(HackingTool):
PROJECT_URL = "https://github.com/jaeles-project/gospider"
def __init__(self):
- super(GoSpider, self).__init__(runnable = False)
+ super().__init__(runnable = False)
class WebCrawlingTools(HackingToolsCollection):
TITLE = "Web crawling"
TOOLS = [GoSpider()]
- def pretty_print(self):
- table = Table(title="Web Crawling Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Web Crawling Tools Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = WebCrawlingTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/others/wifi_jamming.py b/tools/others/wifi_jamming.py
index 55b20b8..5a31a61 100644
--- a/tools/others/wifi_jamming.py
+++ b/tools/others/wifi_jamming.py
@@ -1,28 +1,21 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
from rich import box
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class WifiJammerNG(HackingTool):
TITLE = "WifiJammer-NG"
DESCRIPTION = "Continuously jam all wifi clients and access points within range."
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/MisterBianco/wifijammer-ng.git",
- "cd wifijammer-ng;sudo pip install -r requirements.txt"
+ "git clone https://github.com/MisterBianco/wifijammer-ng.git",
+ "cd wifijammer-ng;pip install --user -r requirements.txt"
]
RUN_COMMANDS = [
- 'echo "python wifijammer.py [-a AP MAC] [-c CHANNEL] [-d] [-i INTERFACE] [-m MAXIMUM] [-k] [-p PACKETS] [-s SKIP] [-t TIME INTERVAL] [-D]"| boxes | lolcat',
- "cd wifijammer-ng;sudo python wifijammer.py"
+ "cd wifijammer-ng && sudo python3 wifijammer.py --help",
]
PROJECT_URL = "https://github.com/MisterBianco/wifijammer-ng"
@@ -31,8 +24,10 @@ class KawaiiDeauther(HackingTool):
TITLE = "KawaiiDeauther"
DESCRIPTION = "Kawaii Deauther is a pentest toolkit whose goal is to perform \n " \
"jam on WiFi clients/routers and spam many fake AP for testing purposes."
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/aryanrtm/KawaiiDeauther.git",
+ "git clone https://github.com/aryanrtm/KawaiiDeauther.git",
"cd KawaiiDeauther;sudo bash install.sh"
]
RUN_COMMANDS = ["cd KawaiiDeauther;sudo bash KawaiiDeauther.sh"]
@@ -46,61 +41,6 @@ class WifiJammingTools(HackingToolsCollection):
KawaiiDeauther()
]
- def pretty_print(self):
- table = Table(title="Wifi Jamming Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Wifi Jamming Tools Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_info"):
- selected.show_info()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = WifiJammingTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/payload_creator.py b/tools/payload_creator.py
index 28ba67a..58029a3 100644
--- a/tools/payload_creator.py
+++ b/tools/payload_creator.py
@@ -1,99 +1,106 @@
-# coding=utf-8
import os
+import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
-
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
-from rich.panel import Panel
-from rich.prompt import Prompt
-
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
+from core import HackingTool, HackingToolsCollection, console
class TheFatRat(HackingTool):
TITLE = "The FatRat"
- DESCRIPTION = "TheFatRat Provides An Easy way to create Backdoors and Payloads " \
- "which can bypass most anti-virus"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "TheFatRat provides an easy way to create backdoors and payloads "
+ "which can bypass most anti-virus."
+ )
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Screetsec/TheFatRat.git",
- "cd TheFatRat && sudo chmod +x setup.sh"
+ "git clone https://github.com/Screetsec/TheFatRat.git",
+ "cd TheFatRat && chmod +x setup.sh",
]
RUN_COMMANDS = ["cd TheFatRat && sudo bash setup.sh"]
PROJECT_URL = "https://github.com/Screetsec/TheFatRat"
def __init__(self):
- super(TheFatRat, self).__init__([
- ('Update', self.update),
- ('Troubleshoot', self.troubleshoot)
+ super().__init__([
+ ("Update", self.update),
+ ("Troubleshoot", self.troubleshoot),
])
def update(self):
- os.system("cd TheFatRat && bash update && chmod +x setup.sh && bash setup.sh")
+ from config import get_tools_dir
+ cwd = str(get_tools_dir() / "TheFatRat")
+ subprocess.run(["bash", "update"], cwd=cwd)
+ subprocess.run(["chmod", "+x", "setup.sh"], cwd=cwd)
+ subprocess.run(["bash", "setup.sh"], cwd=cwd)
def troubleshoot(self):
- os.system("cd TheFatRat && sudo chmod +x chk_tools && ./chk_tools")
+ from config import get_tools_dir
+ cwd = str(get_tools_dir() / "TheFatRat")
+ subprocess.run(["chmod", "+x", "chk_tools"], cwd=cwd)
+ subprocess.run(["./chk_tools"], cwd=cwd)
class Brutal(HackingTool):
TITLE = "Brutal"
- DESCRIPTION = "Brutal is a toolkit to quickly create various payloads, powershell attacks, " \
- "virus attacks and launch listener for a Human Interface Device"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "Brutal is a toolkit to quickly create various payloads, powershell attacks, "
+ "virus attacks and launch listener for a Human Interface Device."
+ )
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Screetsec/Brutal.git",
- "cd Brutal && sudo chmod +x Brutal.sh"
+ "git clone https://github.com/Screetsec/Brutal.git",
+ "cd Brutal && chmod +x Brutal.sh",
]
RUN_COMMANDS = ["cd Brutal && sudo bash Brutal.sh"]
PROJECT_URL = "https://github.com/Screetsec/Brutal"
def show_info(self):
- super(Brutal, self).show_info()
- console.print("""
-[!] Requirement
- >> Arduino Software (I used v1.6.7)
- >> TeensyDuino
- >> Linux udev rules
- >> Copy and paste the PaensyLib folder inside your Arduino libraries
-
-[!] Visit for Installation for Arduino:
- >> https://github.com/Screetsec/Brutal/wiki/Install-Requirements
-""")
+ super().show_info()
+ console.print(
+ "[bold cyan]Requirements:[/bold cyan]\n"
+ " - Arduino Software (v1.6.7+)\n"
+ " - TeensyDuino\n"
+ " - Linux udev rules\n"
+ " See: https://github.com/Screetsec/Brutal/wiki/Install-Requirements"
+ )
class Stitch(HackingTool):
TITLE = "Stitch"
- DESCRIPTION = "Stitch is Cross Platform Python Remote Administrator Tool\n" \
- "[!] Refer Below Link For Wins & Mac OS"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "Stitch is a Cross Platform Python Remote Administrator Tool.\n"
+ "[!] Refer to the project link for Windows & macOS support."
+ )
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/nathanlopez/Stitch.git",
- "cd Stitch && sudo pip install -r lnx_requirements.txt"
+ "git clone https://github.com/nathanlopez/Stitch.git",
+ "cd Stitch && pip install --user -r lnx_requirements.txt",
]
- RUN_COMMANDS = ["cd Stitch && sudo python main.py"]
+ RUN_COMMANDS = ["cd Stitch && sudo python3 main.py"]
PROJECT_URL = "https://nathanlopez.github.io/Stitch"
class MSFVenom(HackingTool):
TITLE = "MSFvenom Payload Creator"
- DESCRIPTION = "MSFvenom Payload Creator (MSFPC) is a wrapper to generate multiple types of payloads, " \
- "based on user choice. Simplifies payload creation."
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "MSFvenom Payload Creator (MSFPC) is a wrapper to generate multiple "
+ "types of payloads, based on user choice."
+ )
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/g0tmi1k/msfpc.git",
- "cd msfpc;sudo chmod +x msfpc.sh"
+ "git clone https://github.com/g0tmi1k/msfpc.git",
+ "cd msfpc && chmod +x msfpc.sh",
]
- RUN_COMMANDS = ["cd msfpc;sudo bash msfpc.sh -h -v"]
+ RUN_COMMANDS = ["cd msfpc && sudo bash msfpc.sh -h -v"]
PROJECT_URL = "https://github.com/g0tmi1k/msfpc"
class Venom(HackingTool):
TITLE = "Venom Shellcode Generator"
- DESCRIPTION = "Venom 1.0.11 (malicious_server) exploits apache2 webserver to deliver LAN payloads via fake webpages."
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Venom exploits apache2 webserver to deliver LAN payloads via fake webpages."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/r00t-3xp10it/venom.git",
+ "git clone https://github.com/r00t-3xp10it/venom.git",
+ # Removed "sudo ./venom.sh -u" from install — interactive, runs the tool during install
"sudo chmod -R 775 venom*/ && cd venom*/ && cd aux && sudo bash setup.sh",
- "sudo ./venom.sh -u"
]
RUN_COMMANDS = ["cd venom && sudo ./venom.sh"]
PROJECT_URL = "https://github.com/r00t-3xp10it/venom"
@@ -101,10 +108,10 @@ class Venom(HackingTool):
class Spycam(HackingTool):
TITLE = "Spycam"
- DESCRIPTION = "Generates a Win32 payload that captures webcam images every 1 minute and sends them to the attacker."
+ DESCRIPTION = "Generates a Win32 payload that captures webcam images every 1 minute."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/indexnotfound404/spycam.git",
- "cd spycam && bash install.sh && chmod +x spycam"
+ "git clone https://github.com/indexnotfound404/spycam.git",
+ "cd spycam && bash install.sh && chmod +x spycam",
]
RUN_COMMANDS = ["cd spycam && ./spycam"]
PROJECT_URL = "https://github.com/indexnotfound404/spycam"
@@ -112,26 +119,26 @@ class Spycam(HackingTool):
class MobDroid(HackingTool):
TITLE = "Mob-Droid"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "Generates metasploit payloads easily without typing long commands."
- INSTALL_COMMANDS = [
- "git clone https://github.com/kinghacker0/mob-droid.git"
- ]
- RUN_COMMANDS = ["cd mob-droid;sudo python mob-droid.py"]
+ INSTALL_COMMANDS = ["git clone https://github.com/kinghacker0/mob-droid.git"]
+ RUN_COMMANDS = ["cd mob-droid && sudo python3 mob-droid.py"]
PROJECT_URL = "https://github.com/kinghacker0/Mob-Droid"
class Enigma(HackingTool):
TITLE = "Enigma"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "Enigma is a Multiplatform payload dropper."
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/UndeadSec/Enigma.git"
- ]
- RUN_COMMANDS = ["cd Enigma;sudo python enigma.py"]
+ INSTALL_COMMANDS = ["git clone https://github.com/UndeadSec/Enigma.git"]
+ RUN_COMMANDS = ["cd Enigma && sudo python3 enigma.py"]
PROJECT_URL = "https://github.com/UndeadSec/Enigma"
class PayloadCreatorTools(HackingToolsCollection):
TITLE = "Payload creation tools"
+ # Bug 11 fix: show_options() override was missing `parent` parameter entirely —
+ # the whole override is now deleted and the base class method is used instead.
TOOLS = [
TheFatRat(),
Brutal(),
@@ -140,62 +147,10 @@ class PayloadCreatorTools(HackingToolsCollection):
Venom(),
Spycam(),
MobDroid(),
- Enigma()
+ Enigma(),
]
- def pretty_print(self):
- table = Table(title="Payload Creation Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- console.print(Panel(table, title="[purple]Available Tools[/purple]", border_style="purple"))
-
- def show_options(self):
- console.print("\n")
- console.print(Panel.fit(
- "[bold purple]Payload Creator Collection[/bold purple]\n"
- "Select a tool to run it or exit.",
- border_style="purple"
- ))
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- desc = getattr(tool, "DESCRIPTION", "") or "—"
- table.add_row(str(i + 1), tool.TITLE, desc.replace("\n", " "))
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "show_actions"):
- selected.show_actions()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
-
- return self.show_options()
-
if __name__ == "__main__":
tools = PayloadCreatorTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/phishing_attack.py b/tools/phishing_attack.py
new file mode 100644
index 0000000..7fb875f
--- /dev/null
+++ b/tools/phishing_attack.py
@@ -0,0 +1,256 @@
+import os
+
+from core import HackingTool, HackingToolsCollection, console
+
+
+class Autophisher(HackingTool):
+ TITLE = "Autophisher RK"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Automated Phishing Toolkit"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/CodingRanjith/autophisher.git",
+ ]
+ RUN_COMMANDS = ["cd autophisher && sudo bash autophisher.sh"]
+ PROJECT_URL = "https://github.com/CodingRanjith/autophisher"
+
+
+class Pyphisher(HackingTool):
+ TITLE = "Pyphisher"
+ DESCRIPTION = "Easy to use phishing tool with 77 website templates"
+ # Bug 9 fix: pip must reference the full path, not rely on a no-op "cd" call
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/KasRoudra/PyPhisher",
+ "pip3 install --user -r PyPhisher/files/requirements.txt",
+ ]
+ RUN_COMMANDS = ["cd PyPhisher && sudo python3 pyphisher.py"]
+ # Bug 8 fix: PROJECT_URL was a git clone command, not a URL
+ PROJECT_URL = "https://github.com/KasRoudra/PyPhisher"
+
+
+class AdvPhishing(HackingTool):
+ TITLE = "AdvPhishing"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "This is Advance Phishing Tool ! OTP PHISHING"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/Ignitetch/AdvPhishing.git",
+ # Vuln 2 fix: chmod 777 → chmod +x
+ "cd AdvPhishing && chmod +x Linux-Setup.sh && bash Linux-Setup.sh",
+ ]
+ RUN_COMMANDS = ["cd AdvPhishing && sudo bash AdvPhishing.sh"]
+ PROJECT_URL = "https://github.com/Ignitetch/AdvPhishing"
+
+
+class Setoolkit(HackingTool):
+ TITLE = "Setoolkit"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "The Social-Engineer Toolkit is an open-source penetration\n"
+ "testing framework designed for social engineering."
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/trustedsec/social-engineer-toolkit/",
+ "cd social-engineer-toolkit && pip install --user .",
+ ]
+ RUN_COMMANDS = ["sudo setoolkit"]
+ PROJECT_URL = "https://github.com/trustedsec/social-engineer-toolkit"
+
+
+class SocialFish(HackingTool):
+ TITLE = "SocialFish"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Automated Phishing Tool & Information Collector NOTE: username is 'root' and password is 'pass'"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/UndeadSec/SocialFish.git && sudo apt-get install python3 python3-pip python3-dev -y",
+ "cd SocialFish && sudo python3 -m pip install -r requirements.txt",
+ ]
+ RUN_COMMANDS = ["cd SocialFish && sudo python3 SocialFish.py root pass"]
+ PROJECT_URL = "https://github.com/UndeadSec/SocialFish"
+
+
+class HiddenEye(HackingTool):
+ TITLE = "HiddenEye"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "Modern Phishing Tool With Advanced Functionality And Multiple Tunnelling Services\n"
+ "\t[!] https://github.com/DarkSecDevelopers/HiddenEye"
+ )
+ INSTALL_COMMANDS = [
+ # Vuln 2 fix: chmod 777 → chmod 755
+ "git clone https://github.com/Morsmalleo/HiddenEye.git && chmod -R 755 HiddenEye",
+ "cd HiddenEye && sudo pip3 install -r requirements.txt && pip3 install pyngrok",
+ ]
+ RUN_COMMANDS = ["cd HiddenEye && sudo python3 HiddenEye.py"]
+ PROJECT_URL = "https://github.com/Morsmalleo/HiddenEye"
+
+
+class Evilginx3(HackingTool):
+ TITLE = "Evilginx3"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "evilginx is a man-in-the-middle attack framework used for phishing login credentials\n"
+ "along with session cookies, bypassing 2-factor authentication.\n"
+ "Requires Go >= 1.18 installed."
+ )
+ # Bug 6 fix: removed 'sudo evilginx' (interactive) from INSTALL_COMMANDS
+ INSTALL_COMMANDS = [
+ "sudo apt-get install -y git make golang-go",
+ "go install github.com/kgretzky/evilginx/v3@latest",
+ ]
+ RUN_COMMANDS = ["evilginx"]
+ PROJECT_URL = "https://github.com/kgretzky/evilginx2"
+ REQUIRES_GO = True
+
+
+class ISeeYou(HackingTool):
+ TITLE = "I-See_You"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = (
+ "[!] ISeeYou finds the exact location of a target via social engineering.\n"
+ "[!] Expose local servers to the internet and decode location from log file."
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/Viralmaniar/I-See-You.git",
+ "cd I-See-You && sudo chmod u+x ISeeYou.sh",
+ ]
+ RUN_COMMANDS = ["cd I-See-You && sudo bash ISeeYou.sh"]
+ PROJECT_URL = "https://github.com/Viralmaniar/I-See-You"
+
+
+class SayCheese(HackingTool):
+ TITLE = "SayCheese"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Take webcam shots from target just by sending a malicious link"
+ INSTALL_COMMANDS = ["git clone https://github.com/hangetzzu/saycheese"]
+ RUN_COMMANDS = ["cd saycheese && sudo bash saycheese.sh"]
+ PROJECT_URL = "https://github.com/hangetzzu/saycheese"
+
+
+class QRJacking(HackingTool):
+ TITLE = "QR Code Jacking"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "QR Code Jacking (Any Website)"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/cryptedwolf/ohmyqr.git && sudo apt -y install scrot",
+ ]
+ RUN_COMMANDS = ["cd ohmyqr && sudo bash ohmyqr.sh"]
+ PROJECT_URL = "https://github.com/cryptedwolf/ohmyqr"
+
+
+# Bug 10 fix: WifiPhisher removed from phishing tools — it belongs in wireless_attack.py
+
+
+class BlackEye(HackingTool):
+ TITLE = "BlackEye"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "The ultimate phishing tool with 38 websites available!"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/thelinuxchoice/blackeye",
+ ]
+ RUN_COMMANDS = ["cd blackeye && sudo bash blackeye.sh"]
+ PROJECT_URL = "https://github.com/An0nUD4Y/blackeye"
+
+
+class ShellPhish(HackingTool):
+ TITLE = "ShellPhish"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Phishing Tool for 18 social media"
+ INSTALL_COMMANDS = ["git clone https://github.com/An0nUD4Y/shellphish.git"]
+ RUN_COMMANDS = ["cd shellphish && sudo bash shellphish.sh"]
+ PROJECT_URL = "https://github.com/An0nUD4Y/shellphish"
+
+
+class Thanos(HackingTool):
+ TITLE = "Thanos"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Browser to Browser Phishing toolkit"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/TridevReddy/Thanos.git",
+ # Vuln 2 fix: chmod -R 777 → chmod +x
+ "cd Thanos && chmod +x Thanos.sh",
+ ]
+ RUN_COMMANDS = ["cd Thanos && sudo bash Thanos.sh"]
+ PROJECT_URL = "https://github.com/TridevReddy/Thanos"
+
+
+class QRLJacking(HackingTool):
+ TITLE = "QRLJacking"
+ DESCRIPTION = "QRLJacking — session hijacking attack vector targeting QR code based login"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/OWASP/QRLJacking.git",
+ # Bug fix: geckodriver must be fetched as a binary, not cloned from source
+ "GECKO_VER=$(curl -s https://api.github.com/repos/mozilla/geckodriver/releases/latest | grep tag_name | cut -d '\"' -f4) && "
+ "wget -q https://github.com/mozilla/geckodriver/releases/download/$GECKO_VER/geckodriver-$GECKO_VER-linux64.tar.gz -O /tmp/geckodriver.tar.gz && "
+ "tar -xzf /tmp/geckodriver.tar.gz -C /tmp && sudo mv /tmp/geckodriver /usr/local/bin/",
+ "cd QRLJacking && pip3 install --user -r QRLJacker/requirements.txt",
+ ]
+ RUN_COMMANDS = ["cd QRLJacking/QRLJacker && python3 QrlJacker.py"]
+ PROJECT_URL = "https://github.com/OWASP/QRLJacking"
+
+
+class Maskphish(HackingTool):
+ TITLE = "Maskphish"
+ SUPPORTED_OS = ["linux"]
+ DESCRIPTION = "Hide phishing URL under a normal looking URL (google.com or facebook.com)"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/jaykali/maskphish.git",
+ ]
+ RUN_COMMANDS = ["cd maskphish && sudo bash maskphish.sh"]
+ PROJECT_URL = "https://github.com/jaykali/maskphish"
+
+
+class BlackPhish(HackingTool):
+ TITLE = "BlackPhish"
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/iinc0gnit0/BlackPhish.git",
+ "cd BlackPhish && sudo bash install.sh",
+ ]
+ RUN_COMMANDS = ["cd BlackPhish && sudo python3 blackphish.py"]
+ PROJECT_URL = "https://github.com/iinc0gnit0/BlackPhish"
+
+ def __init__(self):
+ # Bug fix: super() Python 3 style
+ super().__init__([("Update", self.update)])
+
+ def update(self):
+ import subprocess
+ from config import get_tools_dir
+ subprocess.run(["bash", "update.sh"], cwd=str(get_tools_dir() / "BlackPhish"))
+
+
+class Dnstwist(HackingTool):
+ # Bug 2 fix: all attributes were wrong case (Title, Install_commands, etc.)
+ # They are now the correct uppercase names the base class reads.
+ TITLE = "dnstwist"
+ DESCRIPTION = "Domain name permutation engine for detecting typosquatting, phishing and brand impersonation"
+ INSTALL_COMMANDS = ["pip3 install --user dnstwist"]
+ RUN_COMMANDS = ["dnstwist --help"]
+ PROJECT_URL = "https://github.com/elceef/dnstwist"
+
+
+class PhishingAttackTools(HackingToolsCollection):
+ TITLE = "Phishing attack tools"
+ TOOLS = [
+ Autophisher(),
+ Pyphisher(),
+ AdvPhishing(),
+ Setoolkit(),
+ SocialFish(),
+ HiddenEye(),
+ Evilginx3(),
+ ISeeYou(),
+ SayCheese(),
+ QRJacking(),
+ BlackEye(),
+ ShellPhish(),
+ Thanos(),
+ QRLJacking(),
+ BlackPhish(),
+ Maskphish(),
+ Dnstwist(),
+ ]
+
+
+if __name__ == "__main__":
+ tools = PhishingAttackTools()
+ tools.show_options()
diff --git a/tools/phising_attack.py b/tools/phising_attack.py
deleted file mode 100644
index fc90cdd..0000000
--- a/tools/phising_attack.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# coding=utf-8
-import os
-
-from core import HackingTool
-from core import HackingToolsCollection
-
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
-from rich.panel import Panel
-from rich.prompt import Prompt
-
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
-
-class autophisher(HackingTool):
- TITLE = "Autophisher RK"
- DESCRIPTION = "Automated Phishing Toolkit"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/CodingRanjith/autophisher.git",
- "cd autophisher"
- ]
- RUN_COMMANDS = ["cd autophisher;sudo bash autophisher.sh"]
- PROJECT_URL = "https://github.com/CodingRanjith/autophisher"
-
-
-class Pyphisher(HackingTool):
- TITLE = "Pyphisher"
- DESCRIPTION = "Easy to use phishing tool with 77 website templates"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/KasRoudra/PyPhisher",
- "cd PyPhisher/files",
- "pip3 install -r requirements.txt"
- ]
- RUN_COMMANDS = ["cd PyPhisher;sudo python3 pyphisher.py"]
- PROJECT_URL = "git clone https://github.com/KasRoudra/PyPhisher"
-
-
-class AdvPhishing(HackingTool):
- TITLE = "AdvPhishing"
- DESCRIPTION = "This is Advance Phishing Tool ! OTP PHISHING"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Ignitetch/AdvPhishing.git",
- "cd AdvPhishing;chmod 777 *;bash Linux-Setup.sh"]
- RUN_COMMANDS = ["cd AdvPhishing && sudo bash AdvPhishing.sh"]
- PROJECT_URL = "https://github.com/Ignitetch/AdvPhishing"
-
-
-class Setoolkit(HackingTool):
- TITLE = "Setoolkit"
- DESCRIPTION = "The Social-Engineer Toolkit is an open-source penetration\n" \
- "testing framework designed for social engine"
- INSTALL_COMMANDS = [
- "git clone https://github.com/trustedsec/social-engineer-toolkit/",
- "cd social-engineer-toolkit && sudo python3 setup.py"
- ]
- RUN_COMMANDS = ["sudo setoolkit"]
- PROJECT_URL = "https://github.com/trustedsec/social-engineer-toolkit"
-
-
-class SocialFish(HackingTool):
- TITLE = "SocialFish"
- DESCRIPTION = "Automated Phishing Tool & Information Collector NOTE: username is 'root' and password is 'pass'"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/UndeadSec/SocialFish.git && sudo apt-get install python3 python3-pip python3-dev -y",
- "cd SocialFish && sudo python3 -m pip install -r requirements.txt"
- ]
- RUN_COMMANDS = ["cd SocialFish && sudo python3 SocialFish.py root pass"]
- PROJECT_URL = "https://github.com/UndeadSec/SocialFish"
-
-
-class HiddenEye(HackingTool):
- TITLE = "HiddenEye"
- DESCRIPTION = "Modern Phishing Tool With Advanced Functionality And " \
- "Multiple Tunnelling Services \n" \
- "\t [!]https://github.com/DarkSecDevelopers/HiddenEye"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Morsmalleo/HiddenEye.git ;sudo chmod 777 HiddenEye",
- "cd HiddenEye;sudo pip3 install -r requirements.txt;sudo pip3 install requests;pip3 install pyngrok"
- ]
- RUN_COMMANDS = ["cd HiddenEye;sudo python3 HiddenEye.py"]
- PROJECT_URL = "https://github.com/Morsmalleo/HiddenEye.git"
-
-
-class Evilginx2(HackingTool):
- TITLE = "Evilginx2"
- DESCRIPTION = "evilginx2 is a man-in-the-middle attack framework used " \
- "for phishing login credentials along with session cookies,\n" \
- "which in turn allows to bypass 2-factor authentication protection.\n\n\t " \
- "[+]Make sure you have installed GO of version at least 1.14.0 \n" \
- "[+]After installation, add this to your ~/.profile, assuming that you installed GO in /usr/local/go\n\t " \
- "[+]export GOPATH=$HOME/go \n " \
- "[+]export PATH=$PATH:/usr/local/go/bin:$GOPATH/bin \n" \
- "[+]Then load it with source ~/.profiles."
- INSTALL_COMMANDS = [
- "sudo apt-get install git make;go get -u github.com/kgretzky/evilginx2",
- "cd $GOPATH/src/github.com/kgretzky/evilginx2;make",
- "sudo make install;sudo evilginx"
- ]
- RUN_COMMANDS = ["sudo evilginx"]
- PROJECT_URL = "https://github.com/kgretzky/evilginx2"
-
-
-class ISeeYou(HackingTool):
- TITLE = "I-See_You"
- DESCRIPTION = "[!] ISeeYou is a tool to find Exact Location of Victom By" \
- " User SocialEngineering or Phishing Engagement..\n" \
- "[!] Users can expose their local servers to the Internet " \
- "and decode the location coordinates by looking at the log file"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Viralmaniar/I-See-You.git",
- "cd I-See-You && sudo chmod u+x ISeeYou.sh"
- ]
- RUN_COMMANDS = ["cd I-See-You && sudo bash ISeeYou.sh"]
- PROJECT_URL = "https://github.com/Viralmaniar/I-See-You"
-
-
-class SayCheese(HackingTool):
- TITLE = "SayCheese"
- DESCRIPTION = "Take webcam shots from target just sending a malicious link"
- INSTALL_COMMANDS = ["sudo git clone https://github.com/hangetzzu/saycheese"]
- RUN_COMMANDS = ["cd saycheese && sudo bash saycheese.sh"]
- PROJECT_URL = "https://github.com/hangetzzu/saycheese"
-
-
-class QRJacking(HackingTool):
- TITLE = "QR Code Jacking"
- DESCRIPTION = "QR Code Jacking (Any Website)"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/cryptedwolf/ohmyqr.git && sudo apt -y install scrot"]
- RUN_COMMANDS = ["cd ohmyqr && sudo bash ohmyqr.sh"]
- PROJECT_URL = "https://github.com/cryptedwolf/ohmyqr"
-
-
-class WifiPhisher(HackingTool):
- TITLE = "WifiPhisher"
- DESCRIPTION = "The Rogue Access Point Framework"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/wifiphisher/wifiphisher.git",
- "cd wifiphisher"]
- RUN_COMMANDS = ["cd wifiphisher && sudo python setup.py"]
- PROJECT_URL = "https://github.com/wifiphisher/wifiphisher"
-
-
-class BlackEye(HackingTool):
- TITLE = "BlackEye"
- DESCRIPTION = "The ultimate phishing tool with 38 websites available!"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/thelinuxchoice/blackeye",
- "cd blackeye "]
- RUN_COMMANDS = ["cd blackeye && sudo bash blackeye.sh"]
- PROJECT_URL = "https://github.com/An0nUD4Y/blackeye"
-
-
-class ShellPhish(HackingTool):
- TITLE = "ShellPhish"
- DESCRIPTION = "Phishing Tool for 18 social media"
- INSTALL_COMMANDS = ["git clone https://github.com/An0nUD4Y/shellphish.git"]
- RUN_COMMANDS = ["cd shellphish;sudo bash shellphish.sh"]
- PROJECT_URL = "https://github.com/An0nUD4Y/shellphish"
-
-
-class Thanos(HackingTool):
- TITLE = "Thanos"
- DESCRIPTION = "Browser to Browser Phishingtoolkit"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/TridevReddy/Thanos.git",
- "cd Thanos && sudo chmod -R 777 Thanos.sh"
- ]
- RUN_COMMANDS = ["cd Thanos;sudo bash Thanos.sh"]
- PROJECT_URL = "https://github.com/TridevReddy/Thanos"
-
-
-class QRLJacking(HackingTool):
- TITLE = "QRLJacking"
- DESCRIPTION = "QRLJacking"
- INSTALL_COMMANDS = [
- "git clone https://github.com/OWASP/QRLJacking.git",
- "cd QRLJacking",
- "git clone https://github.com/mozilla/geckodriver.git",
- "chmod +x geckodriver",
- "sudo mv -f geckodriver /usr/local/share/geckodriver",
- "sudo ln -s /usr/local/share/geckodriver /usr/local/bin/geckodriver",
- "sudo ln -s /usr/local/share/geckodriver /usr/bin/geckodriver",
- "cd QRLJacker;pip3 install -r requirements.txt"
- ]
- RUN_COMMANDS = ["cd QRLJacking/QRLJacker;python3 QrlJacker.py"]
- PROJECT_URL = "https://github.com/OWASP/QRLJacking"
-
-
-class Maskphish(HackingTool):
- TITLE = "Miskphish"
- DESCRIPTION = "Hide phishing URL under a normal looking URL (google.com or facebook.com)"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/jaykali/maskphish.git",
- "cd maskphish"]
- RUN_COMMANDS = ["cd maskphish;sudo bash maskphish.sh"]
- PROJECT_URL = "https://github.com/jaykali/maskphish"
-
-
-class BlackPhish(HackingTool):
- TITLE = "BlackPhish"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/iinc0gnit0/BlackPhish.git",
- "cd BlackPhish;sudo bash install.sh"
- ]
- RUN_COMMANDS = ["cd BlackPhish;sudo python3 blackphish.py"]
- PROJECT_URL = "https://github.com/iinc0gnit0/BlackPhish"
-
- def __init__(self):
- super(BlackPhish, self).__init__([('Update', self.update)])
-
- def update(self):
- os.system("cd BlackPhish;sudo bash update.sh")
-
-
-class dnstwist(HackingTool):
- Title = 'dnstwist'
- Install_commands = ['sudo git clone https://github.com/elceef/dnstwist.git','cd dnstwist']
- Run_commands = ['cd dnstwist;sudo python3 dnstwist.py']
- project_url = 'https://github.com/elceef/dnstwist'
-
-
-class PhishingAttackTools(HackingToolsCollection):
- TITLE = "Phishing attack tools"
- TOOLS = [
- autophisher(),
- Pyphisher(),
- AdvPhishing(),
- Setoolkit(),
- SocialFish(),
- HiddenEye(),
- Evilginx2(),
- ISeeYou(),
- SayCheese(),
- QRJacking(),
- BlackEye(),
- ShellPhish(),
- Thanos(),
- QRLJacking(),
- BlackPhish(),
- Maskphish(),
- dnstwist()
- ]
-
- def _get_attr_fallback(self, item, *names, default=""):
- for n in names:
- if hasattr(item, n):
- return getattr(item, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Phishing Attack Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- # try typical attribute names, then fall back to common variations
- title = (
- self._get_attr_fallback(t, "TITLE", "Title", "title")
- or t.__class__.__name__
- )
- desc = self._get_attr_fallback(t, "DESCRIPTION", "Description", "description", "INSTALL_COMMANDS", default="") or ""
- # prefer PROJECT_URL but also accept project_url or project_url-like fields
- url = self._get_attr_fallback(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="") or ""
- table.add_row(str(title), str(desc).strip().replace("\n", " "), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Phishing Attack Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr_fallback(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr_fallback(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # If tool exposes show_options (collection-style), delegate to it
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # Otherwise, if runnable, call its run method
- elif hasattr(selected, "run"):
- selected.run()
- # Preserve any before_run hooks if present
- elif hasattr(selected, "before_run"):
- selected.before_run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
-if __name__ == "__main__":
- tools = PhishingAttackTools()
- tools.pretty_print()
- tools.show_options()
diff --git a/tools/post_exploitation.py b/tools/post_exploitation.py
index c1cd3a9..4c2047e 100644
--- a/tools/post_exploitation.py
+++ b/tools/post_exploitation.py
@@ -1,122 +1,156 @@
-# coding=utf-8
import os
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class Vegile(HackingTool):
TITLE = "Vegile - Ghost In The Shell"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "This tool will set up your backdoor/rootkits when " \
"backdoor is already setup it will be \n" \
"hidden your specific process,unlimited your session in " \
"metasploit and transparent."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Screetsec/Vegile.git",
+ "git clone https://github.com/Screetsec/Vegile.git",
"cd Vegile && sudo chmod +x Vegile"
]
RUN_COMMANDS = ["cd Vegile && sudo bash Vegile"]
PROJECT_URL = "https://github.com/Screetsec/Vegile"
def before_run(self):
- os.system('echo "You can Use Command: \n'
- '[!] Vegile -i / --inject [backdoor/rootkit] \n'
- '[!] Vegile -u / --unlimited [backdoor/rootkit] \n'
- '[!] Vegile -h / --help"|boxes -d parchment')
+ console.print(
+ "[bold magenta]Vegile commands:[/]\n"
+ " Vegile -i / --inject [backdoor/rootkit]\n"
+ " Vegile -u / --unlimited [backdoor/rootkit]\n"
+ " Vegile -h / --help"
+ )
class ChromeKeyLogger(HackingTool):
TITLE = "Chrome Keylogger"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "Hera Chrome Keylogger"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/UndeadSec/HeraKeylogger.git",
+ "git clone https://github.com/UndeadSec/HeraKeylogger.git",
"cd HeraKeylogger && sudo apt-get install python3-pip -y && sudo pip3 install -r requirements.txt"
]
RUN_COMMANDS = ["cd HeraKeylogger && sudo python3 hera.py"]
PROJECT_URL = "https://github.com/UndeadSec/HeraKeylogger"
+class PwncatCS(HackingTool):
+ TITLE = "pwncat-cs (Reverse Shell Handler)"
+ DESCRIPTION = (
+ "Post-exploitation platform — manages reverse/bind shells with automation.\n"
+ "Handles file upload/download, persistence, privilege escalation.\n"
+ "Usage: pwncat-cs -lp 4444"
+ )
+ SUPPORTED_OS = ["linux", "macos"]
+ INSTALL_COMMANDS = ["pip install --user pwncat-cs"]
+ RUN_COMMANDS = ["pwncat-cs --help"]
+ PROJECT_URL = "https://github.com/calebstewart/pwncat"
+
+
+class Sliver(HackingTool):
+ TITLE = "Sliver (C2 Framework)"
+ DESCRIPTION = "Cross-platform adversary emulation/red team C2 framework — mTLS, HTTP(S), DNS, WireGuard."
+ INSTALL_COMMANDS = [
+ "curl -sSf https://sliver.sh/install -o /tmp/sliver-install.sh",
+ "sudo bash /tmp/sliver-install.sh",
+ ]
+ RUN_COMMANDS = ["sliver --help"]
+ PROJECT_URL = "https://github.com/BishopFox/sliver"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Havoc(HackingTool):
+ TITLE = "Havoc (C2 Framework)"
+ DESCRIPTION = "Modern post-exploitation C2 framework with EDR evasion. Cobalt Strike alternative."
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/HavocFramework/Havoc.git",
+ "cd Havoc && make",
+ ]
+ RUN_COMMANDS = ["cd Havoc && ./havoc --help"]
+ PROJECT_URL = "https://github.com/HavocFramework/Havoc"
+ SUPPORTED_OS = ["linux"]
+
+
+class PEASSng(HackingTool):
+ TITLE = "PEASS-ng — LinPEAS/WinPEAS (Priv Esc)"
+ DESCRIPTION = "Privilege escalation enumeration scripts for Linux and Windows."
+ INSTALL_COMMANDS = [
+ "curl -sSL https://github.com/peass-ng/PEASS-ng/releases/latest/download/linpeas.sh -o linpeas.sh",
+ "chmod +x linpeas.sh",
+ ]
+ RUN_COMMANDS = ["./linpeas.sh --help"]
+ PROJECT_URL = "https://github.com/peass-ng/PEASS-ng"
+
+
+class LigoloNg(HackingTool):
+ TITLE = "Ligolo-ng (Tunneling/Pivoting)"
+ DESCRIPTION = "Advanced tunneling/pivoting tool using TUN interfaces — no SOCKS needed."
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install github.com/nicocha30/ligolo-ng@latest",
+ ]
+ RUN_COMMANDS = ["ligolo-ng --help"]
+ PROJECT_URL = "https://github.com/nicocha30/ligolo-ng"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class ChiselTunnel(HackingTool):
+ TITLE = "Chisel (HTTP Tunnel)"
+ DESCRIPTION = "Fast TCP/UDP tunnel over HTTP, secured via SSH — pivoting and port forwarding."
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install github.com/jpillora/chisel@latest",
+ ]
+ RUN_COMMANDS = ["chisel --help"]
+ PROJECT_URL = "https://github.com/jpillora/chisel"
+
+
+class EvilWinRM(HackingTool):
+ TITLE = "Evil-WinRM (Windows Remote Shell)"
+ DESCRIPTION = "Ultimate WinRM shell for hacking/pentesting Windows machines."
+ REQUIRES_RUBY = True
+ INSTALL_COMMANDS = ["gem install evil-winrm"]
+ RUN_COMMANDS = ["evil-winrm --help"]
+ PROJECT_URL = "https://github.com/Hackplayers/evil-winrm"
+ SUPPORTED_OS = ["linux"]
+
+
+class Mythic(HackingTool):
+ TITLE = "Mythic (C2 Platform)"
+ DESCRIPTION = "Collaborative, multi-payload C2 platform designed for red team operations."
+ REQUIRES_DOCKER = True
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/its-a-feature/Mythic.git",
+ "cd Mythic && sudo make",
+ ]
+ RUN_COMMANDS = ["cd Mythic && sudo ./mythic-cli start"]
+ PROJECT_URL = "https://github.com/its-a-feature/Mythic"
+ SUPPORTED_OS = ["linux"]
+
+
class PostExploitationTools(HackingToolsCollection):
TITLE = "Post exploitation tools"
TOOLS = [
Vegile(),
- ChromeKeyLogger()
+ ChromeKeyLogger(),
+ PwncatCS(),
+ Sliver(),
+ Havoc(),
+ PEASSng(),
+ LigoloNg(),
+ ChiselTunnel(),
+ EvilWinRM(),
+ Mythic(),
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Post-Exploitation Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="").strip().replace("\n", " ")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc or "—"), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Post-Exploitation Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # Delegate to collection-style show_options if available
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # Otherwise call run if available
- elif hasattr(selected, "run"):
- selected.run()
- # If tool exposes before_run (like Vegile), call it to preserve original behavior
- elif hasattr(selected, "before_run"):
- selected.before_run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = PostExploitationTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/remote_administration.py b/tools/remote_administration.py
index c54f1ba..bceacf6 100644
--- a/tools/remote_administration.py
+++ b/tools/remote_administration.py
@@ -1,28 +1,11 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
-class Stitch(HackingTool):
- TITLE = "Stitch"
- DESCRIPTION = "Stitch is a cross platform python framework.\n" \
- "which allows you to build custom payloads\n" \
- "For Windows, Mac and Linux."
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/nathanlopez/Stitch.git",
- "cd Stitch;sudo pip install -r lnx_requirements.txt"
- ]
- RUN_COMMANDS = ["cd Stitch;python main.py"]
- PROJECT_URL = "https://github.com/nathanlopez/Stitch"
+# Bug 17 fix: Stitch was defined in both payload_creator.py and remote_administration.py.
+# It is kept in payload_creator.py (its correct category) and removed from here.
class Pyshell(HackingTool):
@@ -30,8 +13,8 @@ class Pyshell(HackingTool):
DESCRIPTION = "Pyshell is a Rat Tool that can be able to download & upload " \
"files,\n Execute OS Command and more.."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/knassar702/Pyshell.git;"
- "sudo pip install pyscreenshot python-nmap requests"
+ "git clone https://github.com/knassar702/Pyshell.git;"
+ "pip install --user pyscreenshot python-nmap requests"
]
RUN_COMMANDS = ["cd Pyshell;./Pyshell"]
PROJECT_URL = "https://github.com/knassar702/pyshell"
@@ -40,75 +23,9 @@ class Pyshell(HackingTool):
class RemoteAdministrationTools(HackingToolsCollection):
TITLE = "Remote Administrator Tools (RAT)"
TOOLS = [
- Stitch(),
Pyshell()
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Remote Administration Tools (RAT)", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="").strip().replace("\n", " ")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc or "—"), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Remote Administration Tools (RAT) Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- # If tool exposes show_options (collection-style), delegate to it
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- # Otherwise, if runnable, call its run method
- elif hasattr(selected, "run"):
- selected.run()
- # Preserve any before_run hooks if present
- elif hasattr(selected, "before_run"):
- selected.before_run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = RemoteAdministrationTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/reverse_engineering.py b/tools/reverse_engineering.py
index a221d46..588df80 100644
--- a/tools/reverse_engineering.py
+++ b/tools/reverse_engineering.py
@@ -1,18 +1,10 @@
-# coding=utf-8
import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class AndroGuard(HackingTool):
TITLE = "Androguard"
@@ -22,14 +14,15 @@ class AndroGuard(HackingTool):
PROJECT_URL = "https://github.com/androguard/androguard "
def __init__(self):
- super(AndroGuard, self).__init__(runnable=False)
+ super().__init__(runnable=False)
class Apk2Gold(HackingTool):
TITLE = "Apk2Gold"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "Apk2Gold is a CLI tool for decompiling Android apps to Java"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/lxdvs/apk2gold.git",
+ "git clone https://github.com/lxdvs/apk2gold.git",
"cd apk2gold;sudo bash make.sh"
]
PROJECT_URL = "https://github.com/lxdvs/apk2gold "
@@ -47,13 +40,40 @@ class Jadx(HackingTool):
"[*] decode AndroidManifest.xml and other resources from " \
"resources.arsc"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/skylot/jadx.git",
- "cd jadx;./gradlew dist"
+ "git clone https://github.com/skylot/jadx.git",
+ # Bug 30 fix: gradlew dist requires Java — check first
+ "java -version 2>&1 | grep -q 'version' && cd jadx && ./gradlew dist || echo '[ERROR] Java not found. Install: sudo apt install default-jdk'",
]
PROJECT_URL = "https://github.com/skylot/jadx"
+ REQUIRES_JAVA = True
def __init__(self):
- super(Jadx, self).__init__(runnable=False)
+ # Py3-4 fix: super(Jadx, self) → super()
+ super().__init__(runnable=False)
+
+
+class Ghidra(HackingTool):
+ TITLE = "Ghidra (NSA Reverse Engineering)"
+ DESCRIPTION = "NSA's software reverse engineering framework — disassembly, decompilation, scripting."
+ REQUIRES_JAVA = True
+ INSTALL_COMMANDS = [
+ "sudo apt-get install -y ghidra || echo 'Download from https://ghidra-sre.org/'",
+ ]
+ RUN_COMMANDS = ["ghidra --help || echo 'Run: ghidraRun'"]
+ PROJECT_URL = "https://github.com/NationalSecurityAgency/ghidra"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Radare2(HackingTool):
+ TITLE = "Radare2 (RE Framework)"
+ DESCRIPTION = "Portable UNIX-like reverse engineering framework and command-line toolset."
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/radareorg/radare2.git",
+ "cd radare2 && sys/install.sh",
+ ]
+ RUN_COMMANDS = ["r2 -h"]
+ PROJECT_URL = "https://github.com/radareorg/radare2"
+ SUPPORTED_OS = ["linux", "macos"]
class ReverseEngineeringTools(HackingToolsCollection):
@@ -61,71 +81,11 @@ class ReverseEngineeringTools(HackingToolsCollection):
TOOLS = [
AndroGuard(),
Apk2Gold(),
- Jadx()
+ Jadx(),
+ Ghidra(),
+ Radare2(),
]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Reverse Engineering Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="").strip().replace("\n", " ")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc or "—"), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Reverse Engineering Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "before_run"):
- selected.before_run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = ReverseEngineeringTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/sql_injection.py b/tools/sql_injection.py
new file mode 100644
index 0000000..c7a3b9a
--- /dev/null
+++ b/tools/sql_injection.py
@@ -0,0 +1,88 @@
+from core import HackingTool, HackingToolsCollection, console
+
+from rich.panel import Panel
+from rich.prompt import Prompt
+
+
+class Sqlmap(HackingTool):
+ TITLE = "Sqlmap tool"
+ DESCRIPTION = "sqlmap is an open source penetration testing tool that " \
+ "automates the process of detecting and exploiting SQL injection flaws " \
+ "and taking over database servers. [!] python3 sqlmap.py -u [http://example.com] --batch --banner. More usage: https://github.com/sqlmapproject/sqlmap/wiki/Usage"
+ INSTALL_COMMANDS = ["git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev"]
+ RUN_COMMANDS = ["cd sqlmap-dev;python3 sqlmap.py --wizard"]
+ PROJECT_URL = "https://github.com/sqlmapproject/sqlmap"
+
+
+class NoSqlMap(HackingTool):
+ TITLE = "NoSqlMap"
+ DESCRIPTION = "NoSQLMap is an open source Python tool designed to audit and automate injection attacks. [*] Please install MongoDB."
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/codingo/NoSQLMap.git",
+ # Bug 25 fix: was "python setup.py install" (Python 2) and "python NoSQLMap"
+ "cd NoSQLMap && pip install --user .",
+ ]
+ # Bug 25 fix: "python" → "python3"
+ RUN_COMMANDS = ["python3 -m nosqlmap"]
+ PROJECT_URL = "https://github.com/codingo/NoSQLMap"
+
+
+class SQLiScanner(HackingTool):
+ TITLE = "Damn Small SQLi Scanner"
+ DESCRIPTION = "DSSS is a fully functional SQL injection vulnerability scanner also supporting GET and POST parameters. Usage: python3 dsss.py -h | -u [URL]"
+ INSTALL_COMMANDS = ["git clone https://github.com/stamparm/DSSS.git"]
+ PROJECT_URL = "https://github.com/stamparm/DSSS"
+
+ def __init__(self):
+ super().__init__(runnable=False)
+
+
+class Explo(HackingTool):
+ TITLE = "Explo"
+ DESCRIPTION = "Explo is a simple tool to describe web security issues in human and machine readable format. Usage: explo [--verbose|-v] testcase.yaml | explo [--verbose|-v] examples/*.yaml"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/dtag-dev-sec/explo.git",
+ "cd explo && pip install --user .",
+ ]
+ PROJECT_URL = "https://github.com/dtag-dev-sec/explo"
+
+ def __init__(self):
+ super().__init__(runnable=False)
+
+
+class Blisqy(HackingTool):
+ TITLE = "Blisqy - Exploit Time-based blind-SQL injection"
+ DESCRIPTION = "Blisqy helps web security researchers find time-based blind SQL injections on HTTP headers and exploit them."
+ INSTALL_COMMANDS = ["git clone https://github.com/JohnTroony/Blisqy.git"]
+ PROJECT_URL = "https://github.com/JohnTroony/Blisqy"
+
+ def __init__(self):
+ super().__init__(runnable=False)
+
+
+class Leviathan(HackingTool):
+ TITLE = "Leviathan - Wide Range Mass Audit Toolkit"
+ DESCRIPTION = "Leviathan is a mass audit toolkit with service discovery, brute force, SQL injection detection, and custom exploit capabilities. Requires API keys."
+ INSTALL_COMMANDS = ["git clone https://github.com/leviathan-framework/leviathan.git",
+ "cd leviathan;pip install --user -r requirements.txt"]
+ RUN_COMMANDS = ["cd leviathan;python leviathan.py"]
+ PROJECT_URL = "https://github.com/leviathan-framework/leviathan"
+
+
+class SQLScan(HackingTool):
+ TITLE = "SQLScan"
+ DESCRIPTION = "SQLScan is a quick web scanner to find SQL injection points. Not for educational purposes."
+ INSTALL_COMMANDS = ["sudo apt install php php-bz2 php-curl php-mbstring curl",
+ "sudo curl https://raw.githubusercontent.com/Cvar1984/sqlscan/dev/build/main.phar --output /usr/local/bin/sqlscan",
+ "chmod +x /usr/local/bin/sqlscan"]
+ RUN_COMMANDS = ["sudo sqlscan"]
+ PROJECT_URL = "https://github.com/Cvar1984/sqlscan"
+
+
+class SqlInjectionTools(HackingToolsCollection):
+ TITLE = "SQL Injection Tools"
+ TOOLS = [Sqlmap(), NoSqlMap(), SQLiScanner(), Explo(), Blisqy(), Leviathan(), SQLScan()]
+
+if __name__ == "__main__":
+ tools = SqlInjectionTools()
+ tools.show_options()
diff --git a/tools/sql_tools.py b/tools/sql_tools.py
deleted file mode 100644
index 36061ee..0000000
--- a/tools/sql_tools.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# coding=utf-8
-from core import HackingTool
-from core import HackingToolsCollection
-
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
-from rich.panel import Panel
-from rich.prompt import Prompt
-
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
-
-class Sqlmap(HackingTool):
- TITLE = "Sqlmap tool"
- DESCRIPTION = "sqlmap is an open source penetration testing tool that " \
- "automates the process of detecting and exploiting SQL injection flaws " \
- "and taking over database servers. [!] python3 sqlmap.py -u [http://example.com] --batch --banner. More usage: https://github.com/sqlmapproject/sqlmap/wiki/Usage"
- INSTALL_COMMANDS = ["sudo git clone --depth 1 https://github.com/sqlmapproject/sqlmap.git sqlmap-dev"]
- RUN_COMMANDS = ["cd sqlmap-dev;python3 sqlmap.py --wizard"]
- PROJECT_URL = "https://github.com/sqlmapproject/sqlmap"
-
-
-class NoSqlMap(HackingTool):
- TITLE = "NoSqlMap"
- DESCRIPTION = "NoSQLMap is an open source Python tool designed to audit and automate injection attacks. [*] Please install MongoDB."
- INSTALL_COMMANDS = ["git clone https://github.com/codingo/NoSQLMap.git",
- "sudo chmod -R 755 NoSQLMap;cd NoSQLMap;python setup.py install"]
- RUN_COMMANDS = ["python NoSQLMap"]
- PROJECT_URL = "https://github.com/codingo/NoSQLMap"
-
-
-class SQLiScanner(HackingTool):
- TITLE = "Damn Small SQLi Scanner"
- DESCRIPTION = "DSSS is a fully functional SQL injection vulnerability scanner also supporting GET and POST parameters. Usage: python3 dsss.py -h | -u [URL]"
- INSTALL_COMMANDS = ["git clone https://github.com/stamparm/DSSS.git"]
- PROJECT_URL = "https://github.com/stamparm/DSSS"
-
- def __init__(self):
- super(SQLiScanner, self).__init__(runnable=False)
-
-
-class Explo(HackingTool):
- TITLE = "Explo"
- DESCRIPTION = "Explo is a simple tool to describe web security issues in human and machine readable format. Usage: explo [--verbose|-v] testcase.yaml | explo [--verbose|-v] examples/*.yaml"
- INSTALL_COMMANDS = ["git clone https://github.com/dtag-dev-sec/explo.git",
- "cd explo;sudo python setup.py install"]
- PROJECT_URL = "https://github.com/dtag-dev-sec/explo"
-
- def __init__(self):
- super(Explo, self).__init__(runnable=False)
-
-
-class Blisqy(HackingTool):
- TITLE = "Blisqy - Exploit Time-based blind-SQL injection"
- DESCRIPTION = "Blisqy helps web security researchers find time-based blind SQL injections on HTTP headers and exploit them."
- INSTALL_COMMANDS = ["git clone https://github.com/JohnTroony/Blisqy.git"]
- PROJECT_URL = "https://github.com/JohnTroony/Blisqy"
-
- def __init__(self):
- super(Blisqy, self).__init__(runnable=False)
-
-
-class Leviathan(HackingTool):
- TITLE = "Leviathan - Wide Range Mass Audit Toolkit"
- DESCRIPTION = "Leviathan is a mass audit toolkit with service discovery, brute force, SQL injection detection, and custom exploit capabilities. Requires API keys."
- INSTALL_COMMANDS = ["git clone https://github.com/leviathan-framework/leviathan.git",
- "cd leviathan;sudo pip install -r requirements.txt"]
- RUN_COMMANDS = ["cd leviathan;python leviathan.py"]
- PROJECT_URL = "https://github.com/leviathan-framework/leviathan"
-
-
-class SQLScan(HackingTool):
- TITLE = "SQLScan"
- DESCRIPTION = "SQLScan is a quick web scanner to find SQL injection points. Not for educational purposes."
- INSTALL_COMMANDS = ["sudo apt install php php-bz2 php-curl php-mbstring curl",
- "sudo curl https://raw.githubusercontent.com/Cvar1984/sqlscan/dev/build/main.phar --output /usr/local/bin/sqlscan",
- "chmod +x /usr/local/bin/sqlscan"]
- RUN_COMMANDS = ["sudo sqlscan"]
- PROJECT_URL = "https://github.com/Cvar1984/sqlscan"
-
-
-class SqlInjectionTools(HackingToolsCollection):
- TITLE = "SQL Injection Tools"
- TOOLS = [Sqlmap(), NoSqlMap(), SQLiScanner(), Explo(), Blisqy(), Leviathan(), SQLScan()]
-
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="SQL Injection Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="").strip().replace("\n", " ")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "PROJECT", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc or "—"), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]SQL Injection Tools Collection[/bold magenta]\nSelect a tool to view options or run it.", border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = int(Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99"))
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "before_run"):
- selected.before_run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
-if __name__ == "__main__":
- tools = SqlInjectionTools()
- tools.pretty_print()
- tools.show_options()
diff --git a/tools/steganography.py b/tools/steganography.py
index fc457fd..bccc075 100644
--- a/tools/steganography.py
+++ b/tools/steganography.py
@@ -1,19 +1,11 @@
-# coding=utf-8
import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
+from core import HackingTool, HackingToolsCollection, console
from core import validate_input
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
class SteganoHide(HackingTool):
TITLE = "SteganoHide"
@@ -59,7 +51,7 @@ class StegoCracker(HackingTool):
TITLE = "StegoCracker"
DESCRIPTION = "StegoCracker lets you hide and retrieve data in image or audio files"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/W1LDN16H7/StegoCracker.git",
+ "git clone https://github.com/W1LDN16H7/StegoCracker.git",
"sudo chmod -R 755 StegoCracker"
]
RUN_COMMANDS = [
@@ -73,7 +65,7 @@ class Whitespace(HackingTool):
TITLE = "Whitespace"
DESCRIPTION = "Use whitespace and unicode characters for steganography"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/beardog108/snow10.git",
+ "git clone https://github.com/beardog108/snow10.git",
"sudo chmod -R 755 snow10"
]
RUN_COMMANDS = ["cd snow10 && ./install.sh"]
@@ -84,65 +76,6 @@ class SteganographyTools(HackingToolsCollection):
TITLE = "Steganography Tools"
TOOLS = [SteganoHide(), StegnoCracker(), StegoCracker(), Whitespace()]
- def _get_attr(self, obj, *names, default=""):
- for n in names:
- if hasattr(obj, n):
- return getattr(obj, n)
- return default
-
- def pretty_print(self):
- table = Table(title="Steganography Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- title = self._get_attr(t, "TITLE", "Title", "title", default=t.__class__.__name__)
- desc = self._get_attr(t, "DESCRIPTION", "Description", "description", default="").strip().replace("\n", " ")
- url = self._get_attr(t, "PROJECT_URL", "PROJECT_URL", "project_url", "projectUrl", default="")
- table.add_row(str(title), str(desc or "—"), str(url))
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Steganography Tools Collection[/bold magenta]\nSelect a tool to run or view options.", border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = self._get_attr(tool, "TITLE", "Title", "title", default=tool.__class__.__name__)
- desc = self._get_attr(tool, "DESCRIPTION", "Description", "description", default="—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = int(Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99"))
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- elif hasattr(selected, "before_run"):
- selected.before_run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = SteganographyTools()
- tools.pretty_print()
tools.show_options()
diff --git a/tools/tool_manager.py b/tools/tool_manager.py
index 510cc0e..84bfb57 100644
--- a/tools/tool_manager.py
+++ b/tools/tool_manager.py
@@ -1,126 +1,98 @@
-# coding=utf-8
import os
import sys
+import subprocess
from time import sleep
-from core import HackingTool
-from core import HackingToolsCollection
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
-from rich.panel import Panel
-from rich.prompt import Prompt
+from rich.prompt import Confirm
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
+from core import HackingTool, HackingToolsCollection, console
+from constants import APP_INSTALL_DIR, APP_BIN_PATH, USER_CONFIG_DIR, REPO_URL
class UpdateTool(HackingTool):
TITLE = "Update Tool or System"
- DESCRIPTION = "Update Tool or System"
+ DESCRIPTION = "Update system packages or pull the latest hackingtool code"
def __init__(self):
- super(UpdateTool, self).__init__([
+ super().__init__([
("Update System", self.update_sys),
- ("Update Hackingtool", self.update_ht)
+ ("Update Hackingtool", self.update_ht),
], installable=False, runnable=False)
def update_sys(self):
- os.system("sudo apt update && sudo apt full-upgrade -y")
- os.system("sudo apt-get install tor openssl curl && sudo apt-get update tor openssl curl")
- os.system("sudo apt-get install python3-pip")
+ from os_detect import CURRENT_OS, PACKAGE_UPDATE_CMDS
+ mgr = CURRENT_OS.pkg_manager
+ cmd = PACKAGE_UPDATE_CMDS.get(mgr)
+ if cmd:
+ priv = "" if (CURRENT_OS.system == "macos" or os.geteuid() == 0) else "sudo "
+ # shell=True needed — cmd contains && chains; strings are hardcoded, not user input
+ subprocess.run(f"{priv}{cmd}", shell=True, check=False)
+ else:
+ console.print("[warning]Unknown package manager — update manually.[/warning]")
def update_ht(self):
- os.system("sudo chmod +x /etc/;"
- "sudo chmod +x /usr/share/doc;"
- "sudo rm -rf /usr/share/doc/hackingtool/;"
- "cd /etc/;"
- "sudo rm -rf /etc/hackingtool/;"
- "mkdir hackingtool;"
- "cd hackingtool;"
- "git clone https://github.com/Z4nzu/hackingtool.git;"
- "cd hackingtool;"
- "sudo chmod +x install.sh;"
- "./install.sh")
+ if not APP_INSTALL_DIR.exists():
+ console.print(f"[error]Install directory not found: {APP_INSTALL_DIR}[/error]")
+ console.print("[dim]Run install.py first.[/dim]")
+ return
+ console.print(f"[bold cyan]Pulling latest code from {REPO_URL}...[/bold cyan]")
+ result = subprocess.run(
+ ["git", "pull", "--rebase"],
+ cwd=str(APP_INSTALL_DIR),
+ capture_output=True, text=True,
+ )
+ if result.returncode != 0:
+ console.print(f"[error]git pull failed:\n{result.stderr}[/error]")
+ return
+ pip = str(APP_INSTALL_DIR / "venv" / "bin" / "pip")
+ if (APP_INSTALL_DIR / "venv" / "bin" / "pip").exists():
+ subprocess.run([pip, "install", "-q", "-r",
+ str(APP_INSTALL_DIR / "requirements.txt")])
+ console.print("[success]✔ Hackingtool updated.[/success]")
class UninstallTool(HackingTool):
TITLE = "Uninstall HackingTool"
- DESCRIPTION = "Uninstall HackingTool"
+ DESCRIPTION = "Remove hackingtool from system"
def __init__(self):
- super(UninstallTool, self).__init__([
- ('Uninstall', self.uninstall)
+ super().__init__([
+ ("Uninstall", self.uninstall),
], installable=False, runnable=False)
def uninstall(self):
- console.print("hackingtool started to uninstall..\n")
+ import shutil
+ console.print("[warning]This will remove hackingtool from your system.[/warning]")
+ if not Confirm.ask("Continue?", default=False):
+ return
+
+ if APP_INSTALL_DIR.exists():
+ shutil.rmtree(str(APP_INSTALL_DIR))
+ console.print(f"[success]✔ Removed {APP_INSTALL_DIR}[/success]")
+ else:
+ console.print(f"[dim]{APP_INSTALL_DIR} not found — already removed?[/dim]")
+
+ if APP_BIN_PATH.exists():
+ APP_BIN_PATH.unlink()
+ console.print(f"[success]✔ Removed launcher {APP_BIN_PATH}[/success]")
+
+ if Confirm.ask(f"Also remove user data at {USER_CONFIG_DIR}?", default=False):
+ shutil.rmtree(str(USER_CONFIG_DIR), ignore_errors=True)
+ console.print(f"[success]✔ Removed {USER_CONFIG_DIR}[/success]")
+
+ console.print("[bold green]Hackingtool uninstalled. Goodbye.[/bold green]")
sleep(1)
- os.system("sudo chmod +x /etc/;"
- "sudo chmod +x /usr/share/doc;"
- "sudo rm -rf /usr/share/doc/hackingtool/;"
- "cd /etc/;"
- "sudo rm -rf /etc/hackingtool/;")
- console.print("\n[bold green]Hackingtool Successfully Uninstalled... Goodbye.[/bold green]")
- sys.exit()
+ sys.exit(0)
class ToolManager(HackingToolsCollection):
TITLE = "Update or Uninstall | Hackingtool"
TOOLS = [
UpdateTool(),
- UninstallTool()
+ UninstallTool(),
]
- def pretty_print(self):
- table = Table(title="Tool Manager — Update / Uninstall", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "))
-
- panel = Panel(table, title="[purple]Available Manager Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Tool Manager[/bold magenta]\nSelect an action to run.", border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Options[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc)
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = int(Prompt.ask("[bold cyan]Select an option[/bold cyan]", default="99"))
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
-
- return self.show_options(parent=parent)
-
if __name__ == "__main__":
manager = ToolManager()
- manager.pretty_print()
manager.show_options()
diff --git a/tools/web_attack.py b/tools/web_attack.py
new file mode 100644
index 0000000..9b421c3
--- /dev/null
+++ b/tools/web_attack.py
@@ -0,0 +1,285 @@
+import subprocess
+from core import HackingTool, HackingToolsCollection, console
+
+from rich.panel import Panel
+from rich.prompt import Prompt
+
+
+class Web2Attack(HackingTool):
+ TITLE = "Web2Attack"
+ DESCRIPTION = "Web hacking framework with tools, exploits by python"
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/santatic/web2attack.git"
+ ]
+ RUN_COMMANDS = ["cd web2attack && sudo python3 w2aconsole"]
+ PROJECT_URL = "https://github.com/santatic/web2attack"
+
+
+class Skipfish(HackingTool):
+ TITLE = "Skipfish"
+ DESCRIPTION = (
+ "Skipfish – Fully automated, active web application "
+ "security reconnaissance tool \n "
+ "Usage: skipfish -o [FolderName] targetip/site"
+ )
+ RUN_COMMANDS = [
+ "sudo skipfish -h",
+ 'echo "skipfish -o [FolderName] targetip/site"|boxes -d headline | lolcat'
+ ]
+
+ def __init__(self):
+ super().__init__(installable=False)
+
+
+class SubDomainFinder(HackingTool):
+ TITLE = "SubDomain Finder"
+ DESCRIPTION = (
+ "Sublist3r is a python tool designed to enumerate "
+ "subdomains of websites using OSINT \n "
+ "Usage:\n\t[1] python3 sublist3r.py -d example.com \n"
+ "[2] python3 sublist3r.py -d example.com -p 80,443"
+ )
+ INSTALL_COMMANDS = [
+ "sudo pip3 install requests argparse dnspython",
+ "git clone https://github.com/aboul3la/Sublist3r.git",
+ "cd Sublist3r && sudo pip3 install -r requirements.txt"
+ ]
+ RUN_COMMANDS = ["cd Sublist3r && python3 sublist3r.py -h"]
+ PROJECT_URL = "https://github.com/aboul3la/Sublist3r"
+
+
+class CheckURL(HackingTool):
+ TITLE = "CheckURL"
+ DESCRIPTION = (
+ "Detect evil urls that uses IDN Homograph Attack.\n\t"
+ "[!] python3 checkURL.py --url google.com"
+ )
+ INSTALL_COMMANDS = ["git clone https://github.com/UndeadSec/checkURL.git"]
+ RUN_COMMANDS = ["cd checkURL && python3 checkURL.py --help"]
+ PROJECT_URL = "https://github.com/UndeadSec/checkURL"
+
+
+class Blazy(HackingTool):
+ TITLE = "Blazy(Also Find ClickJacking)"
+ DESCRIPTION = "Blazy is a modern login page bruteforcer"
+ INSTALL_COMMANDS = []
+ RUN_COMMANDS = []
+ PROJECT_URL = "https://github.com/UltimateHackers/Blazy"
+ ARCHIVED = True
+ ARCHIVED_REASON = "Python 2 only (pip2.7/python2.7). Repo archived/unmaintained."
+
+ def __init__(self):
+ super().__init__(installable=False, runnable=False)
+
+
+class SubDomainTakeOver(HackingTool):
+ TITLE = "Sub-Domain TakeOver"
+ DESCRIPTION = (
+ "Sub-domain takeover vulnerability occur when a sub-domain "
+ "\n (subdomain.example.com) is pointing to a service "
+ "(e.g: GitHub, AWS/S3,..)\nthat has been removed or deleted.\n"
+ "Usage:python3 takeover.py -d www.domain.com -v"
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/edoardottt/takeover.git",
+ "cd takeover && pip install --user ."
+ ]
+ PROJECT_URL = "https://github.com/edoardottt/takeover"
+
+ def __init__(self):
+ super().__init__(runnable=False)
+
+
+class Dirb(HackingTool):
+ TITLE = "Dirb"
+ DESCRIPTION = (
+ "DIRB is a Web Content Scanner. It looks for existing "
+ "(and/or hidden) Web Objects.\n"
+ "It basically works by launching a dictionary based "
+ "attack against \n a web server and analyzing the response."
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://gitlab.com/kalilinux/packages/dirb.git",
+ "cd dirb;sudo bash configure;make"
+ ]
+ PROJECT_URL = "https://gitlab.com/kalilinux/packages/dirb"
+
+ def run(self):
+ uinput = input("Enter Url >> ")
+ subprocess.run(["sudo", "dirb", uinput])
+
+
+class Nuclei(HackingTool):
+ TITLE = "Nuclei (Vulnerability Scanner)"
+ DESCRIPTION = (
+ "Fast, template-based vulnerability scanner used by 50k+ security teams.\n"
+ "Usage: nuclei -u https://example.com"
+ )
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@latest",
+ "nuclei -update-templates",
+ ]
+ RUN_COMMANDS = ["nuclei -h"]
+ PROJECT_URL = "https://github.com/projectdiscovery/nuclei"
+
+
+class Ffuf(HackingTool):
+ TITLE = "ffuf (Web Fuzzer)"
+ DESCRIPTION = (
+ "Fast web fuzzer — content discovery, parameter fuzzing, vhost discovery.\n"
+ "Usage: ffuf -w wordlist.txt -u https://example.com/FUZZ"
+ )
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install -v github.com/ffuf/ffuf/v2@latest",
+ ]
+ RUN_COMMANDS = ["ffuf -h"]
+ PROJECT_URL = "https://github.com/ffuf/ffuf"
+
+
+class Feroxbuster(HackingTool):
+ TITLE = "Feroxbuster (Directory Brute Force)"
+ DESCRIPTION = (
+ "Fast, recursive content discovery tool written in Rust.\n"
+ "Usage: feroxbuster -u https://example.com -w wordlist.txt"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = [
+ "curl -sL https://raw.githubusercontent.com/epi052/feroxbuster/main/install-nix.sh "
+ "| sudo bash -s /usr/local/bin",
+ ]
+ RUN_COMMANDS = ["feroxbuster -h"]
+ PROJECT_URL = "https://github.com/epi052/feroxbuster"
+
+
+class Nikto(HackingTool):
+ TITLE = "Nikto (Web Server Scanner)"
+ DESCRIPTION = (
+ "Scan web servers for dangerous files, outdated software, misconfigurations.\n"
+ "Usage: nikto -h https://example.com"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt-get install -y nikto"]
+ RUN_COMMANDS = ["nikto -Help"]
+ PROJECT_URL = "https://github.com/sullo/nikto"
+
+
+class Wafw00f(HackingTool):
+ TITLE = "wafw00f (WAF Detector)"
+ DESCRIPTION = (
+ "Fingerprint and identify Web Application Firewalls (WAF).\n"
+ "Usage: wafw00f https://example.com"
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/EnableSecurity/wafw00f.git",
+ "cd wafw00f && pip install --user .",
+ ]
+ RUN_COMMANDS = ["wafw00f --help"]
+ PROJECT_URL = "https://github.com/EnableSecurity/wafw00f"
+
+
+class Katana(HackingTool):
+ TITLE = "Katana (Web Crawler)"
+ DESCRIPTION = (
+ "Next-generation crawling and spidering framework from ProjectDiscovery.\n"
+ "Usage: katana -u https://example.com"
+ )
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = [
+ "go install -v github.com/projectdiscovery/katana/cmd/katana@latest",
+ ]
+ RUN_COMMANDS = ["katana -h"]
+ PROJECT_URL = "https://github.com/projectdiscovery/katana"
+
+
+class Gobuster(HackingTool):
+ TITLE = "Gobuster (Dir/DNS/Vhost Brute Force)"
+ DESCRIPTION = "Directory/file, DNS, and vhost brute-forcing tool written in Go."
+ REQUIRES_GO = True
+ INSTALL_COMMANDS = ["go install github.com/OJ/gobuster/v3@latest"]
+ RUN_COMMANDS = ["gobuster --help"]
+ PROJECT_URL = "https://github.com/OJ/gobuster"
+
+
+class Dirsearch(HackingTool):
+ TITLE = "Dirsearch (Web Path Discovery)"
+ DESCRIPTION = "Web path brute-forcing tool for discovering directories and files on web servers."
+ INSTALL_COMMANDS = ["pip install --user dirsearch"]
+ RUN_COMMANDS = ["dirsearch --help"]
+ PROJECT_URL = "https://github.com/maurosoria/dirsearch"
+
+
+class OwaspZap(HackingTool):
+ TITLE = "OWASP ZAP (Web App Scanner)"
+ DESCRIPTION = "Full-featured web application security scanner — proxy, spider, fuzzer, scanner."
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt-get install -y zaproxy"]
+ RUN_COMMANDS = ["zaproxy --help"]
+ PROJECT_URL = "https://github.com/zaproxy/zaproxy"
+
+
+class TestSSL(HackingTool):
+ TITLE = "testssl.sh (TLS/SSL Checker)"
+ DESCRIPTION = "Check TLS/SSL ciphers, protocols, and cryptographic flaws on any port."
+ INSTALL_COMMANDS = ["git clone https://github.com/drwetter/testssl.sh.git"]
+ RUN_COMMANDS = ["cd testssl.sh && ./testssl.sh --help"]
+ PROJECT_URL = "https://github.com/drwetter/testssl.sh"
+
+
+class Arjun(HackingTool):
+ TITLE = "Arjun (HTTP Parameter Discovery)"
+ DESCRIPTION = "HTTP parameter discovery suite that finds hidden GET/POST parameters."
+ INSTALL_COMMANDS = ["pip install --user arjun"]
+ RUN_COMMANDS = ["arjun --help"]
+ PROJECT_URL = "https://github.com/s0md3v/Arjun"
+
+
+class Caido(HackingTool):
+ TITLE = "Caido (Web Security Auditing)"
+ DESCRIPTION = "Lightweight, modern web security auditing toolkit — Burp Suite alternative written in Rust."
+ INSTALL_COMMANDS = [
+ "curl -sSL https://caido.download/releases/latest/caido-cli-linux-x86_64.tar.gz | sudo tar xz -C /usr/local/bin",
+ ]
+ RUN_COMMANDS = ["caido --help"]
+ PROJECT_URL = "https://github.com/caido/caido"
+ SUPPORTED_OS = ["linux", "macos"]
+
+
+class Mitmproxy(HackingTool):
+ TITLE = "mitmproxy (Intercepting Proxy)"
+ DESCRIPTION = "Interactive TLS-capable intercepting HTTP proxy for pentesters and developers."
+ INSTALL_COMMANDS = ["pip install --user mitmproxy"]
+ RUN_COMMANDS = ["mitmproxy --version"]
+ PROJECT_URL = "https://github.com/mitmproxy/mitmproxy"
+
+
+class WebAttackTools(HackingToolsCollection):
+ TITLE = "Web Attack tools"
+ DESCRIPTION = ""
+ TOOLS = [
+ Web2Attack(),
+ Skipfish(),
+ SubDomainFinder(),
+ CheckURL(),
+ Blazy(),
+ SubDomainTakeOver(),
+ Dirb(),
+ Nuclei(),
+ Ffuf(),
+ Feroxbuster(),
+ Nikto(),
+ Wafw00f(),
+ Katana(),
+ Gobuster(),
+ Dirsearch(),
+ OwaspZap(),
+ TestSSL(),
+ Arjun(),
+ Caido(),
+ Mitmproxy(),
+ ]
+
+if __name__ == "__main__":
+ tools = WebAttackTools()
+ tools.show_options()
diff --git a/tools/webattack.py b/tools/webattack.py
deleted file mode 100644
index f27e2a5..0000000
--- a/tools/webattack.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# coding=utf-8
-import subprocess
-from core import HackingTool
-from core import HackingToolsCollection
-
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
-from rich.panel import Panel
-from rich.prompt import Prompt
-
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
-
-class Web2Attack(HackingTool):
- TITLE = "Web2Attack"
- DESCRIPTION = "Web hacking framework with tools, exploits by python"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/santatic/web2attack.git"
- ]
- RUN_COMMANDS = ["cd web2attack && sudo python3 w2aconsole"]
- PROJECT_URL = "https://github.com/santatic/web2attack"
-
-
-class Skipfish(HackingTool):
- TITLE = "Skipfish"
- DESCRIPTION = (
- "Skipfish – Fully automated, active web application "
- "security reconnaissance tool \n "
- "Usage: skipfish -o [FolderName] targetip/site"
- )
- RUN_COMMANDS = [
- "sudo skipfish -h",
- 'echo "skipfish -o [FolderName] targetip/site"|boxes -d headline | lolcat'
- ]
-
- def __init__(self):
- super(Skipfish, self).__init__(installable=False)
-
-
-class SubDomainFinder(HackingTool):
- TITLE = "SubDomain Finder"
- DESCRIPTION = (
- "Sublist3r is a python tool designed to enumerate "
- "subdomains of websites using OSINT \n "
- "Usage:\n\t[1] python3 sublist3r.py -d example.com \n"
- "[2] python3 sublist3r.py -d example.com -p 80,443"
- )
- INSTALL_COMMANDS = [
- "sudo pip3 install requests argparse dnspython",
- "sudo git clone https://github.com/aboul3la/Sublist3r.git",
- "cd Sublist3r && sudo pip3 install -r requirements.txt"
- ]
- RUN_COMMANDS = ["cd Sublist3r && python3 sublist3r.py -h"]
- PROJECT_URL = "https://github.com/aboul3la/Sublist3r"
-
-
-class CheckURL(HackingTool):
- TITLE = "CheckURL"
- DESCRIPTION = (
- "Detect evil urls that uses IDN Homograph Attack.\n\t"
- "[!] python3 checkURL.py --url google.com"
- )
- INSTALL_COMMANDS = ["sudo git clone https://github.com/UndeadSec/checkURL.git"]
- RUN_COMMANDS = ["cd checkURL && python3 checkURL.py --help"]
- PROJECT_URL = "https://github.com/UndeadSec/checkURL"
-
-
-class Blazy(HackingTool):
- TITLE = "Blazy(Also Find ClickJacking)"
- DESCRIPTION = "Blazy is a modern login page bruteforcer"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/UltimateHackers/Blazy.git",
- "cd Blazy && sudo pip2.7 install -r requirements.txt"
- ]
- RUN_COMMANDS = ["cd Blazy && sudo python2.7 blazy.py"]
- PROJECT_URL = "https://github.com/UltimateHackers/Blazy"
-
-
-class SubDomainTakeOver(HackingTool):
- TITLE = "Sub-Domain TakeOver"
- DESCRIPTION = (
- "Sub-domain takeover vulnerability occur when a sub-domain "
- "\n (subdomain.example.com) is pointing to a service "
- "(e.g: GitHub, AWS/S3,..)\nthat has been removed or deleted.\n"
- "Usage:python3 takeover.py -d www.domain.com -v"
- )
- INSTALL_COMMANDS = [
- "git clone https://github.com/edoardottt/takeover.git",
- "cd takeover;sudo python3 setup.py install"
- ]
- PROJECT_URL = "https://github.com/edoardottt/takeover"
-
- def __init__(self):
- super(SubDomainTakeOver, self).__init__(runnable=False)
-
-
-class Dirb(HackingTool):
- TITLE = "Dirb"
- DESCRIPTION = (
- "DIRB is a Web Content Scanner. It looks for existing "
- "(and/or hidden) Web Objects.\n"
- "It basically works by launching a dictionary based "
- "attack against \n a web server and analyzing the response."
- )
- INSTALL_COMMANDS = [
- "sudo git clone https://gitlab.com/kalilinux/packages/dirb.git",
- "cd dirb;sudo bash configure;make"
- ]
- PROJECT_URL = "https://gitlab.com/kalilinux/packages/dirb"
-
- def run(self):
- uinput = input("Enter Url >> ")
- subprocess.run(["sudo", "dirb", uinput])
-
-
-class WebAttackTools(HackingToolsCollection):
- TITLE = "Web Attack tools"
- DESCRIPTION = ""
- TOOLS = [
- Web2Attack(),
- Skipfish(),
- SubDomainFinder(),
- CheckURL(),
- Blazy(),
- SubDomainTakeOver(),
- Dirb()
- ]
-
- def pretty_print(self):
- table = Table(title="Web Attack Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Web Attack Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
-if __name__ == "__main__":
- tools = WebAttackTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
diff --git a/tools/wireless_attack.py b/tools/wireless_attack.py
new file mode 100644
index 0000000..1c6c177
--- /dev/null
+++ b/tools/wireless_attack.py
@@ -0,0 +1,233 @@
+from rich.prompt import Prompt
+
+from core import HackingTool, HackingToolsCollection, console
+
+
+class WIFIPumpkin(HackingTool):
+ TITLE = "WiFi-Pumpkin"
+ DESCRIPTION = (
+ "The WiFi-Pumpkin is a rogue AP framework to easily create fake networks\n"
+ "while forwarding legitimate traffic to and from the unsuspecting target."
+ )
+ INSTALL_COMMANDS = [
+ "sudo apt install -y libssl-dev libffi-dev build-essential python3-pyqt5",
+ "git clone https://github.com/P0cL4bs/wifipumpkin3.git",
+ "chmod -R 755 wifipumpkin3",
+ "cd wifipumpkin3 && pip install --user .",
+ ]
+ RUN_COMMANDS = ["sudo wifipumpkin3"]
+ PROJECT_URL = "https://github.com/P0cL4bs/wifipumpkin3"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+
+class pixiewps(HackingTool):
+ TITLE = "pixiewps"
+ DESCRIPTION = (
+ "Pixiewps is a tool written in C used to bruteforce offline the WPS pin\n"
+ "exploiting the low or non-existing entropy of some Access Points "
+ "(pixie dust attack)."
+ )
+ INSTALL_COMMANDS = [
+ # Bug 29 fix: removed wget https://pastebin.com/... (insecure download from pastebin)
+ "git clone https://github.com/wiire/pixiewps.git && apt-get -y install build-essential",
+ "cd pixiewps && make",
+ "cd pixiewps && sudo make install",
+ ]
+ PROJECT_URL = "https://github.com/wiire/pixiewps"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+ def run(self):
+ console.print(
+ "[bold cyan]Usage:[/bold cyan]\n"
+ " 1. Put interface into monitor mode: [yellow]airmon-ng start [/yellow]\n"
+ " 2. Scan: [yellow]wash -i [/yellow]\n"
+ " 3. Attack: [yellow]reaver -i -b -c -vvv -K 1 -f[/yellow]\n"
+ " 4. Run: [yellow]pixiewps -h[/yellow]"
+ )
+
+
+class BluePot(HackingTool):
+ TITLE = "Bluetooth Honeypot GUI Framework"
+ DESCRIPTION = (
+ "You need at least 1 bluetooth receiver.\n"
+ "Install libbluetooth-dev (Ubuntu) / bluez-libs-devel (Fedora) / bluez-devel (openSUSE)."
+ )
+ INSTALL_COMMANDS = [
+ # Bug 15 fix: missing comma caused implicit string concatenation — two strings joined
+ "sudo wget https://raw.githubusercontent.com/andrewmichaelsmith/bluepot/master/bin/bluepot-0.2.tar.gz",
+ "sudo tar xfz bluepot-0.2.tar.gz && sudo rm bluepot-0.2.tar.gz",
+ ]
+ RUN_COMMANDS = ["cd bluepot && sudo java -jar bluepot.jar"]
+ PROJECT_URL = "https://github.com/andrewmichaelsmith/bluepot"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_JAVA = True
+
+
+class Fluxion(HackingTool):
+ TITLE = "Fluxion"
+ DESCRIPTION = "Fluxion is a remake of linset by vk496 with enhanced functionality."
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/FluxionNetwork/fluxion.git",
+ "cd fluxion && chmod +x fluxion.sh",
+ ]
+ RUN_COMMANDS = ["cd fluxion && sudo bash fluxion.sh -i"]
+ PROJECT_URL = "https://github.com/FluxionNetwork/fluxion"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+
+class Wifiphisher(HackingTool):
+ TITLE = "Wifiphisher"
+ DESCRIPTION = (
+ "Wifiphisher is a rogue Access Point framework for conducting red team engagements\n"
+ "or Wi-Fi security testing. Easily achieve man-in-the-middle position against\n"
+ "wireless clients by performing targeted Wi-Fi association attacks."
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/wifiphisher/wifiphisher.git",
+ "cd wifiphisher && pip install --user .",
+ ]
+ RUN_COMMANDS = ["cd wifiphisher && sudo wifiphisher"]
+ PROJECT_URL = "https://github.com/wifiphisher/wifiphisher"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+
+class Wifite(HackingTool):
+ TITLE = "Wifite"
+ DESCRIPTION = "Wifite is an automated wireless attack tool."
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/derv82/wifite2.git",
+ "cd wifite2 && pip install --user .",
+ ]
+ RUN_COMMANDS = ["sudo wifite"]
+ PROJECT_URL = "https://github.com/derv82/wifite2"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+
+class EvilTwin(HackingTool):
+ TITLE = "EvilTwin"
+ DESCRIPTION = (
+ "Fakeap — perform Evil Twin Attack by getting credentials "
+ "using a Fake page and Fake Access Point."
+ )
+ INSTALL_COMMANDS = ["git clone https://github.com/Z4nzu/fakeap.git"]
+ RUN_COMMANDS = ["cd fakeap && sudo bash fakeap.sh"]
+ PROJECT_URL = "https://github.com/Z4nzu/fakeap"
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+
+class Fastssh(HackingTool):
+ TITLE = "Fastssh"
+ DESCRIPTION = (
+ "Fastssh — multi-threaded scan and brute force attack against SSH protocol\n"
+ "using the most commonly used credentials."
+ )
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/Z4nzu/fastssh.git && cd fastssh && chmod +x fastssh.sh",
+ "sudo apt-get install -y sshpass netcat",
+ ]
+ RUN_COMMANDS = ["cd fastssh && sudo bash fastssh.sh --scan"]
+ PROJECT_URL = "https://github.com/Z4nzu/fastssh"
+ SUPPORTED_OS = ["linux"]
+
+
+class Howmanypeople(HackingTool):
+ TITLE = "Howmanypeople"
+ DESCRIPTION = (
+ "Count the number of people around you by monitoring wifi signals.\n"
+ "[@] WIFI ADAPTER REQUIRED\n"
+ "[*] It may be illegal to monitor networks for MAC addresses on networks you do not own."
+ )
+ INSTALL_COMMANDS = [
+ # Bug 14 fix: missing comma caused "sudo apt-get install tshark;sudo python3..."
+ # to be one implicitly concatenated string — only first command ran
+ "sudo apt-get install -y tshark",
+ "sudo python3 -m pip install howmanypeoplearearound",
+ ]
+ RUN_COMMANDS = ["howmanypeoplearearound"]
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+
+
+class Airgeddon(HackingTool):
+ TITLE = "Airgeddon (Wireless Attack Suite)"
+ DESCRIPTION = (
+ "Multi-use bash script for auditing wireless networks.\n"
+ "Covers WPA/WPA2, WEP, WPS, PMKID, evil twin, handshake capture and more."
+ )
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/v1s1t0r1sh3r3/airgeddon.git",
+ ]
+ RUN_COMMANDS = ["cd airgeddon && sudo bash airgeddon.sh"]
+ PROJECT_URL = "https://github.com/v1s1t0r1sh3r3/airgeddon"
+
+
+class Hcxdumptool(HackingTool):
+ TITLE = "hcxdumptool (PMKID Capture)"
+ DESCRIPTION = (
+ "Capture packets and PMKID hashes from WLAN devices.\n"
+ "Usage: hcxdumptool -i -o capture.pcapng --enable_status=1"
+ )
+ SUPPORTED_OS = ["linux"]
+ REQUIRES_WIFI = True
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/ZerBea/hcxdumptool.git",
+ "cd hcxdumptool && make && sudo make install",
+ ]
+ RUN_COMMANDS = ["hcxdumptool --help"]
+ PROJECT_URL = "https://github.com/ZerBea/hcxdumptool"
+
+
+class Hcxtools(HackingTool):
+ TITLE = "hcxtools (PMKID/Hash Conversion)"
+ DESCRIPTION = (
+ "Convert captured WLAN packets to hashcat/JtR-compatible format.\n"
+ "Usage: hcxpcapngtool -o hashes.txt capture.pcapng"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = [
+ "git clone https://github.com/ZerBea/hcxtools.git",
+ "cd hcxtools && make && sudo make install",
+ ]
+ RUN_COMMANDS = ["hcxpcapngtool --help"]
+ PROJECT_URL = "https://github.com/ZerBea/hcxtools"
+
+
+class Bettercap(HackingTool):
+ TITLE = "Bettercap (Network/WiFi/BLE MITM)"
+ DESCRIPTION = "Swiss army knife for WiFi, BLE, HID, and Ethernet network recon and MITM attacks."
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt-get install -y bettercap"]
+ RUN_COMMANDS = ["sudo bettercap --help"]
+ PROJECT_URL = "https://github.com/bettercap/bettercap"
+
+
+class WirelessAttackTools(HackingToolsCollection):
+ TITLE = "Wireless attack tools"
+ TOOLS = [
+ WIFIPumpkin(),
+ pixiewps(),
+ BluePot(),
+ Fluxion(),
+ Wifiphisher(),
+ Wifite(),
+ EvilTwin(),
+ Fastssh(),
+ Howmanypeople(),
+ Airgeddon(),
+ Hcxdumptool(),
+ Hcxtools(),
+ Bettercap(),
+ ]
+
+
+if __name__ == "__main__":
+ tools = WirelessAttackTools()
+ tools.show_options()
diff --git a/tools/wireless_attack_tools.py b/tools/wireless_attack_tools.py
deleted file mode 100644
index 387ec32..0000000
--- a/tools/wireless_attack_tools.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# coding=utf-8
-import os
-import subprocess
-
-from core import HackingTool
-from core import HackingToolsCollection
-
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
-from rich.panel import Panel
-from rich.prompt import Prompt
-
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
-
-
-class WIFIPumpkin(HackingTool):
- TITLE = "WiFi-Pumpkin"
- DESCRIPTION = (
- "The WiFi-Pumpkin is a rogue AP framework to easily create "
- "these fake networks\n"
- "all while forwarding legitimate traffic to and from the "
- "unsuspecting target."
- )
- INSTALL_COMMANDS = [
- "sudo apt install libssl-dev libffi-dev build-essential",
- "sudo git clone https://github.com/P0cL4bs/wifipumpkin3.git",
- "chmod -R 755 wifipumpkin3",
- "sudo apt install python3-pyqt5",
- "cd wifipumpkin3;sudo python3 setup.py install",
- ]
- RUN_COMMANDS = ["sudo wifipumpkin3"]
- PROJECT_URL = "https://github.com/P0cL4bs/wifipumpkin3"
-
-
-class pixiewps(HackingTool):
- TITLE = "pixiewps"
- DESCRIPTION = (
- "Pixiewps is a tool written in C used to bruteforce offline "
- "the WPS pin\n "
- "exploiting the low or non-existing entropy of some Access "
- "Points, the so-called pixie dust attack"
- )
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/wiire/pixiewps.git && apt-get -y install build-essential",
- "cd pixiewps*/ && make",
- "cd pixiewps*/ && sudo make install && wget https://pastebin.com/y9Dk1Wjh",
- ]
- PROJECT_URL = "https://github.com/wiire/pixiewps"
-
- def run(self):
- os.system(
- 'echo "'
- '1.> Put your interface into monitor mode using '
- "'airmon-ng start {wireless interface}\n'"
- "'2.> wash -i {monitor-interface like mon0}\'\n'"
- "'3.> reaver -i {monitor interface} -b {BSSID of router} -c {router channel} -vvv -K 1 -f"
- '| boxes -d boy'
- )
- print("You Have To Run Manually By USing >>pixiewps -h ")
-
-
-class BluePot(HackingTool):
- TITLE = "Bluetooth Honeypot GUI Framework"
- DESCRIPTION = (
- "You need to have at least 1 bluetooth receiver "
- "(if you have many it will work with those, too).\n"
- "You must install/libbluetooth-dev on "
- "Ubuntu/bluez-libs-devel on Fedora/bluez-devel on openSUSE"
- )
- INSTALL_COMMANDS = [
- "sudo wget https://raw.githubusercontent.com/andrewmichaelsmith/bluepot/master/bin/bluepot-0.2.tar.gz"
- "sudo tar xfz bluepot-0.2.tar.gz;sudo rm bluepot-0.2.tar.gz"
- ]
- RUN_COMMANDS = ["cd bluepot && sudo java -jar bluepot.jar"]
- PROJECT_URL = "https://github.com/andrewmichaelsmith/bluepot"
-
-
-class Fluxion(HackingTool):
- TITLE = "Fluxion"
- DESCRIPTION = "Fluxion is a remake of linset by vk496 with enhanced functionality."
- INSTALL_COMMANDS = [
- "git clone https://github.com/FluxionNetwork/fluxion.git",
- "cd fluxion && sudo chmod +x fluxion.sh",
- ]
- RUN_COMMANDS = ["cd fluxion;sudo bash fluxion.sh -i"]
- PROJECT_URL = "https://github.com/FluxionNetwork/fluxion"
-
-
-class Wifiphisher(HackingTool):
- TITLE = "Wifiphisher"
- DESCRIPTION = """
- Wifiphisher is a rogue Access Point framework for conducting red team engagements or Wi-Fi security testing.
- Using Wifiphisher, penetration testers can easily achieve a man-in-the-middle position against wireless clients by performing
- targeted Wi-Fi association attacks. Wifiphisher can be further used to mount victim-customized web phishing attacks against the
- connected clients in order to capture credentials (e.g. from third party login pages or WPA/WPA2 Pre-Shared Keys) or infect the
- victim stations with malware..\n
- For More Details Visit >> https://github.com/wifiphisher/wifiphisher
- """
- INSTALL_COMMANDS = [
- "git clone https://github.com/wifiphisher/wifiphisher.git",
- "cd wifiphisher;sudo python3 setup.py install",
- ]
- RUN_COMMANDS = ["cd wifiphisher;sudo wifiphisher"]
- PROJECT_URL = "https://github.com/wifiphisher/wifiphisher"
-
-
-class Wifite(HackingTool):
- TITLE = "Wifite"
- DESCRIPTION = "Wifite is an automated wireless attack tool"
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/derv82/wifite2.git",
- "cd wifite2 && sudo python3 setup.py install",
- ]
- RUN_COMMANDS = ["cd wifite2; sudo wifite"]
- PROJECT_URL = "https://github.com/derv82/wifite2"
-
-
-class EvilTwin(HackingTool):
- TITLE = "EvilTwin"
- DESCRIPTION = (
- "Fakeap is a script to perform Evil Twin Attack, by getting"
- " credentials using a Fake page and Fake Access Point"
- )
- INSTALL_COMMANDS = ["sudo git clone https://github.com/Z4nzu/fakeap.git"]
- RUN_COMMANDS = ["cd fakeap && sudo bash fakeap.sh"]
- PROJECT_URL = "https://github.com/Z4nzu/fakeap"
-
-
-class Fastssh(HackingTool):
- TITLE = "Fastssh"
- DESCRIPTION = (
- "Fastssh is an Shell Script to perform multi-threaded scan"
- " \n and brute force attack against SSH protocol using the "
- "most commonly credentials."
- )
- INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Z4nzu/fastssh.git && cd fastssh && sudo chmod +x fastssh.sh",
- "sudo apt-get install -y sshpass netcat",
- ]
- RUN_COMMANDS = ["cd fastssh && sudo bash fastssh.sh --scan"]
- PROJECT_URL = "https://github.com/Z4nzu/fastssh"
-
-
-class Howmanypeople(HackingTool):
- TITLE = "Howmanypeople"
- DESCRIPTION = (
- "Count the number of people around you by monitoring wifi "
- "signals.\n"
- "[@] WIFI ADAPTER REQUIRED* \n[*]"
- "It may be illegal to monitor networks for MAC addresses, \n"
- "especially on networks that you do not own. "
- "Please check your country's laws"
- )
- INSTALL_COMMANDS = [
- "sudo apt-get install tshark"
- ";sudo python3 -m pip install howmanypeoplearearound"
- ]
- RUN_COMMANDS = ["howmanypeoplearearound"]
-
-
-class WirelessAttackTools(HackingToolsCollection):
- TITLE = "Wireless attack tools"
- DESCRIPTION = ""
- TOOLS = [
- WIFIPumpkin(),
- pixiewps(),
- BluePot(),
- Fluxion(),
- Wifiphisher(),
- Wifite(),
- EvilTwin(),
- Fastssh(),
- Howmanypeople(),
- ]
-
- def pretty_print(self):
- table = Table(title="Wireless Attack Tools", show_lines=True, expand=True)
- table.add_column("Title", style="purple", no_wrap=True)
- table.add_column("Description", style="purple")
- table.add_column("Project URL", style="purple", no_wrap=True)
-
- for t in self.TOOLS:
- desc = getattr(t, "DESCRIPTION", "") or ""
- url = getattr(t, "PROJECT_URL", "") or ""
- table.add_row(t.TITLE, desc.strip().replace("\n", " "), url)
-
- panel = Panel(table, title="[purple]Available Tools[/purple]", border_style="purple")
- console.print(panel)
-
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Wireless Attack Tools Collection[/bold magenta]\n"
- "Select a tool to view options or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_options"):
- selected.show_options(parent=self)
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
-if __name__ == "__main__":
- tools = WirelessAttackTools()
- tools.pretty_print()
- tools.show_options()
\ No newline at end of file
diff --git a/tools/wordlist_generator.py b/tools/wordlist_generator.py
index 109dcd5..44f9aab 100644
--- a/tools/wordlist_generator.py
+++ b/tools/wordlist_generator.py
@@ -1,25 +1,18 @@
-# coding=utf-8
import os
import subprocess
-from rich.console import Console
-from rich.theme import Theme
-from rich.table import Table
from rich.panel import Panel
from rich.prompt import Prompt
+from rich.table import Table
from rich import box
-from core import HackingTool
-from core import HackingToolsCollection
-
-_theme = Theme({"purple": "#7B61FF"})
-console = Console(theme=_theme)
+from core import HackingTool, HackingToolsCollection, console
class Cupp(HackingTool):
TITLE = "Cupp"
- DESCRIPTION = "WlCreator is a C program that can create all possibilities of passwords,\n " \
- "and you can choose Length, Lowercase, Capital, Numbers and Special Chars"
+ # Bug 24 fix: DESCRIPTION was copy-pasted from WlCreator — completely wrong
+ DESCRIPTION = "Common User Passwords Profiler — generates personalized wordlists based on target info."
INSTALL_COMMANDS = ["git clone https://github.com/Mebus/cupp.git"]
RUN_COMMANDS = ["cd cupp && python3 cupp.py -i"]
PROJECT_URL = "https://github.com/Mebus/cupp"
@@ -40,7 +33,7 @@ class WlCreator(HackingTool):
DESCRIPTION = "WlCreator is a C program that can create all possibilities" \
" of passwords,\n and you can choose Length, Lowercase, " \
"Capital, Numbers and Special Chars"
- INSTALL_COMMANDS = ["sudo git clone https://github.com/Z4nzu/wlcreator.git"]
+ INSTALL_COMMANDS = ["git clone https://github.com/Z4nzu/wlcreator.git"]
RUN_COMMANDS = [
"cd wlcreator && sudo gcc -o wlcreator wlcreator.c && ./wlcreator 5"]
PROJECT_URL = "https://github.com/Z4nzu/wlcreator"
@@ -60,7 +53,7 @@ class GoblinWordGenerator(HackingTool):
TITLE = "Goblin WordGenerator"
DESCRIPTION = "Goblin WordGenerator"
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/UndeadSec/GoblinWordGenerator.git"]
+ "git clone https://github.com/UndeadSec/GoblinWordGenerator.git"]
RUN_COMMANDS = ["cd GoblinWordGenerator && python3 goblin.py"]
PROJECT_URL = "https://github.com/UndeadSec/GoblinWordGenerator.git"
@@ -83,7 +76,7 @@ class showme(HackingTool):
"part of BreachCompilation leak. This database makes " \
"finding passwords faster and easier than ever before."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/Viralmaniar/SMWYG-Show-Me-What-You-Got.git",
+ "git clone https://github.com/Viralmaniar/SMWYG-Show-Me-What-You-Got.git",
"cd SMWYG-Show-Me-What-You-Got && pip3 install -r requirements.txt"
]
RUN_COMMANDS = ["cd SMWYG-Show-Me-What-You-Got && python SMWYG.py"]
@@ -100,13 +93,52 @@ class showme(HackingTool):
console.print(panel)
+class Hashcat(HackingTool):
+ TITLE = "Hashcat (Password Cracker)"
+ DESCRIPTION = (
+ "World's fastest GPU/CPU password recovery tool — supports 300+ hash types.\n"
+ "Usage: hashcat -m 0 -a 0 hashes.txt wordlist.txt"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt-get install -y hashcat"]
+ RUN_COMMANDS = ["hashcat --help"]
+ PROJECT_URL = "https://github.com/hashcat/hashcat"
+
+
+class JohnTheRipper(HackingTool):
+ TITLE = "John the Ripper"
+ DESCRIPTION = (
+ "Open-source password security auditing and recovery tool.\n"
+ "Usage: john --wordlist=wordlist.txt hashfile"
+ )
+ SUPPORTED_OS = ["linux"]
+ INSTALL_COMMANDS = ["sudo apt-get install -y john"]
+ RUN_COMMANDS = ["john --help"]
+ PROJECT_URL = "https://github.com/openwall/john"
+
+
+class Haiti(HackingTool):
+ TITLE = "haiti (Hash Type Identifier)"
+ DESCRIPTION = (
+ "Identify hash types — supports 300+ algorithms.\n"
+ "Usage: haiti "
+ )
+ REQUIRES_RUBY = True
+ INSTALL_COMMANDS = ["gem install haiti-hash"]
+ RUN_COMMANDS = ["haiti --help"]
+ PROJECT_URL = "https://github.com/noraj/haiti"
+
+
class WordlistGeneratorTools(HackingToolsCollection):
TITLE = "Wordlist Generator"
TOOLS = [
Cupp(),
WlCreator(),
GoblinWordGenerator(),
- showme()
+ showme(),
+ Hashcat(),
+ JohnTheRipper(),
+ Haiti(),
]
def show_info(self):
@@ -125,45 +157,7 @@ class WordlistGeneratorTools(HackingToolsCollection):
table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
console.print(table)
- def show_options(self, parent=None):
- console.print("\n")
- panel = Panel.fit("[bold magenta]Wordlist Generator Collection[/bold magenta]\n"
- "Select a tool to view details or run it.",
- border_style="purple")
- console.print(panel)
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True, expand=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- title = getattr(tool, "TITLE", tool.__class__.__name__)
- desc = getattr(tool, "DESCRIPTION", "—")
- table.add_row(str(i + 1), title, desc or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to previous menu")
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to view/run[/bold cyan]", default="99")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- selected = self.TOOLS[choice - 1]
- if hasattr(selected, "show_info"):
- selected.show_info()
- elif hasattr(selected, "run"):
- selected.run()
- else:
- console.print("[bold yellow]Selected tool has no runnable interface.[/bold yellow]")
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
-
-
if __name__ == "__main__":
tools = WordlistGeneratorTools()
tools.show_info()
- tools.show_options()
\ No newline at end of file
+ tools.show_options()
diff --git a/tools/xss_attack.py b/tools/xss_attack.py
index 9bdd47f..ba406f6 100644
--- a/tools/xss_attack.py
+++ b/tools/xss_attack.py
@@ -1,28 +1,20 @@
-# coding=utf-8
import os
import subprocess
-from rich.console import Console
from rich.panel import Panel
from rich.prompt import Prompt
-from rich.table import Table
-from core import HackingTool
-from core import HackingToolsCollection
-
-console = Console()
+from core import HackingTool, HackingToolsCollection, console
class Dalfox(HackingTool):
TITLE = "DalFox (Finder of XSS)"
DESCRIPTION = "XSS Scanning and Parameter Analysis tool."
INSTALL_COMMANDS = [
- "sudo apt-get install golang",
- "sudo git clone https://github.com/hahwul/dalfox",
- "cd dalfox;go install"
+ "sudo apt-get install -y golang",
+ "go install github.com/hahwul/dalfox/v2@latest",
]
RUN_COMMANDS = [
- "~/go/bin/dalfox",
- 'echo "You Need To Run manually by using [!]~/go/bin/dalfox [options]"'
+ "~/go/bin/dalfox --help",
]
PROJECT_URL = "https://github.com/hahwul/dalfox"
@@ -99,8 +91,9 @@ class XSSCon(HackingTool):
border_style="bright_yellow"
))
website = Prompt.ask("[bold cyan]Enter Website[/bold cyan]")
- os.system("cd XSSCon;")
- subprocess.run(["python3", "xsscon.py", "-u", website])
+ from config import get_tools_dir
+ subprocess.run(["python3", "xsscon.py", "-u", website],
+ cwd=str(get_tools_dir() / "XSSCon"))
class XanXSS(HackingTool):
@@ -110,10 +103,9 @@ class XanXSS(HackingTool):
PROJECT_URL = "https://github.com/Ekultek/XanXSS"
def run(self):
- os.system("cd XanXSS; python xanxss.py -h")
- console.print(
- "[cyan]You have to run it manually using:[/cyan]\n[bold yellow]python xanxss.py [options][/bold yellow]"
- )
+ from config import get_tools_dir
+ subprocess.run(["python3", "xanxss.py", "-h"],
+ cwd=str(get_tools_dir() / "XanXSS"))
class XSSStrike(HackingTool):
@@ -127,14 +119,15 @@ class XSSStrike(HackingTool):
PROJECT_URL = "https://github.com/UltimateHackers/XSStrike"
def __init__(self):
- super(XSSStrike, self).__init__(runnable=False)
+ super().__init__(runnable=False)
class RVuln(HackingTool):
TITLE = "RVuln"
+ SUPPORTED_OS = ["linux"]
DESCRIPTION = "Multi-threaded and Automated Web Vulnerability Scanner written in Rust."
INSTALL_COMMANDS = [
- "sudo git clone https://github.com/iinc0gnit0/RVuln.git;"
+ "git clone https://github.com/iinc0gnit0/RVuln.git;"
"curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh;"
"source $HOME/.cargo/env;"
"sudo apt install librust-openssl-dev;"
@@ -164,30 +157,3 @@ class XSSAttackTools(HackingToolsCollection):
"A curated set of tools for XSS vulnerability analysis and exploitation.",
border_style="bright_magenta"
))
-
- def show_options(self, parent=None):
- console.print("\n")
- self.show_info()
-
- table = Table(title="[bold cyan]Available Tools[/bold cyan]", show_lines=True)
- table.add_column("Index", justify="center", style="bold yellow")
- table.add_column("Tool Name", justify="left", style="bold green")
- table.add_column("Description", justify="left", style="white")
-
- for i, tool in enumerate(self.TOOLS):
- table.add_row(str(i + 1), tool.TITLE, tool.DESCRIPTION or "—")
-
- table.add_row("[red]99[/red]", "[bold red]Exit[/bold red]", "Return to Main Menu")
-
- console.print(table)
-
- try:
- choice = Prompt.ask("[bold cyan]Select a tool to run[/bold cyan]")
- choice = int(choice)
- if 1 <= choice <= len(self.TOOLS):
- self.TOOLS[choice - 1].show_options(parent=self)
- elif choice == 99:
- return 99
- except Exception:
- console.print("[bold red]Invalid choice. Try again.[/bold red]")
- return self.show_options(parent=parent)
diff --git a/update.sh b/update.sh
index 4f6554b..ec80550 100644
--- a/update.sh
+++ b/update.sh
@@ -1,51 +1,34 @@
#!/bin/bash
+set -euo pipefail
-RED='\e[1;31m'
-GREEN='\e[1;32m'
-YELLOW='\e[1;33m'
-BLUE='\e[1;34m'
+INSTALL_DIR="/usr/share/hackingtool"
-echo "███████╗██╗ ██╗███╗ ██╗███████╗██╗ ██╗ ";
-echo "╚══███╔╝██║ ██║████╗ ██║╚══███╔╝██║ ██║ ";
-echo " ███╔╝ ███████║██╔██╗ ██║ ███╔╝ ██║ ██║ ";
-echo " ███╔╝ ╚════██║██║╚██╗██║ ███╔╝ ██║ ██║ ";
-echo "███████╗ ██║██║ ╚████║███████╗╚██████╔╝ ";
-echo "╚══════╝ ╚═╝╚═╝ ╚═══╝╚══════╝ ╚═════╝ ";
-echo " ";
-
-# Check if the script is run as root
if [[ $EUID -ne 0 ]]; then
- echo -e "${RED}[ERROR]\e[0m This script must be run as root."
- exit 1
+ echo "[ERROR] Run as root: sudo bash update.sh"
+ exit 1
fi
-install_dir="/usr/share/hackingtool"
-# Change to the directory containing the install.sh script
-cd $install_dir || { echo -e "${RED}[ERROR]\e[0m Could not change to directory containing install.sh."; exit 1; }
-echo -e "${YELLOW}[*] Checking Internet Connection ..${NC}"
-echo "";
-if curl -s -m 10 https://www.google.com > /dev/null || curl -s -m 10 https://www.github.com > /dev/null; then
- echo -e "${GREEN}[✔] Internet connection is OK [✔]${NC}"
- echo ""
+if [[ ! -d "$INSTALL_DIR" ]]; then
+ echo "[ERROR] Installation not found at $INSTALL_DIR. Run install.py first."
+ exit 1
+fi
+
+echo "[*] Checking internet connection..."
+if ! curl -sSf --max-time 10 https://github.com > /dev/null; then
+ echo "[ERROR] No internet connection."
+ exit 1
+fi
+echo "[✔] Internet OK"
+
+echo "[*] Pulling latest changes..."
+git -C "$INSTALL_DIR" config --local safe.directory "$INSTALL_DIR"
+git -C "$INSTALL_DIR" pull --rebase
+
+echo "[*] Updating Python dependencies..."
+if [[ -f "$INSTALL_DIR/venv/bin/pip" ]]; then
+ "$INSTALL_DIR/venv/bin/pip" install -q --upgrade -r "$INSTALL_DIR/requirements.txt"
else
- echo -e "${RED}[✘] Please check your internet connection[✘]"
- echo ""
- exit 1
-fi
-echo -e "[*]Marking hackingtool directory as safe-directory"
-git config --global --add safe.directory $install_dir
-# Update the repository and the tool itself
-echo -e "${BLUE}[INFO]\e[0m Updating repository and tool..."
-if ! sudo git pull; then
- echo -e "${RED}[ERROR]\e[0m Failed to update repository or tool."
- exit 1
+ echo "[WARN] venv not found — skipping pip update. Run install.py to create it."
fi
-# Re-run the installation script
-echo -e "${GREEN}[INFO]\e[0m Running installation script..."
-if ! sudo bash install.sh; then
- echo -e "${RED}[ERROR]\e[0m Failed to run installation script."
- exit 1
-fi
-
-echo -e "${GREEN}[SUCCESS]\e[0m Tool updated successfully."
+echo "[✔] Hackingtool updated. Run 'hackingtool' to start."