mirror of
https://github.com/Z4nzu/hackingtool
synced 2026-05-23 00:49:59 +00:00
Phase 3: Installation & path overhaul
This commit is contained in:
parent
a46f01005b
commit
08f1e3e063
4 changed files with 349 additions and 370 deletions
184
hackingtool.py
184
hackingtool.py
|
|
@ -1,23 +1,31 @@
|
|||
#!/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 webbrowser
|
||||
from platform import system
|
||||
from time import sleep
|
||||
|
||||
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 IntPrompt, 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 core import HackingToolsCollection
|
||||
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
|
||||
|
|
@ -40,36 +48,36 @@ from tools.xss_attack import XSSAttackTools
|
|||
console = Console()
|
||||
|
||||
ASCII_LOGO = r"""
|
||||
▄█ █▄ ▄████████ ▄████████ ▄█ ▄█▄ ▄█ ███▄▄▄▄ ▄██████▄ ███ ▄██████▄ ▄██████▄ ▄█
|
||||
███ ███ ███ ███ ███ ███ ███ ▄███▀ ███ ███▀▀▀██▄ ███ ███ ▀█████████▄ ███ ███ ███ ███ ███
|
||||
███ ███ ███ ███ ███ █▀ ███▐██▀ ███▌ ███ ███ ███ █▀ ▀███▀▀██ ███ ███ ███ ███ ███
|
||||
▄███▄▄▄▄███▄▄ ███ ███ ███ ▄█████▀ ███▌ ███ ███ ▄███ ███ ▀ ███ ███ ███ ███ ███
|
||||
▀▀███▀▀▀▀███▀ ▀███████████ ███ ▀▀█████▄ ███▌ ███ ███ ▀▀███ ████▄ ███ ███ ███ ███ ███ ███
|
||||
███ ███ ███ ███ ███ █▄ ███▐██▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
|
||||
███ ███ ███ ███ ███ ███ ███ ▀███▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███▌ ▄
|
||||
███ █▀ ███ █▀ ████████▀ ███ ▀█▀ █▀ ▀█ █▀ ████████▀ ▄████▀ ▀██████▀ ▀██████▀ █████▄▄██
|
||||
▀ ▀
|
||||
▄█ █▄ ▄████████ ▄████████ ▄█ ▄█▄ ▄█ ███▄▄▄▄ ▄██████▄ ███ ▄██████▄ ▄██████▄ ▄█
|
||||
███ ███ ███ ███ ███ ███ ███ ▄███▀ ███ ███▀▀▀██▄ ███ ███ ▀█████████▄ ███ ███ ███ ███ ███
|
||||
███ ███ ███ ███ ███ █▀ ███▐██▀ ███▌ ███ ███ ███ █▀ ▀███▀▀██ ███ ███ ███ ███ ███
|
||||
▄███▄▄▄▄███▄▄ ███ ███ ███ ▄█████▀ ███▌ ███ ███ ▄███ ███ ▀ ███ ███ ███ ███ ███
|
||||
▀▀███▀▀▀▀███▀ ▀███████████ ███ ▀▀█████▄ ███▌ ███ ███ ▀▀███ ████▄ ███ ███ ███ ███ ███ ███
|
||||
███ ███ ███ ███ ███ █▄ ███▐██▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███
|
||||
███ ███ ███ ███ ███ ███ ███ ▀███▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███▌ ▄
|
||||
███ █▀ ███ █▀ ████████▀ ███ ▀█▀ █▀ ▀█ █▀ ████████▀ ▄████▀ ▀██████▀ ▀██████▀ █████▄▄██
|
||||
▀ ▀
|
||||
"""
|
||||
|
||||
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", "🛡️"),
|
||||
("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", "💥"),
|
||||
("Steganography tools", "🖼️"),
|
||||
("Other tools", "✨"),
|
||||
("Update or Uninstall | Hackingtool", "♻️"),
|
||||
]
|
||||
|
||||
all_tools = [
|
||||
|
|
@ -90,7 +98,7 @@ all_tools = [
|
|||
XSSAttackTools(),
|
||||
SteganographyTools(),
|
||||
OtherTools(),
|
||||
ToolManager()
|
||||
ToolManager(),
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -99,20 +107,18 @@ class AllTools(HackingToolsCollection):
|
|||
TOOLS = all_tools
|
||||
|
||||
def show_info(self):
|
||||
header = Text()
|
||||
header.append(ASCII_LOGO, style="bold magenta")
|
||||
header.append("\n\n",)
|
||||
header = Text(ASCII_LOGO, style="bold magenta")
|
||||
footer = Text.assemble(
|
||||
(" https://github.com/Z4nzu/hackingtool ", "bold bright_black"),
|
||||
(f" {REPO_WEB_URL} ", "bold bright_black"),
|
||||
(" | ",),
|
||||
("Version 1.1.0", "bold green"),
|
||||
(VERSION_DISPLAY, "bold green"),
|
||||
)
|
||||
warning = Text(" Please Don't Use For illegal Activity ", style="bold red")
|
||||
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"
|
||||
border_style="magenta",
|
||||
)
|
||||
console.print(panel)
|
||||
|
||||
|
|
@ -123,55 +129,32 @@ def build_menu():
|
|||
table.add_column("name", justify="left")
|
||||
|
||||
for idx, (title, icon) in enumerate(tool_definitions):
|
||||
if idx == 17:
|
||||
if idx == len(tool_definitions) - 1:
|
||||
label = "[bold magenta]99[/bold magenta]"
|
||||
name = f"[bold magenta]{icon} {title}[/bold magenta]"
|
||||
name = f"[bold magenta]{icon} {title}[/bold magenta]"
|
||||
else:
|
||||
label = f"[bold magenta]{idx}[/bold magenta]"
|
||||
name = f"[white]{icon}[/white] [magenta]{title}[/magenta]"
|
||||
name = f"[white]{icon}[/white] [magenta]{title}[/magenta]"
|
||||
table.add_row(label, name)
|
||||
|
||||
top_panel = Panel(
|
||||
console.print(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(
|
||||
style="magenta", padding=(0, 1), box=box.ROUNDED,
|
||||
))
|
||||
console.print(Panel.fit(
|
||||
table,
|
||||
title="[bold magenta]Select a tool[/bold magenta]",
|
||||
border_style="bright_magenta",
|
||||
box=box.SQUARE
|
||||
)
|
||||
footer = Align.center(Text("Choose number and press Enter — 99 to exit", style="italic bright_black"))
|
||||
console.print(top_panel)
|
||||
console.print(menu_panel)
|
||||
box=box.SQUARE,
|
||||
))
|
||||
console.print(Rule(style="bright_black"))
|
||||
console.print(footer)
|
||||
console.print(Align.center(Text(
|
||||
"Choose number and press Enter — 99 to exit",
|
||||
style="italic bright_black",
|
||||
)))
|
||||
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
|
||||
|
||||
|
||||
def interact_menu():
|
||||
while True:
|
||||
try:
|
||||
|
|
@ -183,13 +166,11 @@ def interact_menu():
|
|||
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}"))
|
||||
console.print(Panel(
|
||||
f"[bold magenta]{tool_definitions[choice][1]} Selected:[/bold magenta] [white]{name}[/white]"
|
||||
))
|
||||
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]")
|
||||
tool.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):
|
||||
|
|
@ -198,29 +179,32 @@ def interact_menu():
|
|||
else:
|
||||
console.print("[red]Invalid selection. Pick a number from the menu.[/red]")
|
||||
except KeyboardInterrupt:
|
||||
console.print("\n[bold red]Interrupted by user — exiting[/bold red]")
|
||||
console.print("\n[bold red]Interrupted — exiting[/bold red]")
|
||||
break
|
||||
|
||||
|
||||
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]")
|
||||
|
||||
# Ensure ~/.hackingtool/tools/ exists — no os.chdir(), tools use absolute paths
|
||||
tools_dir = get_tools_dir()
|
||||
console.print(f"[dim]Tools directory: {tools_dir}[/dim]")
|
||||
|
||||
AllTools().show_info()
|
||||
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__":
|
||||
|
|
|
|||
324
install.py
324
install.py
|
|
@ -1,207 +1,249 @@
|
|||
#!/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
|
||||
|
||||
# Update index first (skip for brew — not needed)
|
||||
if mgr != "brew":
|
||||
update_cmd = PACKAGE_UPDATE_CMDS.get(mgr, "")
|
||||
if update_cmd:
|
||||
priv = "" if CURRENT_OS.system == "macos" else "sudo "
|
||||
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))
|
||||
priv = "" if CURRENT_OS.system == "macos" else "sudo "
|
||||
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 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 git_clone() -> bool:
|
||||
console.print(f"[dim]Cloning {REPO_URL}...[/dim]")
|
||||
r = subprocess.run(["git", "clone", REPO_URL, str(APP_INSTALL_DIR)], check=False)
|
||||
if r.returncode == 0:
|
||||
console.print("[success]✔ Repository cloned[/success]")
|
||||
return True
|
||||
except Exception as e:
|
||||
console.print(f"[red][✘] Failed to clone repository: {e}[/red]")
|
||||
return False
|
||||
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 git_clone():
|
||||
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)
|
||||
|
|
|
|||
|
|
@ -1,126 +1,97 @@
|
|||
# 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" else "sudo "
|
||||
os.system(f"{priv}{cmd}")
|
||||
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()
|
||||
|
|
|
|||
66
update.sh
66
update.sh
|
|
@ -1,51 +1,33 @@
|
|||
#!/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" pull --rebase
|
||||
|
||||
echo "[*] Updating Python dependencies..."
|
||||
if [[ -f "$INSTALL_DIR/venv/bin/pip" ]]; then
|
||||
"$INSTALL_DIR/venv/bin/pip" install -q -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."
|
||||
|
|
|
|||
Loading…
Reference in a new issue