Toolbelt v2.0 - Complete refactor with interactive menus and profiles

Major rewrite from single-file script to modular architecture with comprehensive features:

## New Features
- Interactive 3-level menu system (Main → Categories → Tools)
- Pre-built profiles: Bug Bounty, CTF, Web App, Network, Full Pentest
- Distro detection with appropriate tool sets (Kali, Debian, Ubuntu)
- NO root requirement - runs as user, uses sudo selectively
- Comprehensive logging (console + ~/toolbelt-install.log)
- Fresh CLI tool integration and detection
- Smart tool detection (skips already-installed tools)

## Architecture Changes
- Modular design: utils.py, config.py, installer.py, toolbelt.py
- utils.py: Distro detection, logging setup, helper functions
- config.py: Tool definitions, profiles, category metadata
- installer.py: Installation logic for all tool categories
- toolbelt.py: Interactive menu system and main flow

## Improvements
- Fixed $HOME path resolution bug (no more /root issues)
- Added comprehensive error handling and reporting
- Category-based tool organization (APT, Go, /opt, Python, Docker, Scripts)
- Parallel Go tool installation with ThreadPoolExecutor
- Shell alias setup for Docker tools

## Documentation
- Complete README rewrite with usage examples
- Architecture diagrams and file structure
- Integration guide for fresh ecosystem
- Version history and changelog

## Archived Files
- toolbelt.sh → toolbelt.sh.old (legacy bash version)
- toolbelt.py → toolbelt_old.py (original Python v1.0)

Part of the Djedi security tooling ecosystem integration.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
rpriven 2025-10-31 23:17:41 -06:00
parent 848216cc8c
commit fd0659d70c
Signed by: djedi
GPG key ID: D04DED574622EF45
8 changed files with 2079 additions and 347 deletions

23
.gitignore vendored Normal file
View file

@ -0,0 +1,23 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
*.egg-info/
dist/
build/
# Logs
*.log
# IDE
.vscode/
.idea/
*.swp
*.swo
*~
# OS
.DS_Store
Thumbs.db

336
README.md
View file

@ -1,108 +1,272 @@
# Djedi Toolbelt # Djedi Toolbelt v2.0
This is intended for new Kali installs to install a large amount of useful tools not included with Kali in a short amount of time. [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![Python: 3.6+](https://img.shields.io/badge/Python-3.6+-blue.svg)](https://www.python.org/)
It is recommended if this is a new Kali VM to run PimpMyKali and run the 'N' option first. Dewalt has done an excellent job on this and keeps getting better every time I use it. You can check it out here: https://github.com/Dewalt-arch/pimpmykali It is also integrated into toolbelt but I always like running this first anyway. **Comprehensive security tool installer with interactive menus, pre-built profiles, and distro-specific support.**
## Updates ---
Python version got some important tweaks to speed things up and smooth out some issues. Actually the python code has not changed yet, it is just now actually working as intended since I fixed the apt-fast installation. It now takes only 1 to 3 minutes compared to 10 to 15 minutes or so using the bash version. Still may have some tweaks to work through but it seems to be working well in the several tests I've done. I will be putting this into a script shortly but here is instructions. ## 🚀 What's New in v2.0
### toolbelt.py Installation - ✅ **Interactive 3-Level Menu System** - Browse categories, select tools, install profiles
- ✅ **Pre-Built Profiles** - Bug Bounty, CTF, Web App, Network, Full Pentest
- ✅ **Distro Detection** - Kali, Debian, Ubuntu support with appropriate tool sets
- ✅ **No Root Requirement** - Runs as user, uses sudo only when needed
- ✅ **Comprehensive Logging** - Dual output (console + file)
- ✅ **Fresh Integration** - Detects and recommends modern CLI tools
- ✅ **Modular Architecture** - Clean, maintainable Python code
First we must install apt-fast ---
```bash
sudo apt install aria2 -y
sudo /bin/bash -c "$(curl -sL https://git.io/vokNn)"
cp apt-fast /usr/local/sbin/
sudo chmod +x /usr/local/sbin/apt-fast
cp apt-fast.conf /etc
```
Then we should be good to go: ## 📋 Quick Start
```bash
curl https://raw.githubusercontent.com/rpriven/toolbelt/main/toolbelt.py | sudo python3
```
Still a couple minor errors and I want to put this into a script soon.
*However, please note that there is an issue with the go tools and the useful scripts being downloaded in the /root directory instead of /home/kali because the script must be run as root. Working on a fix for this*
## Overview
This script installs / updates some of the important key tools for Pentesters and Bug Bounty Hunters. You probably
have most of these tools installed already (as it was designed for use with Kali/Debian/Ubuntu), but it is useful for
me to have it all together in one script so I don't have to take the time to search for everything when I make a
new VM or have to go through and install or update everything manually.
This is a rough version as it is my first attempt at building some sort of a recon framework (if you can call
it that) for Pentesting, CTFs as well as Bug Bounties. There will be an accompanying automation script as well.
**This installs a good amount of tools, if you are looking for something light, you may want to remove what you do not want or need before running the script.**
*It is also a good idea to read through unfamiliar code before executing it anyway.*
## (Old) Installation
Simply download the script and run it:
```bash ```bash
wget https://raw.githubusercontent.com/rpriven/toolbelt/main/toolbelt.sh # Clone the repository
chmod +x toolbelt.sh git clone https://github.com/rpriven/toolbelt.git
sudo ./toolbelt.sh cd toolbelt
# Run toolbelt (no sudo needed!)
python3 toolbelt.py
``` ```
Easier: **Important:** Do NOT run as root/sudo. The script will use sudo for specific commands that require it.
---
## 🎯 Features
### Interactive Menu System
**Level 1 - Main Menu:**
- Quick Install Profiles
- Browse & Select Categories
- Install Prerequisites (fresh)
- View Installed Tools
**Level 2 - Categories:**
- 📦 APT Tools - Package manager tools
- 🔷 Go Tools - Security tools written in Go
- 🔧 /opt Tools - Tools cloned to /opt
- 🐍 Python Tools - Tools via pip3
- 🐳 Docker Tools - Containerized tools
- 📜 Useful Scripts - PEAS, PowerView, etc.
**Level 3 - Tool Selection:**
- Install all tools in category
- Individual tool selection (coming soon)
### Pre-Built Profiles
**Bug Bounty Hunter** - Web app testing and reconnaissance
- nmap, masscan, nikto, sqlmap, burpsuite
- nuclei, httpx, subfinder, katana, amass
- Sublist3r, wafw00f, XSStrike
- wfuzz, arjun, scripts collection
**CTF Player** - Capture The Flag tools
- nmap, burpsuite, sqlmap, wireshark
- Python tools: wfuzz, scrapy, requests
- Scripts collection
**Web Application Testing** - Web security focus
- nmap, nikto, sqlmap, burpsuite
- nuclei, httpx, katana
- wafw00f, XSStrike, Striker
- wfuzz, arjun, scrapy
**Network Pentesting** - Network recon and scanning
- nmap, masscan, wireshark
- naabu, amass, assetfinder, httprobe
- RustScan (Docker)
**Full Pentesting Arsenal** - Everything (5GB+)
- All APT tools
- All Go tools
- All /opt tools
- All Python tools
- All Docker tools
- All scripts
---
## 🛠️ Tool Categories
### APT Tools (via package manager)
**Kali Linux:**
nmap, masscan, naabu, nuclei, burpsuite, feroxbuster, nikto, gobuster, seclists, sqlmap, git, docker.io, docker-compose, golang-go, wireshark
**Debian/Ubuntu:**
nmap, masscan, nikto, sqlmap, git, docker.io, docker-compose, golang-go, wireshark, burpsuite
### Go Tools (via go install)
naabu, nuclei, katana, httpx, subfinder, amass, assetfinder, httprobe, gowitness, subjack, hakrawler, webanalyze
*All ProjectDiscovery tools included*
### /opt Tools (cloned to /opt)
- **pimpmykali** (Kali only) - Golang + Impacket setup
- **xnLinkFinder** - Link finder for bug bounty
- **Knockpy** - Subdomain enumeration
- **Sublist3r** - Subdomain discovery
- **Striker** - Web application scanner
- **wafw00f** - WAF detection
- **waymore** - Web archive scraper
- **XSStrike** - XSS detection suite
### Python Tools (via pip3)
wfuzz, arjun, scrapy, tld, requests, fuzzywuzzy
### Docker Tools
**RustScan** - Fast port scanner
- Includes alias setup for shell
### Useful Scripts (downloaded to ~/scripts)
- **linpeas.sh** - Linux privilege escalation
- **jaws-enum.ps1** - Windows enumeration
- **LinEnum.sh** - Linux enumeration
- **winPEASany_ofs.exe** - Windows privilege escalation
- **php-reverse-shell.php** - PHP reverse shell
- **linux-exploit-suggester.sh** - Linux exploit suggester
- **PowerView.ps1** - PowerShell AD enumeration
---
## 🔧 Requirements
- **OS:** Kali Linux, Debian, or Ubuntu
- **Python:** 3.6+
- **Package Manager:** apt
- **Privileges:** sudo access (script runs as user, not root)
---
## 📖 Usage Examples
### Install a Profile
```bash ```bash
curl https://raw.githubusercontent.com/rpriven/toolbelt/main/toolbelt.sh | sudo sh python3 toolbelt.py
# Select: 1) Quick Install Profiles
# Choose: Bug Bounty Hunter
``` ```
## What is on the Toolbelt: ### Browse Categories
- Nmap ```bash
- naabu python3 toolbelt.py
- Nuclei # Select: 2) Browse & Select Categories
- Burp Suite # Choose category (e.g., Go Tools)
- feroxbuster # Install all or select specific tools
- nikto ```
- masscan
- Gobuster
- SecLists
- SQLmap
- git
- docker
- docker.io
- pimpmykali
- Golang
- Impacket
- knockpy
- Sublist3r
- Striker
- waymore
- wfuzz
- scrapy
- amass
- assetfinder
- httprobe
- gowitness
- subjack
- hakrawler
- webanalyze
- RustScan
## To Do List ### Check Installed Tools
### Add basic syntax to tools ```bash
python3 toolbelt.py
# Select: 4) View Installed Tools
```
### Add checks for the Go programs if they are the @latest version so it doesn't re-download them every time ---
the script is run, only when it is either not found or not up to date
### Add to the toolbelt: ## 🔗 Integration with Fresh
- dnmasscan Toolbelt integrates with [fresh](https://github.com/rpriven/fresh) for modern CLI productivity tools.
- interlace
- static-flow
- sn1per
- more...
### Add colors **Recommended Setup:**
1. **Install fresh first** - Modern CLI foundation (fzf, ripgrep, bat, etc.)
2. **Install toolbelt** - Security tools
3. **Install tmux-recon** (optional) - Pentesting automation
Fresh provides essential CLI tools that enhance the security workflow. Toolbelt will detect if fresh is installed and prompt you to install it if missing.
---
## 📂 Architecture
```
toolbelt/
├── toolbelt.py # Main entry point with interactive menus
├── utils.py # Distro detection, logging, helpers
├── config.py # Tool definitions, profiles, categories
├── installer.py # Installation logic for each category
├── toolbelt_old.py # Original v1.0 (reference)
└── toolbelt.sh.old # Legacy bash version (archived)
```
**Modular Design:**
- `utils.py` - System checks, logging setup, helper functions
- `config.py` - Tool lists, profile definitions, category metadata
- `installer.py` - Installation functions for each tool category
- `toolbelt.py` - Interactive menu system and main flow
---
## 🔐 Security Notes
- **No Root Execution**: Script runs as regular user, uses sudo only for specific commands
- **Logging**: All operations logged to `~/toolbelt-install.log`
- **Smart Detection**: Skips already-installed tools
- **Error Handling**: Comprehensive error checking and reporting
---
## 🐛 Known Issues
- Individual tool selection menu (Level 3) coming in next update
- Custom profile saving/loading planned for future release
---
## 🤝 Contributing
Contributions welcome! Please feel free to submit pull requests or open issues for:
- Additional tool suggestions
- New profiles
- Platform support improvements
- Bug fixes
---
## 📝 Version History
**v2.0.0** (2025-10-31)
- Complete rewrite with interactive menu system
- Pre-built profile support
- Distro detection (Kali, Debian, Ubuntu)
- Removed root requirement
- Added comprehensive logging
- Fresh integration
- Modular architecture
**v1.0** (2023)
- Original automated installer
- Bash and Python versions
- Root required
- No menu system
---
## 📜 License
This project is licensed under the MIT License - see the LICENSE file for details.
---
## 🙏 Acknowledgments
- Built for the pentesting and bug bounty community
- Integrates tools from ProjectDiscovery, OWASP, and many open source developers
- Inspired by the need for quick, consistent tool setup across environments
- Part of the Djedi security tooling ecosystem
---
**Djedi Toolbelt** - Because every pentester deserves a well-equipped toolbelt. 🔧

315
config.py Normal file
View file

@ -0,0 +1,315 @@
#!/usr/bin/env python3
"""
Djedi Toolbelt - Configuration and Tool Definitions
Defines all tools, categories, and profiles
"""
from typing import Dict, List
# ============================================================================
# Tool Categories
# ============================================================================
# APT Tools - Available via package manager
APT_TOOLS_KALI = [
"nmap",
"masscan",
"naabu",
"nuclei",
"burpsuite",
"feroxbuster",
"nikto",
"gobuster",
"seclists",
"sqlmap",
"git",
"docker.io",
"docker-compose",
"golang-go",
"wireshark",
]
APT_TOOLS_DEBIAN = [
"nmap",
"masscan",
"nikto",
"sqlmap",
"git",
"docker.io",
"docker-compose",
"golang-go",
"wireshark",
"burpsuite", # Community edition available in some repos
]
# /opt Tools - Cloned to /opt directory
OPT_TOOLS = {
"pimpmykali": {
"url": "https://github.com/Dewalt-arch/pimpmykali",
"post_install": [
"cd /opt/pimpmykali && sudo ./pimpmykali.sh --go",
"cd /opt/pimpmykali && sudo ./pimpmykali.sh --impacket",
"cd /opt/pimpmykali && sudo ./pimpmykali.sh --upgrade"
],
"kali_only": True
},
"xnLinkFinder": {
"url": "https://github.com/xnl-h4ck3r/xnLinkFinder.git",
"post_install": ["cd /opt/xnLinkFinder && sudo python setup.py install"],
"kali_only": False
},
"knock": {
"url": "https://github.com/guelfoweb/knock.git",
"post_install": ["cd /opt/knock && pip3 install -r requirements.txt"],
"kali_only": False
},
"Sublist3r": {
"url": "https://github.com/aboul3la/Sublist3r.git",
"post_install": ["cd /opt/Sublist3r && pip install -r requirements.txt"],
"kali_only": False
},
"Striker": {
"url": "https://github.com/s0md3v/Striker.git",
"post_install": ["cd /opt/Striker && pip install -r requirements.txt"],
"kali_only": False
},
"wafw00f": {
"url": "https://github.com/EnableSecurity/wafw00f.git",
"post_install": [
"cd /opt/wafw00f && pip3 install -r requirements.txt",
"cd /opt/wafw00f && sudo python setup.py install"
],
"kali_only": False
},
"waymore": {
"url": "https://github.com/xnl-h4ck3r/waymore.git",
"post_install": [
"cd /opt/waymore && pip3 install -r requirements.txt",
"cd /opt/waymore && sudo python setup.py install"
],
"kali_only": False
},
"XSStrike": {
"url": "https://github.com/s0md3v/XSStrike.git",
"post_install": ["cd /opt/XSStrike && pip3 install -r requirements.txt"],
"kali_only": False
},
}
# Python Tools - Installed via pip3
PYTHON_TOOLS = [
"wfuzz",
"arjun",
"scrapy",
"tld",
"requests",
"fuzzywuzzy",
]
# Go Tools - Installed via go install
GO_TOOLS = {
"naabu": "github.com/projectdiscovery/naabu/v2/cmd/naabu@latest",
"nuclei": "github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest",
"katana": "github.com/projectdiscovery/katana/cmd/katana@latest",
"httpx": "github.com/projectdiscovery/httpx/cmd/httpx@latest",
"subfinder": "github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest",
"amass": "github.com/OWASP/Amass/v3/...@master",
"assetfinder": "github.com/tomnomnom/assetfinder@latest",
"httprobe": "github.com/tomnomnom/httprobe@latest",
"gowitness": "github.com/sensepost/gowitness@latest",
"subjack": "github.com/haccer/subjack@latest",
"hakrawler": "github.com/hakluke/hakrawler@latest",
"webanalyze": "github.com/rverton/webanalyze/cmd/webanalyze@latest",
}
# Docker Tools
DOCKER_TOOLS = {
"rustscan": {
"image": "rustscan/rustscan:2.0.1",
"alias": "alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:2.0.1'"
},
}
# Useful Scripts - Downloaded to ~/scripts
USEFUL_SCRIPTS = {
"linpeas.sh": "https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh",
"jaws-enum.ps1": "https://github.com/411Hall/JAWS/raw/master/jaws-enum.ps1",
"LinEnum.sh": "https://github.com/rebootuser/LinEnum/raw/master/LinEnum.sh",
"winPEASany_ofs.exe": "https://github.com/carlospolop/PEASS-ng/releases/download/20230122/winPEASany_ofs.exe",
"php-reverse-shell.php": "https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php",
"linux-exploit-suggester.sh": "https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh",
"PowerView.ps1": "https://github.com/PowerShellMafia/PowerSploit/raw/master/Recon/PowerView.ps1",
}
# ============================================================================
# Installation Profiles
# ============================================================================
PROFILES = {
"bug-bounty": {
"name": "Bug Bounty Hunter",
"description": "Tools for bug bounty hunting and web application testing",
"categories": {
"apt": ["nmap", "masscan", "nikto", "sqlmap", "burpsuite", "git"],
"go": ["nuclei", "httpx", "subfinder", "katana", "amass", "assetfinder", "httprobe"],
"opt": ["Sublist3r", "wafw00f", "XSStrike"],
"python": ["wfuzz", "arjun", "requests"],
"scripts": True, # Install all scripts
}
},
"ctf": {
"name": "CTF Player",
"description": "Tools for Capture The Flag competitions",
"categories": {
"apt": ["nmap", "burpsuite", "sqlmap", "git", "wireshark"],
"python": ["wfuzz", "scrapy", "requests"],
"scripts": True,
}
},
"web-app": {
"name": "Web Application Testing",
"description": "Focused on web application security testing",
"categories": {
"apt": ["nmap", "nikto", "sqlmap", "burpsuite"],
"go": ["nuclei", "httpx", "katana"],
"opt": ["wafw00f", "XSStrike", "Striker"],
"python": ["wfuzz", "arjun", "scrapy"],
}
},
"network": {
"name": "Network Pentesting",
"description": "Network reconnaissance and scanning tools",
"categories": {
"apt": ["nmap", "masscan", "wireshark"],
"go": ["naabu", "amass", "assetfinder", "httprobe"],
"docker": ["rustscan"],
}
},
"full-pentest": {
"name": "Full Pentesting Arsenal",
"description": "Complete toolset for comprehensive penetration testing",
"categories": {
"apt": "all",
"go": "all",
"opt": "all",
"python": "all",
"docker": "all",
"scripts": True,
}
},
}
# ============================================================================
# Category Metadata
# ============================================================================
CATEGORIES = {
"apt": {
"name": "APT Tools",
"description": "Tools installed via apt package manager",
"icon": "📦",
"requires_sudo": True,
},
"go": {
"name": "Go Tools",
"description": "Security tools written in Go",
"icon": "🔷",
"requires_sudo": False,
},
"opt": {
"name": "/opt Tools",
"description": "Tools cloned to /opt directory",
"icon": "🔧",
"requires_sudo": True,
},
"python": {
"name": "Python Tools",
"description": "Tools installed via pip3",
"icon": "🐍",
"requires_sudo": False,
},
"docker": {
"name": "Docker Tools",
"description": "Containerized security tools",
"icon": "🐳",
"requires_sudo": False,
},
"scripts": {
"name": "Useful Scripts",
"description": "PEAS, PowerView, and other scripts",
"icon": "📜",
"requires_sudo": False,
},
}
# ============================================================================
# Helper Functions
# ============================================================================
def get_apt_tools_for_distro(distro_type: str) -> List[str]:
"""
Get appropriate APT tools list for distro
Args:
distro_type: One of 'kali', 'debian', 'ubuntu', 'unknown'
Returns:
List of APT package names
"""
if distro_type == 'kali':
return APT_TOOLS_KALI
elif distro_type in ['debian', 'ubuntu']:
return APT_TOOLS_DEBIAN
else:
# Conservative list for unknown distros
return [
"nmap",
"nikto",
"sqlmap",
"git",
"docker.io",
]
def get_opt_tools_for_distro(distro_type: str) -> Dict:
"""
Get appropriate /opt tools for distro
Args:
distro_type: One of 'kali', 'debian', 'ubuntu', 'unknown'
Returns:
Dictionary of /opt tools
"""
if distro_type == 'kali':
return OPT_TOOLS
# Filter out Kali-only tools for other distros
return {
name: config
for name, config in OPT_TOOLS.items()
if not config.get('kali_only', False)
}
def get_profile(profile_name: str) -> Dict:
"""
Get profile configuration by name
Args:
profile_name: Profile identifier
Returns:
Profile configuration dictionary or None
"""
return PROFILES.get(profile_name)
def list_profiles() -> List[str]:
"""
Get list of available profile names
Returns:
List of profile names
"""
return list(PROFILES.keys())

479
installer.py Normal file
View file

@ -0,0 +1,479 @@
#!/usr/bin/env python3
"""
Djedi Toolbelt - Installation Functions
Handles installation of tools across all categories
"""
import os
import subprocess
import logging
from typing import List, Dict, Optional
from concurrent.futures import ThreadPoolExecutor, as_completed
from pathlib import Path
from utils import (
run_command,
ensure_directory,
get_home_dir,
check_command_exists,
print_success,
print_info,
print_warning,
print_error,
)
import config
# ============================================================================
# APT Tools Installation
# ============================================================================
def install_apt_tools(
tools: Optional[List[str]] = None,
distro_type: str = 'unknown',
logger: Optional[logging.Logger] = None
) -> bool:
"""
Install tools via APT package manager
Args:
tools: List of package names (None for all)
distro_type: Distro type for filtering
logger: Logger instance
Returns:
True if successful
"""
if tools is None:
tools = config.get_apt_tools_for_distro(distro_type)
if not tools:
print_warning("No APT tools to install for this distribution")
return True
print_info(f"Installing {len(tools)} APT tools...")
if logger:
logger.info(f"Installing APT tools: {', '.join(tools)}")
# Update apt cache
try:
print_info("Updating APT cache...")
run_command(['apt', 'update'], use_sudo=True, logger=logger)
except Exception as e:
print_error(f"Failed to update APT cache: {e}")
if logger:
logger.error(f"APT update failed: {e}")
return False
# Check which tools are already installed
tools_to_install = []
for tool in tools:
# Handle cases like docker.io where command name != package name
check_name = tool.replace('.io', '').replace('-', '')
if check_command_exists(check_name):
print_success(f"{tool} already installed")
if logger:
logger.debug(f"{tool} already installed")
else:
tools_to_install.append(tool)
if not tools_to_install:
print_success("All APT tools already installed")
return True
# Install tools
print_info(f"Installing {len(tools_to_install)} new tools...")
try:
cmd = ['apt', 'install', '-y'] + tools_to_install
result = run_command(cmd, use_sudo=True, logger=logger)
print_success(f"Installed {len(tools_to_install)} APT tools")
if logger:
logger.info(f"APT installation complete: {', '.join(tools_to_install)}")
return True
except Exception as e:
print_error(f"Failed to install some APT tools: {e}")
if logger:
logger.error(f"APT installation failed: {e}")
return False
# ============================================================================
# /opt Tools Installation
# ============================================================================
def install_opt_tool(
tool_name: str,
tool_config: Dict,
logger: Optional[logging.Logger] = None
) -> bool:
"""
Install a single /opt tool
Args:
tool_name: Name of the tool
tool_config: Tool configuration dict
logger: Logger instance
Returns:
True if successful
"""
opt_path = f"/opt/{tool_name}"
# Check if already installed
if os.path.isdir(opt_path):
print_success(f"{tool_name} already installed")
if logger:
logger.debug(f"{tool_name} already installed at {opt_path}")
return True
print_info(f"Installing {tool_name}...")
if logger:
logger.info(f"Installing /opt tool: {tool_name}")
try:
# Clone repository
cmd = ['git', 'clone', tool_config['url'], opt_path]
run_command(cmd, use_sudo=True, logger=logger)
# Run post-install commands if specified
if 'post_install' in tool_config:
for post_cmd in tool_config['post_install']:
run_command(post_cmd, use_sudo=True, shell=True, logger=logger)
print_success(f"{tool_name} installed")
if logger:
logger.info(f"{tool_name} installation complete")
return True
except Exception as e:
print_error(f"Failed to install {tool_name}: {e}")
if logger:
logger.error(f"Failed to install {tool_name}: {e}")
return False
def install_opt_tools(
tools: Optional[List[str]] = None,
distro_type: str = 'unknown',
logger: Optional[logging.Logger] = None
) -> bool:
"""
Install /opt tools
Args:
tools: List of tool names (None for all)
distro_type: Distro type for filtering
logger: Logger instance
Returns:
True if successful
"""
all_tools = config.get_opt_tools_for_distro(distro_type)
if tools is None:
tools_to_install = all_tools
else:
tools_to_install = {k: v for k, v in all_tools.items() if k in tools}
if not tools_to_install:
print_warning("No /opt tools to install for this distribution")
return True
print_info(f"Installing {len(tools_to_install)} /opt tools...")
# Ensure /opt exists
ensure_directory("/opt", use_sudo=True)
# Install each tool
success_count = 0
for tool_name, tool_config in tools_to_install.items():
if install_opt_tool(tool_name, tool_config, logger):
success_count += 1
print_success(f"Installed {success_count}/{len(tools_to_install)} /opt tools")
return success_count == len(tools_to_install)
# ============================================================================
# Python Tools Installation
# ============================================================================
def install_python_tools(
tools: Optional[List[str]] = None,
logger: Optional[logging.Logger] = None
) -> bool:
"""
Install Python tools via pip3
Args:
tools: List of package names (None for all)
logger: Logger instance
Returns:
True if successful
"""
if tools is None:
tools = config.PYTHON_TOOLS
if not tools:
print_warning("No Python tools to install")
return True
print_info(f"Installing {len(tools)} Python tools...")
if logger:
logger.info(f"Installing Python tools: {', '.join(tools)}")
try:
cmd = ['pip3', 'install', '--upgrade'] + tools
run_command(cmd, logger=logger)
print_success(f"Installed {len(tools)} Python tools")
if logger:
logger.info(f"Python tools installation complete")
return True
except Exception as e:
print_error(f"Failed to install Python tools: {e}")
if logger:
logger.error(f"Python tools installation failed: {e}")
return False
# ============================================================================
# Go Tools Installation
# ============================================================================
def install_go_tool(
tool_name: str,
tool_path: str,
logger: Optional[logging.Logger] = None
) -> bool:
"""
Install a single Go tool
Args:
tool_name: Name of the tool
tool_path: Go module path
logger: Logger instance
Returns:
True if successful
"""
try:
cmd = ['go', 'install', '-v', tool_path]
run_command(cmd, logger=logger)
return True
except Exception as e:
if logger:
logger.error(f"Failed to install {tool_name}: {e}")
return False
def install_go_tools(
tools: Optional[List[str]] = None,
logger: Optional[logging.Logger] = None,
parallel: bool = True
) -> bool:
"""
Install Go tools
Args:
tools: List of tool names (None for all)
logger: Logger instance
parallel: Install in parallel if True
Returns:
True if successful
"""
all_tools = config.GO_TOOLS
if tools is None:
tools_to_install = all_tools
else:
tools_to_install = {k: v for k, v in all_tools.items() if k in tools}
if not tools_to_install:
print_warning("No Go tools to install")
return True
print_info(f"Installing {len(tools_to_install)} Go tools...")
if logger:
logger.info(f"Installing Go tools: {', '.join(tools_to_install.keys())}")
# Check if Go is installed
if not check_command_exists('go'):
print_error("Go is not installed! Install golang-go first.")
return False
success_count = 0
if parallel:
# Install in parallel using ThreadPoolExecutor
with ThreadPoolExecutor(max_workers=5) as executor:
futures = {
executor.submit(install_go_tool, name, path, logger): name
for name, path in tools_to_install.items()
}
for future in as_completed(futures):
tool_name = futures[future]
try:
if future.result():
print_success(f"{tool_name} installed")
success_count += 1
else:
print_error(f"{tool_name} failed")
except Exception as e:
print_error(f"{tool_name} failed: {e}")
else:
# Install sequentially
for tool_name, tool_path in tools_to_install.items():
if install_go_tool(tool_name, tool_path, logger):
print_success(f"{tool_name} installed")
success_count += 1
else:
print_error(f"{tool_name} failed")
print_success(f"Installed {success_count}/{len(tools_to_install)} Go tools")
return success_count == len(tools_to_install)
# ============================================================================
# Docker Tools Installation
# ============================================================================
def install_docker_tools(
tools: Optional[List[str]] = None,
logger: Optional[logging.Logger] = None
) -> bool:
"""
Install Docker tools
Args:
tools: List of tool names (None for all)
logger: Logger instance
Returns:
True if successful
"""
all_tools = config.DOCKER_TOOLS
if tools is None:
tools_to_install = all_tools
else:
tools_to_install = {k: v for k, v in all_tools.items() if k in tools}
if not tools_to_install:
print_warning("No Docker tools to install")
return True
print_info(f"Installing {len(tools_to_install)} Docker tools...")
if logger:
logger.info(f"Installing Docker tools: {', '.join(tools_to_install.keys())}")
# Check if Docker is installed
if not check_command_exists('docker'):
print_error("Docker is not installed! Install docker.io first.")
return False
success_count = 0
for tool_name, tool_config in tools_to_install.items():
try:
# Pull Docker image
cmd = ['docker', 'pull', tool_config['image']]
run_command(cmd, logger=logger)
# Add alias to shell config if specified
if 'alias' in tool_config:
home = get_home_dir()
shell_configs = [
os.path.join(home, '.zshrc'),
os.path.join(home, '.bashrc')
]
for config_file in shell_configs:
if os.path.exists(config_file):
with open(config_file, 'r') as f:
content = f.read()
if tool_name not in content:
with open(config_file, 'a') as f:
f.write(f"\n# {tool_name} alias (added by toolbelt)\n")
f.write(f"{tool_config['alias']}\n")
print_info(f"Added {tool_name} alias to {config_file}")
print_success(f"{tool_name} installed")
success_count += 1
except Exception as e:
print_error(f"Failed to install {tool_name}: {e}")
if logger:
logger.error(f"Failed to install {tool_name}: {e}")
print_success(f"Installed {success_count}/{len(tools_to_install)} Docker tools")
return success_count == len(tools_to_install)
# ============================================================================
# Useful Scripts Download
# ============================================================================
def download_useful_scripts(
scripts: Optional[Dict[str, str]] = None,
logger: Optional[logging.Logger] = None
) -> bool:
"""
Download useful scripts to ~/scripts
Args:
scripts: Dict of {filename: url} (None for all)
logger: Logger instance
Returns:
True if successful
"""
if scripts is None:
scripts = config.USEFUL_SCRIPTS
if not scripts:
print_warning("No scripts to download")
return True
print_info(f"Downloading {len(scripts)} useful scripts...")
if logger:
logger.info(f"Downloading scripts: {', '.join(scripts.keys())}")
# Create scripts directory in user's home (not /root!)
home = get_home_dir()
scripts_dir = os.path.join(home, 'scripts')
ensure_directory(scripts_dir)
success_count = 0
for filename, url in scripts.items():
try:
output_path = os.path.join(scripts_dir, filename)
# Skip if already exists
if os.path.exists(output_path):
print_success(f"{filename} already exists")
success_count += 1
continue
# Download with wget
cmd = ['wget', '-O', output_path, url]
run_command(cmd, logger=logger)
print_success(f"Downloaded {filename}")
success_count += 1
except Exception as e:
print_error(f"Failed to download {filename}: {e}")
if logger:
logger.error(f"Failed to download {filename}: {e}")
print_success(f"Downloaded {success_count}/{len(scripts)} scripts to {scripts_dir}")
return success_count == len(scripts)

613
toolbelt.py Normal file → Executable file
View file

@ -1,306 +1,397 @@
#!/usr/bin/python3 #!/usr/bin/env python3
"""
Djedi Toolbelt v2.0 - Security Tool Installer
Interactive package manager for pentesting and security research tools
"""
###################### import sys
''' Djedi Toolbelt ''' import os
''' Python3 Reboot ''' from typing import Optional, List, Dict
######################
''' # Import local modules
######################################################################### from utils import (
setup_logging,
detect_distro,
check_root_discourage,
check_apt,
check_sudo,
check_command_exists,
print_banner,
print_section,
print_success,
print_info,
print_warning,
print_error,
colorize,
)
import config
import installer
WARNING:
This script is approximately 5 GB and will take a while to run. # ============================================================================
# Fresh Detection & Integration
# ============================================================================
Please make sure you check this before installing. def check_fresh_installed() -> bool:
"""Check if fresh CLI tools are installed"""
fresh_tools = ['fzf', 'rg', 'bat']
return all(check_command_exists(tool) for tool in fresh_tools)
Menu will be coming in one of the next updates to help
cater to your preferences and custom requirements.
######################################################################### def prompt_install_fresh():
''' """Prompt user to install fresh if not detected"""
if check_fresh_installed():
return
''' print()
TO DO: print_warning("Fresh CLI tools not detected")
print_info("Fresh provides modern CLI productivity tools (fzf, ripgrep, bat, etc.)")
print_info("Repository: https://github.com/rpriven/fresh")
print()
Finish - apt threading (sort of, with apt-fast) response = input(colorize("Would you like to install fresh first? [y/N]: ", 'yellow')).strip().lower()
if response == 'y':
print()
print_info("To install fresh, run:")
print()
print(" git clone https://github.com/rpriven/fresh.git && cd fresh")
print(" ./fresh.sh")
print()
print_info("Then come back and run toolbelt again!")
sys.exit(0)
Add - Menu selection for the various categories:
- apt tools only
- opt tools only
- python tools only
- go tools only
- docker tools only
- scripts only
Threading for /opt tools # ============================================================================
# Level 1: Main Menu
# ============================================================================
Find out where scripts are actually downloading def show_main_menu(distro_name: str, distro_type: str):
"""Display the main menu"""
print_banner()
print(colorize(f"Detected: {distro_name}", 'cyan'))
print()
print(colorize("=" * 60, 'white'))
print(colorize(" MAIN MENU", 'cyan'))
print(colorize("=" * 60, 'white'))
print()
print(colorize("1)", 'green') + " Quick Install Profiles")
print(colorize("2)", 'green') + " Browse & Select Categories")
print(colorize("3)", 'green') + " Install Prerequisites (fresh)")
print(colorize("4)", 'green') + " View Installed Tools")
print()
print(colorize("0)", 'red') + " Exit")
print()
Add C2 - Probably Havoc
Add PowerView (if not already included)
Double-check all tools def main_menu_loop(distro_name: str, distro_type: str, logger):
"""Main menu interaction loop"""
while True:
show_main_menu(distro_name, distro_type)
choice = input(colorize("Select option: ", 'yellow')).strip()
Add section for Bug Bounty tools if choice == '1':
profile_menu(distro_type, logger)
Add section for API tools elif choice == '2':
category_menu(distro_type, logger)
Add option to download the recon.py automation script, elif choice == '3':
which uses this toolbelt prompt_install_fresh()
elif choice == '4':
''' view_installed_tools()
elif choice == '0':
import subprocess, os, threading print()
from concurrent.futures import ThreadPoolExecutor, as_completed print_success("Thank you for using Djedi Toolbelt!")
from termcolor import colored sys.exit(0)
from tqdm import tqdm
threads = []
# Check if the user is running as root
if os.geteuid() != 0:
print(colored("Please run as root", 'red'))
exit(1)
'''
subprocess.run(["pip", "install", "progress"])
tools = ["tool1", "tool2", "tool3"]
bar = Bar('Installing', max=len(tools))
for tool in tools:
# Code to install the tool
bar.next()
bar.finish()
'''
# Figlet
os.system("figlet DjediToolbelt | lolcat")
# Version
print("v.0.3\n")
# Message
print(colored("[*] Installing Pentest & Bug Bounty Toolbox Suite", 'magenta'))
#########################
''' Aptitude Programs '''
#########################
def apt_tools():
subprocess.run(["sudo", "apt", "update"])
subprocess.run(["sudo", "apt", "install", "apt-fast"])
programs = ["nmap", "naabu", "nuclei", "burpsuite", "feroxbuster", "nikto", "masscan", "gobuster", "seclists", "sqlmap", "git"]
for program in programs:
if os.system(f"command -v {program}") == 0:
print(colored(f"[*] {program} is already installed", 'blue'))
else: else:
print(colored(f"[+] Installing / updating {program}", 'green')) print_error("Invalid option. Please try again.")
os.system(f"sudo apt-fast install {program} -y") input("\nPress Enter to continue...")
if os.system(f"command -v {program}") != 0:
print(colored(f"[*] Error: Failed to install the program: {program}", 'red'))
exit(1)
os.system(f"sudo apt-fast install docker docker.io golang-go -y")
##################
''' /opt Tools '''
##################
def opt_tools(): # ============================================================================
# Pimpmykali # Level 2: Profile Menu
os.chdir("/opt") # ============================================================================
if not os.path.isdir("/opt/pimpmykali"):
print(colored("[+] Installing pimpmykali...", 'green'))
os.system("sudo git clone https://github.com/Dewalt-arch/pimpmykali")
os.chdir("pimpmykali")
print(colored("[+] Installing Golang...", 'green'))
os.system("sudo ./pimpmykali.sh --go")
print(colored("[+] Installing Impacket...", 'green'))
os.system("sudo ./pimpmykali.sh --impacket")
os.system("sudo ./pimpmykali.sh --upgrade")
os.chdir("/opt")
else:
print(colored("[*] pimpmykali is already installed", 'blue'))
# xnLinkFinder def show_profile_menu():
if not os.path.isdir("/opt/xnLinkFinder"): """Display profile selection menu"""
print(colored("[+] Installing xnLinkFinder...", 'green')) print_section("QUICK INSTALL PROFILES")
os.system("git clone https://github.com/xnl-h4ck3r/xnLinkFinder.git")
os.chdir("xnLinkFinder")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] xnLinkFinder is already installed", 'blue'))
# Knockpy profiles = config.PROFILES
if not os.path.isdir("/opt/knock"): idx = 1
print(colored("[+] Installing Knockpy...", 'green')) profile_map = {}
os.system("sudo git clone https://github.com/guelfoweb/knock.git")
os.chdir("knock")
os.system("pip3 install -r requirements.txt")
os.chdir("/opt")
else:
print(colored("[*] Knockpy is already installed", 'blue'))
# Sublist3r for profile_id, profile_info in profiles.items():
if not os.path.isdir("/opt/Sublist3r"): print(f"{colorize(str(idx) + ')', 'green')} {colorize(profile_info['name'], 'white')}")
print(colored("[+] Installing Sublist3r...", 'green')) print(f" {profile_info['description']}")
os.system("sudo git clone https://github.com/aboul3la/Sublist3r.git") print()
os.chdir("Sublist3r") profile_map[str(idx)] = profile_id
os.system("pip install -r requirements.txt") idx += 1
os.chdir("/opt")
else:
print(colored("[*] Sublist3r is already installed", 'blue'))
# Striker print(colorize("0)", 'red') + " Back to Main Menu")
if not os.path.isdir("/opt/Striker"): print()
print(colored("[+] Installing Striker...", 'green'))
os.system("sudo git clone https://github.com/s0md3v/Striker.git")
os.chdir("Striker")
os.system("pip install -r requirements.txt")
os.chdir("/opt")
else:
print(colored("[*] Striker is already installed", 'blue'))
# wafw00f return profile_map
if not os.path.isdir("/opt/wafw00f"):
print(colored("[+] Installing wafw00f...", 'green'))
os.system("git clone https://github.com/EnableSecurity/wafw00f.git")
os.chdir("wafw00f")
os.system("pip3 install -r requirements.txt")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] wafw00f is already installed", 'blue'))
# Waymore
if not os.path.isdir("/opt/waymore"):
print(colored("[+] Installing waymore...", 'green'))
os.system("git clone https://github.com/xnl-h4ck3r/waymore.git")
os.chdir("waymore")
os.system("pip3 install -r requirements.txt")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] waymore is already installed", 'blue'))
# XSStrike def install_profile(profile_id: str, distro_type: str, logger):
if not os.path.isdir("/opt/XSStrike"): """Install tools from a profile"""
print(colored("[+] Installing XSStrike...", 'green')) profile = config.get_profile(profile_id)
os.system("git clone https://github.com/s0md3v/XSStrike.git") if not profile:
os.chdir("XSStrike") print_error(f"Profile not found: {profile_id}")
os.system("pip3 install -r requirements.txt") return
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] XSStrike is already installed", 'blue'))
#################### print_section(f"Installing Profile: {profile['name']}")
''' Python Tools ''' print_info(profile['description'])
#################### print()
def python_tools(): categories = profile['categories']
print(colored("[+] Installing / Updating Python Tools...", 'green'))
subprocess.run(["pip3", "install", "--upgrade", "wfuzz"])
subprocess.run(["pip3", "install", "arjun"])
subprocess.run(["pip3", "install", "scrapy"])
subprocess.run(["pip3", "install", "tld"])
subprocess.run(["pip3", "install", "requests"])
subprocess.run(["pip3", "install", "fuzzywuzzy"])
################ # APT Tools
''' Go Tools ''' if 'apt' in categories:
################ if categories['apt'] == 'all':
installer.install_apt_tools(distro_type=distro_type, logger=logger)
elif isinstance(categories['apt'], list):
installer.install_apt_tools(tools=categories['apt'], distro_type=distro_type, logger=logger)
def go_tools(): # Go Tools
print(colored("[+] Installing / Updating Go Tools...", 'green')) if 'go' in categories:
commands = [ if categories['go'] == 'all':
["go", "install", "-v", "github.com/projectdiscovery/naabu/v2/cmd/naabu@latest"], installer.install_go_tools(logger=logger)
["go", "install", "-v", "github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest"], elif isinstance(categories['go'], list):
["go", "install", "-v", "github.com/projectdiscovery/katana/cmd/katana@latest"], installer.install_go_tools(tools=categories['go'], logger=logger)
["go", "install", "-v", "github.com/projectdiscovery/httpx/cmd/httpx@latest"],
["go", "install", "-v", "github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest"],
["go", "install", "-v", "github.com/OWASP/Amass/v3/...@master"],
["go", "install", "-v", "github.com/tomnomnom/assetfinder@latest"],
["go", "install", "-v", "github.com/tomnomnom/httprobe@latest"],
["go", "install", "-v", "github.com/sensepost/gowitness@latest"],
["go", "install", "-v", "github.com/haccer/subjack@latest"],
["go", "install", "-v", "github.com/hakluke/hakrawler@latest"],
["go", "install", "-v", "github.com/rverton/webanalyze/cmd/webanalyze@latest"],
]
with ThreadPoolExecutor() as executor: # /opt Tools
results = [executor.submit(subprocess.run, cmd) for cmd in commands] if 'opt' in categories:
for f in as_completed(results): if categories['opt'] == 'all':
print(colored(f.result(), 'green')) installer.install_opt_tools(distro_type=distro_type, logger=logger)
elif isinstance(categories['opt'], list):
installer.install_opt_tools(tools=categories['opt'], distro_type=distro_type, logger=logger)
#################### # Python Tools
''' Docker Tools ''' if 'python' in categories:
#################### if categories['python'] == 'all':
installer.install_python_tools(logger=logger)
elif isinstance(categories['python'], list):
installer.install_python_tools(tools=categories['python'], logger=logger)
def docker_tools(): # Docker Tools
# RustScan if 'docker' in categories:
print(colored("[+] Installing / Updating RustScan...", 'green')) if categories['docker'] == 'all':
os.system("docker pull rustscan/rustscan:2.0.1") installer.install_docker_tools(logger=logger)
if os.path.isfile("~/.zshrc"): elif isinstance(categories['docker'], list):
print(colored("[+] adding rustscan alias to ~/.zshrc", 'green')) installer.install_docker_tools(tools=categories['docker'], logger=logger)
with open("~/.zshrc", "a") as f:
f.write("alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:2.0.1'")
elif os.path.isfile("~/.bashrc"):
print(colored("[+] adding rustscan alias to ~/.bashrc", 'green'))
with open("~/.bashrc", "a") as f:
f.write("alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:2.0.1'")
############### # Scripts
''' Scripts ''' if 'scripts' in categories and categories['scripts']:
############### installer.download_useful_scripts(logger=logger)
def useful_scripts(): print()
def scripts_dir(): print_success(f"Profile '{profile['name']}' installation complete!")
if not os.path.isdir(os.path.expanduser("~/scripts")): input("\nPress Enter to continue...")
# os.chdir(["cd", os.path.expanduser("~")])
os.chdir(os.path.expanduser("~"))
os.makedirs(os.path.expanduser("~/scripts"), exist_ok=True) def profile_menu(distro_type: str, logger):
os.chdir(os.path.expanduser("~/scripts")) """Profile selection menu"""
subprocess.run(["echo", "created", "scripts", "and", "moved", "into", "it"]) while True:
profile_map = show_profile_menu()
choice = input(colorize("Select profile: ", 'yellow')).strip()
if choice == '0':
return
elif choice in profile_map:
install_profile(profile_map[choice], distro_type, logger)
else: else:
os.chdir(os.path.expanduser("~/scripts")) print_error("Invalid option. Please try again.")
subprocess.run(["echo", "directory", "/scripts", "already", "exists,", "moving", "into", "it"]) input("\nPress Enter to continue...")
scripts_dir()
scripts = ["https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh", "https://github.com/411Hall/JAWS/raw/master/jaws-enum.ps1", "https://github.com/rebootuser/LinEnum/raw/master/LinEnum.sh", "https://github.com/carlospolop/PEASS-ng/releases/download/20230122/winPEASany_ofs.exe", "https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php", "https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh", "https://github.com/PowerShellMafia/PowerSploit/raw/master/Recon/PowerView.ps1"] # ============================================================================
# Level 2: Category Menu
# ============================================================================
script_threads = [] def show_category_menu():
"""Display category selection menu"""
print_section("BROWSE & SELECT CATEGORIES")
def download_script_thread(script): idx = 1
subprocess.run(f"wget {script}", shell=True) category_map = {}
def download_script(scripts): for cat_id, cat_info in config.CATEGORIES.items():
for script in tqdm(scripts): icon = cat_info.get('icon', '')
print(colored(f"[+] Grabbing {script}", 'green')) name = cat_info['name']
t = threading.Thread(target=download_script_thread, args=(script,)) desc = cat_info['description']
script_threads.append(t)
t.start()
for t in script_threads: print(f"{colorize(str(idx) + ')', 'green')} {icon} {colorize(name, 'white')}")
t.join() print(f" {desc}")
print()
print(colored("[*] All scripts downloaded", 'green')) category_map[str(idx)] = cat_id
idx += 1
download_script(scripts) print(colorize("0)", 'red') + " Back to Main Menu")
print()
try: return category_map
apt_tools()
opt_tools()
go_tools()
docker_tools()
useful_scripts()
except KeyboardInterrupt:
print(colored(f"[*] Exiting: KeyboardInterrupt", 'red'))
print(colored("[*] Installation Complete", 'magenta'))
print(colored("[*] Reboot Recommended", 'magenta')) def category_menu(distro_type: str, logger):
print(colored("[*] You are now Equipped!", 'green')) """Category selection menu"""
while True:
category_map = show_category_menu()
choice = input(colorize("Select category: ", 'yellow')).strip()
if choice == '0':
return
elif choice in category_map:
category_id = category_map[choice]
tool_selection_menu(category_id, distro_type, logger)
else:
print_error("Invalid option. Please try again.")
input("\nPress Enter to continue...")
# ============================================================================
# Level 3: Tool Selection Menu
# ============================================================================
def show_tool_selection_menu(category_id: str, distro_type: str):
"""Display tool selection menu for a category"""
cat_info = config.CATEGORIES[category_id]
print_section(f"{cat_info['icon']} {cat_info['name']}")
print_info(cat_info['description'])
print()
print(colorize("1)", 'green') + " Install All Tools in Category")
print(colorize("2)", 'green') + " Select Specific Tools (Coming Soon)")
print()
print(colorize("0)", 'red') + " Back")
print()
def tool_selection_menu(category_id: str, distro_type: str, logger):
"""Tool selection menu for a category"""
while True:
show_tool_selection_menu(category_id, distro_type)
choice = input(colorize("Select option: ", 'yellow')).strip()
if choice == '0':
return
elif choice == '1':
install_category_all(category_id, distro_type, logger)
elif choice == '2':
print_warning("Individual tool selection coming in next update!")
input("\nPress Enter to continue...")
else:
print_error("Invalid option. Please try again.")
input("\nPress Enter to continue...")
def install_category_all(category_id: str, distro_type: str, logger):
"""Install all tools in a category"""
cat_info = config.CATEGORIES[category_id]
print_section(f"Installing All {cat_info['name']}")
success = False
if category_id == 'apt':
success = installer.install_apt_tools(distro_type=distro_type, logger=logger)
elif category_id == 'go':
success = installer.install_go_tools(logger=logger)
elif category_id == 'opt':
success = installer.install_opt_tools(distro_type=distro_type, logger=logger)
elif category_id == 'python':
success = installer.install_python_tools(logger=logger)
elif category_id == 'docker':
success = installer.install_docker_tools(logger=logger)
elif category_id == 'scripts':
success = installer.download_useful_scripts(logger=logger)
print()
if success:
print_success(f"{cat_info['name']} installation complete!")
else:
print_warning(f"{cat_info['name']} installation completed with some errors")
input("\nPress Enter to continue...")
# ============================================================================
# View Installed Tools
# ============================================================================
def view_installed_tools():
"""Display currently installed tools"""
print_section("INSTALLED TOOLS")
# Check APT tools
print(colorize("📦 APT Tools:", 'cyan'))
apt_tools = config.get_apt_tools_for_distro('kali') # Use max list
for tool in apt_tools:
check_name = tool.replace('.io', '').replace('-', '')
if check_command_exists(check_name):
print(colorize(f"{tool}", 'green'))
print()
# Check Go tools
print(colorize("🔷 Go Tools:", 'cyan'))
for tool_name in config.GO_TOOLS.keys():
if check_command_exists(tool_name):
print(colorize(f"{tool_name}", 'green'))
print()
# Check Docker tools
print(colorize("🐳 Docker Tools:", 'cyan'))
for tool_name in config.DOCKER_TOOLS.keys():
if check_command_exists(tool_name):
print(colorize(f"{tool_name}", 'green'))
print()
input("Press Enter to continue...")
# ============================================================================
# Main Entry Point
# ============================================================================
def main():
"""Main entry point"""
# System checks
check_root_discourage()
if not check_apt():
print_error("APT package manager not found!")
print_error("This tool currently only supports Debian-based systems.")
sys.exit(1)
if not check_sudo():
print_error("sudo not found! Please install sudo first.")
sys.exit(1)
# Setup logging
logger = setup_logging()
# Detect distribution
distro_name, distro_type = detect_distro()
logger.info(f"Detected distribution: {distro_name} (type: {distro_type})")
# Check for fresh (optional)
prompt_install_fresh()
# Enter main menu loop
try:
main_menu_loop(distro_name, distro_type, logger)
except KeyboardInterrupt:
print()
print()
print_warning("Installation interrupted by user")
logger.info("Installation interrupted by user (KeyboardInterrupt)")
sys.exit(0)
except Exception as e:
print()
print_error(f"Unexpected error: {e}")
logger.error(f"Unexpected error: {e}", exc_info=True)
sys.exit(1)
if __name__ == "__main__":
main()

306
toolbelt_old.py Normal file
View file

@ -0,0 +1,306 @@
#!/usr/bin/python3
######################
''' Djedi Toolbelt '''
''' Python3 Reboot '''
######################
'''
#########################################################################
WARNING:
This script is approximately 5 GB and will take a while to run.
Please make sure you check this before installing.
Menu will be coming in one of the next updates to help
cater to your preferences and custom requirements.
#########################################################################
'''
'''
TO DO:
Finish - apt threading (sort of, with apt-fast)
Add - Menu selection for the various categories:
- apt tools only
- opt tools only
- python tools only
- go tools only
- docker tools only
- scripts only
Threading for /opt tools
Find out where scripts are actually downloading
Add C2 - Probably Havoc
Add PowerView (if not already included)
Double-check all tools
Add section for Bug Bounty tools
Add section for API tools
Add option to download the recon.py automation script,
which uses this toolbelt
'''
import subprocess, os, threading
from concurrent.futures import ThreadPoolExecutor, as_completed
from termcolor import colored
from tqdm import tqdm
threads = []
# Check if the user is running as root
if os.geteuid() != 0:
print(colored("Please run as root", 'red'))
exit(1)
'''
subprocess.run(["pip", "install", "progress"])
tools = ["tool1", "tool2", "tool3"]
bar = Bar('Installing', max=len(tools))
for tool in tools:
# Code to install the tool
bar.next()
bar.finish()
'''
# Figlet
os.system("figlet DjediToolbelt | lolcat")
# Version
print("v.0.3\n")
# Message
print(colored("[*] Installing Pentest & Bug Bounty Toolbox Suite", 'magenta'))
#########################
''' Aptitude Programs '''
#########################
def apt_tools():
subprocess.run(["sudo", "apt", "update"])
subprocess.run(["sudo", "apt", "install", "apt-fast"])
programs = ["nmap", "naabu", "nuclei", "burpsuite", "feroxbuster", "nikto", "masscan", "gobuster", "seclists", "sqlmap", "git"]
for program in programs:
if os.system(f"command -v {program}") == 0:
print(colored(f"[*] {program} is already installed", 'blue'))
else:
print(colored(f"[+] Installing / updating {program}", 'green'))
os.system(f"sudo apt-fast install {program} -y")
if os.system(f"command -v {program}") != 0:
print(colored(f"[*] Error: Failed to install the program: {program}", 'red'))
exit(1)
os.system(f"sudo apt-fast install docker docker.io golang-go -y")
##################
''' /opt Tools '''
##################
def opt_tools():
# Pimpmykali
os.chdir("/opt")
if not os.path.isdir("/opt/pimpmykali"):
print(colored("[+] Installing pimpmykali...", 'green'))
os.system("sudo git clone https://github.com/Dewalt-arch/pimpmykali")
os.chdir("pimpmykali")
print(colored("[+] Installing Golang...", 'green'))
os.system("sudo ./pimpmykali.sh --go")
print(colored("[+] Installing Impacket...", 'green'))
os.system("sudo ./pimpmykali.sh --impacket")
os.system("sudo ./pimpmykali.sh --upgrade")
os.chdir("/opt")
else:
print(colored("[*] pimpmykali is already installed", 'blue'))
# xnLinkFinder
if not os.path.isdir("/opt/xnLinkFinder"):
print(colored("[+] Installing xnLinkFinder...", 'green'))
os.system("git clone https://github.com/xnl-h4ck3r/xnLinkFinder.git")
os.chdir("xnLinkFinder")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] xnLinkFinder is already installed", 'blue'))
# Knockpy
if not os.path.isdir("/opt/knock"):
print(colored("[+] Installing Knockpy...", 'green'))
os.system("sudo git clone https://github.com/guelfoweb/knock.git")
os.chdir("knock")
os.system("pip3 install -r requirements.txt")
os.chdir("/opt")
else:
print(colored("[*] Knockpy is already installed", 'blue'))
# Sublist3r
if not os.path.isdir("/opt/Sublist3r"):
print(colored("[+] Installing Sublist3r...", 'green'))
os.system("sudo git clone https://github.com/aboul3la/Sublist3r.git")
os.chdir("Sublist3r")
os.system("pip install -r requirements.txt")
os.chdir("/opt")
else:
print(colored("[*] Sublist3r is already installed", 'blue'))
# Striker
if not os.path.isdir("/opt/Striker"):
print(colored("[+] Installing Striker...", 'green'))
os.system("sudo git clone https://github.com/s0md3v/Striker.git")
os.chdir("Striker")
os.system("pip install -r requirements.txt")
os.chdir("/opt")
else:
print(colored("[*] Striker is already installed", 'blue'))
# wafw00f
if not os.path.isdir("/opt/wafw00f"):
print(colored("[+] Installing wafw00f...", 'green'))
os.system("git clone https://github.com/EnableSecurity/wafw00f.git")
os.chdir("wafw00f")
os.system("pip3 install -r requirements.txt")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] wafw00f is already installed", 'blue'))
# Waymore
if not os.path.isdir("/opt/waymore"):
print(colored("[+] Installing waymore...", 'green'))
os.system("git clone https://github.com/xnl-h4ck3r/waymore.git")
os.chdir("waymore")
os.system("pip3 install -r requirements.txt")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] waymore is already installed", 'blue'))
# XSStrike
if not os.path.isdir("/opt/XSStrike"):
print(colored("[+] Installing XSStrike...", 'green'))
os.system("git clone https://github.com/s0md3v/XSStrike.git")
os.chdir("XSStrike")
os.system("pip3 install -r requirements.txt")
os.system("sudo python setup.py install")
os.chdir("/opt")
else:
print(colored("[*] XSStrike is already installed", 'blue'))
####################
''' Python Tools '''
####################
def python_tools():
print(colored("[+] Installing / Updating Python Tools...", 'green'))
subprocess.run(["pip3", "install", "--upgrade", "wfuzz"])
subprocess.run(["pip3", "install", "arjun"])
subprocess.run(["pip3", "install", "scrapy"])
subprocess.run(["pip3", "install", "tld"])
subprocess.run(["pip3", "install", "requests"])
subprocess.run(["pip3", "install", "fuzzywuzzy"])
################
''' Go Tools '''
################
def go_tools():
print(colored("[+] Installing / Updating Go Tools...", 'green'))
commands = [
["go", "install", "-v", "github.com/projectdiscovery/naabu/v2/cmd/naabu@latest"],
["go", "install", "-v", "github.com/projectdiscovery/nuclei/v2/cmd/nuclei@latest"],
["go", "install", "-v", "github.com/projectdiscovery/katana/cmd/katana@latest"],
["go", "install", "-v", "github.com/projectdiscovery/httpx/cmd/httpx@latest"],
["go", "install", "-v", "github.com/projectdiscovery/subfinder/v2/cmd/subfinder@latest"],
["go", "install", "-v", "github.com/OWASP/Amass/v3/...@master"],
["go", "install", "-v", "github.com/tomnomnom/assetfinder@latest"],
["go", "install", "-v", "github.com/tomnomnom/httprobe@latest"],
["go", "install", "-v", "github.com/sensepost/gowitness@latest"],
["go", "install", "-v", "github.com/haccer/subjack@latest"],
["go", "install", "-v", "github.com/hakluke/hakrawler@latest"],
["go", "install", "-v", "github.com/rverton/webanalyze/cmd/webanalyze@latest"],
]
with ThreadPoolExecutor() as executor:
results = [executor.submit(subprocess.run, cmd) for cmd in commands]
for f in as_completed(results):
print(colored(f.result(), 'green'))
####################
''' Docker Tools '''
####################
def docker_tools():
# RustScan
print(colored("[+] Installing / Updating RustScan...", 'green'))
os.system("docker pull rustscan/rustscan:2.0.1")
if os.path.isfile("~/.zshrc"):
print(colored("[+] adding rustscan alias to ~/.zshrc", 'green'))
with open("~/.zshrc", "a") as f:
f.write("alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:2.0.1'")
elif os.path.isfile("~/.bashrc"):
print(colored("[+] adding rustscan alias to ~/.bashrc", 'green'))
with open("~/.bashrc", "a") as f:
f.write("alias rustscan='docker run -it --rm --name rustscan rustscan/rustscan:2.0.1'")
###############
''' Scripts '''
###############
def useful_scripts():
def scripts_dir():
if not os.path.isdir(os.path.expanduser("~/scripts")):
# os.chdir(["cd", os.path.expanduser("~")])
os.chdir(os.path.expanduser("~"))
os.makedirs(os.path.expanduser("~/scripts"), exist_ok=True)
os.chdir(os.path.expanduser("~/scripts"))
subprocess.run(["echo", "created", "scripts", "and", "moved", "into", "it"])
else:
os.chdir(os.path.expanduser("~/scripts"))
subprocess.run(["echo", "directory", "/scripts", "already", "exists,", "moving", "into", "it"])
scripts_dir()
scripts = ["https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh", "https://github.com/411Hall/JAWS/raw/master/jaws-enum.ps1", "https://github.com/rebootuser/LinEnum/raw/master/LinEnum.sh", "https://github.com/carlospolop/PEASS-ng/releases/download/20230122/winPEASany_ofs.exe", "https://raw.githubusercontent.com/pentestmonkey/php-reverse-shell/master/php-reverse-shell.php", "https://raw.githubusercontent.com/mzet-/linux-exploit-suggester/master/linux-exploit-suggester.sh", "https://github.com/PowerShellMafia/PowerSploit/raw/master/Recon/PowerView.ps1"]
script_threads = []
def download_script_thread(script):
subprocess.run(f"wget {script}", shell=True)
def download_script(scripts):
for script in tqdm(scripts):
print(colored(f"[+] Grabbing {script}", 'green'))
t = threading.Thread(target=download_script_thread, args=(script,))
script_threads.append(t)
t.start()
for t in script_threads:
t.join()
print(colored("[*] All scripts downloaded", 'green'))
download_script(scripts)
try:
apt_tools()
opt_tools()
go_tools()
docker_tools()
useful_scripts()
except KeyboardInterrupt:
print(colored(f"[*] Exiting: KeyboardInterrupt", 'red'))
print(colored("[*] Installation Complete", 'magenta'))
print(colored("[*] Reboot Recommended", 'magenta'))
print(colored("[*] You are now Equipped!", 'green'))

354
utils.py Normal file
View file

@ -0,0 +1,354 @@
#!/usr/bin/env python3
"""
Djedi Toolbelt - Utility Functions
Provides distro detection, logging, and helper functions
"""
import os
import sys
import subprocess
import logging
from pathlib import Path
from datetime import datetime
from typing import Optional, List, Tuple
# ============================================================================
# Distro Detection
# ============================================================================
def detect_distro() -> Tuple[str, str]:
"""
Detect the Linux distribution
Returns:
Tuple of (distro_name, distro_type)
distro_type is one of: 'kali', 'debian', 'ubuntu', 'unknown'
"""
distro_name = "Unknown"
distro_type = "unknown"
if not os.path.exists('/etc/os-release'):
return (distro_name, distro_type)
try:
with open('/etc/os-release', 'r') as f:
content = f.read()
# Extract PRETTY_NAME
for line in content.split('\n'):
if line.startswith('PRETTY_NAME='):
distro_name = line.split('=')[1].strip('"')
break
# Determine distro type
content_lower = content.lower()
if 'kali' in content_lower:
distro_type = 'kali'
elif 'debian' in content_lower:
distro_type = 'debian'
elif 'ubuntu' in content_lower:
distro_type = 'ubuntu'
except Exception as e:
logging.error(f"Error detecting distro: {e}")
return (distro_name, distro_type)
def is_kali() -> bool:
"""Check if running on Kali Linux"""
_, distro_type = detect_distro()
return distro_type == 'kali'
def is_debian_based() -> bool:
"""Check if running on Debian-based system (Debian, Ubuntu, Kali)"""
_, distro_type = detect_distro()
return distro_type in ['kali', 'debian', 'ubuntu']
# ============================================================================
# Logging Setup
# ============================================================================
def setup_logging(log_file: Optional[str] = None) -> logging.Logger:
"""
Setup logging with both file and console output
Args:
log_file: Optional path to log file. Defaults to ~/toolbelt-install.log
Returns:
Configured logger instance
"""
if log_file is None:
log_file = os.path.expanduser("~/toolbelt-install.log")
# Create logger
logger = logging.getLogger('toolbelt')
logger.setLevel(logging.DEBUG)
# Clear existing handlers
logger.handlers.clear()
# File handler (DEBUG level)
file_handler = logging.FileHandler(log_file, mode='a')
file_handler.setLevel(logging.DEBUG)
file_formatter = logging.Formatter(
'[%(asctime)s] [%(levelname)s] %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
file_handler.setFormatter(file_formatter)
# Console handler (INFO level)
console_handler = logging.StreamHandler(sys.stdout)
console_handler.setLevel(logging.INFO)
console_formatter = logging.Formatter('[%(levelname)s] %(message)s')
console_handler.setFormatter(console_formatter)
# Add handlers
logger.addHandler(file_handler)
logger.addHandler(console_handler)
# Log session start
logger.info("=" * 60)
logger.info(f"Toolbelt session started: {datetime.now()}")
logger.info("=" * 60)
return logger
# ============================================================================
# System Checks
# ============================================================================
def is_root() -> bool:
"""Check if running as root"""
return os.geteuid() == 0
def check_root_discourage():
"""Warn user if running as root (we don't want root!)"""
if is_root():
print("\033[91m") # Red
print("=" * 60)
print("WARNING: Running as root is NOT recommended!")
print("=" * 60)
print("\033[0m") # Reset
print()
print("This script will use sudo for specific commands that need it.")
print("Running the entire script as root can cause issues:")
print(" • Scripts download to /root instead of your home directory")
print(" • Files owned by root instead of your user")
print(" • Potential security issues")
print()
response = input("Continue anyway? [y/N]: ").strip().lower()
if response != 'y':
print("Exiting. Please run without sudo/root.")
sys.exit(0)
def check_command_exists(command: str) -> bool:
"""
Check if a command exists in PATH
Args:
command: Command name to check
Returns:
True if command exists, False otherwise
"""
try:
result = subprocess.run(
['which', command],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
return result.returncode == 0
except Exception:
return False
def check_apt() -> bool:
"""Check if apt package manager is available"""
return check_command_exists('apt')
def check_sudo() -> bool:
"""Check if sudo is available"""
return check_command_exists('sudo')
# ============================================================================
# Helper Functions
# ============================================================================
def run_command(
cmd: List[str],
use_sudo: bool = False,
shell: bool = False,
check: bool = True,
logger: Optional[logging.Logger] = None
) -> subprocess.CompletedProcess:
"""
Run a command with optional sudo
Args:
cmd: Command and arguments as list
use_sudo: Prepend sudo if True
shell: Run as shell command if True
check: Raise exception on non-zero exit if True
logger: Optional logger instance
Returns:
CompletedProcess instance
"""
if use_sudo and not is_root():
if isinstance(cmd, list):
cmd = ['sudo'] + cmd
else:
cmd = f"sudo {cmd}"
if logger:
cmd_str = ' '.join(cmd) if isinstance(cmd, list) else cmd
logger.debug(f"Running: {cmd_str}")
try:
result = subprocess.run(
cmd,
shell=shell,
check=check,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
return result
except subprocess.CalledProcessError as e:
if logger:
logger.error(f"Command failed: {e.cmd}")
logger.error(f"Exit code: {e.returncode}")
if e.stdout:
logger.error(f"Stdout: {e.stdout}")
if e.stderr:
logger.error(f"Stderr: {e.stderr}")
raise
def ensure_directory(path: str, use_sudo: bool = False) -> bool:
"""
Ensure directory exists, create if necessary
Args:
path: Directory path
use_sudo: Use sudo to create if True
Returns:
True if directory exists or was created successfully
"""
expanded_path = os.path.expanduser(path)
if os.path.isdir(expanded_path):
return True
try:
if use_sudo:
subprocess.run(['sudo', 'mkdir', '-p', expanded_path], check=True)
else:
os.makedirs(expanded_path, exist_ok=True)
return True
except Exception as e:
logging.error(f"Failed to create directory {expanded_path}: {e}")
return False
def get_home_dir() -> str:
"""
Get the actual user's home directory (not /root even if running as root)
Returns:
Path to user's home directory
"""
# If running as root, try to get the original user's home
if is_root():
sudo_user = os.environ.get('SUDO_USER')
if sudo_user:
return os.path.expanduser(f"~{sudo_user}")
# Otherwise return normal home
return os.path.expanduser("~")
def colorize(text: str, color: str) -> str:
"""
Colorize text for terminal output
Args:
text: Text to colorize
color: Color name (red, green, yellow, blue, magenta, cyan)
Returns:
Colorized text string
"""
colors = {
'red': '\033[91m',
'green': '\033[92m',
'yellow': '\033[93m',
'blue': '\033[94m',
'magenta': '\033[95m',
'cyan': '\033[96m',
'white': '\033[97m',
'reset': '\033[0m'
}
color_code = colors.get(color.lower(), colors['reset'])
return f"{color_code}{text}{colors['reset']}"
# ============================================================================
# Display Functions
# ============================================================================
def print_banner():
"""Print the toolbelt banner"""
banner = """
🔧 DJEDI TOOLBELT 🔧
Comprehensive Security Tool Installer
"""
print(colorize(banner, 'cyan'))
print(colorize(" v2.0.0", 'magenta'))
print()
def print_section(title: str):
"""Print a section header"""
print()
print(colorize("=" * 60, 'cyan'))
print(colorize(f" {title}", 'white'))
print(colorize("=" * 60, 'cyan'))
print()
def print_success(message: str):
"""Print success message"""
print(colorize(f"{message}", 'green'))
def print_info(message: str):
"""Print info message"""
print(colorize(f"{message}", 'blue'))
def print_warning(message: str):
"""Print warning message"""
print(colorize(f"{message}", 'yellow'))
def print_error(message: str):
"""Print error message"""
print(colorize(f"{message}", 'red'))