Compare commits

...

10 commits

Author SHA1 Message Date
1413c05860
Update payload install location to ~/scripts/payloads/ 2025-11-07 14:32:40 -07:00
a2fa5c3ae9
Remove duplicate image reference after merge 2025-11-01 00:33:43 -06:00
0ff4c87123
Merge remote-tracking branch 'origin/main' 2025-11-01 00:33:24 -06:00
37cfb017f0
Add wordlist dual-location detection and README image sizing 2025-11-01 00:31:56 -06:00
rpriven
2006ba5a45
Added logo 2025-11-01 00:27:03 -06:00
37085d853a
Add wordlist management with SecLists support - v2.1 COMPLETE
Implemented comprehensive wordlist management system.

Features:
- New main menu option "6) Manage Wordlists"
- Install SecLists from GitHub (~500MB collection)
- View wordlist directory structure with file counts
- Update SecLists with git pull
- Installs to ~/wordlists/SecLists (user-owned)

Implementation:
- wordlist_menu() - Interactive wordlist management
- install_seclists() - Clone SecLists with --depth 1
- view_wordlists() - Browse installed wordlists by category
- update_seclists() - Pull latest from GitHub
- Shows popular wordlist categories after install
- Handles reinstall with confirmation prompt

SecLists Categories:
- Passwords (rockyou, common, leaked databases)
- Usernames (common names and usernames)
- Discovery (DNS, web content, subdomains)
- Fuzzing (XSS, SQLi, injection payloads)
- Payloads, IOCs, Web-Shells, Pattern-Matching

Installation Details:
- Location: ~/wordlists/SecLists/
- Size: ~500MB (compressed download)
- Uses --depth 1 for faster clone
- User-owned, no sudo required
- Easy to update with git pull

Image Update:
- Replaced 21 individual images with single toolbelt.jpeg
- Selected best image (seed_13) with tools visible on belt
- Cleaned up images directory

v2.1 Status: ALL FEATURES COMPLETE
 Individual Tool Selection
 Tool Update Detection
 Wordlist Management

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 00:17:21 -06:00
c4f40e79c8
Improve tool update output and version display
Fixed two UX issues in tool update management:

1. Version Check Output:
   - Extract version numbers using regex (v1.2.3 pattern)
   - Show clean version instead of full banner output
   - Fallback to "installed" if version can't be parsed
   - Fixes noise from tool ASCII art banners

2. Update All Go Tools:
   - List all tools before confirmation prompt
   - Show which tools are installed vs will be skipped
   - Skip uninstalled tools during update loop
   - Report skipped count in final summary
   - Users can see exactly what will be updated

Changes:
- Added regex version extraction in check_tool_versions()
- Added tool list display in update_all_go_tools()
- Added skip logic for uninstalled tools
- Updated summary to show: Updated | Failed | Skipped

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 00:11:49 -06:00
bb18a5c070
Add tool update management with hybrid PDTM/go install approach
Implemented comprehensive tool update system with 4 options:
1. Check versions only (show installed vs latest)
2. Update all ProjectDiscovery tools (pdtm -ua) - FAST
3. Update all Go tools (go install @latest for each)
4. Select individual tools to update (gum multi-select)

Features:
- New main menu option "5) Check for Tool Updates"
- Hybrid approach: pdtm for PD tools, go install for all tools
- Auto-installs pdtm if not present
- Interactive gum multi-select for selective updates
- Progress indicators with success/fail counts
- Confirmation prompts before bulk updates
- Comprehensive logging of update operations

Implementation:
- Added update_tools_menu() with 4-option submenu
- check_tool_versions() - displays installed tool versions
- update_pd_tools_bulk() - fast PDTM update for PD tools
- update_all_go_tools() - comprehensive update for all Go tools
- update_selected_tools() - gum multi-select for individual updates
- Updated README with update strategies and usage examples
- Marked feature as complete in TODO.md

This gives users maximum flexibility:
- Power users: Quick pdtm update for all PD tools
- Comprehensive: Update everything including non-PD tools
- Selective: Cherry-pick specific tools to update
- Check-only: See what's outdated without updating

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-11-01 00:03:32 -06:00
5bc00b9643
Fix Python tools category crash in multi-select
Fixed AttributeError when selecting Python tools individually.

Problem:
- config.PYTHON_TOOLS is defined as a list, not a dict
- Code was calling .keys() on a list object
- Error: AttributeError: 'list' object has no attribute 'keys'

Solution:
- Removed .keys() call for Python tools since it's already a list
- Python tools now work correctly in multi-select menu

Note: Scripts category intentionally only allows "Install All"
since scripts are downloaded as a collection set.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 23:53:45 -06:00
a210803453
Fix gum multi-select TTY access issue
Fixed subprocess call to allow gum direct terminal access for interactive UI.

Problem:
- capture_output=True was preventing gum from accessing the TTY
- Gum needs stdin/stderr connected to terminal for interactive display
- Error: "could not open a new TTY: open /dev/tty"

Solution:
- Changed from capture_output=True to explicit stdout=PIPE
- Set stdin=None and stderr=None to allow direct terminal access
- Gum can now properly display interactive selection menu

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-31 23:50:12 -06:00
27 changed files with 623 additions and 10 deletions

View file

@ -1,5 +1,9 @@
# Djedi Toolbelt v2.0 # Djedi Toolbelt v2.0
<p align="center">
<img src="images/toolbelt.png" alt="Djedi Toolbelt" width="500">
</p>
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![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/) [![Python: 3.6+](https://img.shields.io/badge/Python-3.6+-blue.svg)](https://www.python.org/)
@ -43,6 +47,8 @@ python3 toolbelt.py
- Browse & Select Categories - Browse & Select Categories
- Install Prerequisites (fresh) - Install Prerequisites (fresh)
- View Installed Tools - View Installed Tools
- Check for Tool Updates
- Manage Wordlists
**Level 2 - Categories:** **Level 2 - Categories:**
- 📦 APT Tools - Package manager tools - 📦 APT Tools - Package manager tools
@ -54,7 +60,18 @@ python3 toolbelt.py
**Level 3 - Tool Selection:** **Level 3 - Tool Selection:**
- Install all tools in category - Install all tools in category
- Individual tool selection (coming soon) - Individual tool selection (gum multi-select)
**Tool Update Management:**
- Check versions of installed tools
- Update all ProjectDiscovery tools (pdtm)
- Update all Go tools to @latest
- Select individual tools to update (gum multi-select)
**Wordlist Management:**
- Install SecLists (comprehensive wordlist collection)
- View installed wordlists and directory structure
- Update SecLists from GitHub
### Pre-Built Profiles ### Pre-Built Profiles
@ -126,7 +143,7 @@ wfuzz, arjun, scrapy, tld, requests, fuzzywuzzy
**RustScan** - Fast port scanner **RustScan** - Fast port scanner
- Includes alias setup for shell - Includes alias setup for shell
### Useful Scripts (downloaded to ~/scripts) ### Useful Scripts (downloaded to ~/scripts/payloads)
- **linpeas.sh** - Linux privilege escalation - **linpeas.sh** - Linux privilege escalation
- **jaws-enum.ps1** - Windows enumeration - **jaws-enum.ps1** - Windows enumeration
@ -190,6 +207,46 @@ python3 toolbelt.py
# Select: 4) View Installed Tools # Select: 4) View Installed Tools
``` ```
### Update Tools
```bash
python3 toolbelt.py
# Select: 5) Check for Tool Updates
# Option 1: Check versions only (see what's outdated)
# Option 2: Update all ProjectDiscovery tools (pdtm -ua)
# Option 3: Update all Go tools to @latest
# Option 4: Select specific tools to update (gum multi-select)
```
**Update strategies:**
- **Fast PD Update:** Option 2 uses `pdtm` for lightning-fast ProjectDiscovery tool updates
- **Comprehensive Update:** Option 3 updates ALL Go tools (PD + non-PD)
- **Selective Update:** Option 4 lets you cherry-pick which tools to update
### Manage Wordlists
```bash
python3 toolbelt.py
# Select: 6) Manage Wordlists
# Option 1: Install SecLists (~500MB)
# Option 2: View installed wordlists and structure
# Option 3: Update SecLists from GitHub
```
**SecLists includes:**
- **Passwords**: rockyou, common passwords, leaked databases
- **Usernames**: Common usernames and names
- **Subdomains**: DNS enumeration wordlists
- **Directories**: Web content discovery lists
- **Fuzzing**: XSS, SQLi, and other injection payloads
**Installation locations:**
- Kali default: `/usr/share/seclists` (via apt package)
- Custom install: `~/wordlists/SecLists/` (via git clone)
- Toolbelt automatically detects both locations
--- ---
## 🔗 Integration with Fresh ## 🔗 Integration with Fresh

View file

@ -312,10 +312,10 @@ def download_with_progress(url: str, output: str):
## Implementation Priority ## Implementation Priority
**v2.1 (Next Release):** **v2.1 (COMPLETE):**
1. Individual Tool Selection (gum multi-select) ✅ **COMPLETED** 1. Individual Tool Selection (gum multi-select) ✅ **COMPLETED**
2. Tool Update Detection 🔜 2. Tool Update Detection ✅ **COMPLETED**
3. Wordlist Management 🔜 3. Wordlist Management ✅ **COMPLETED**
**v2.2:** **v2.2:**
4. Resource Monitoring 4. Resource Monitoring

View file

@ -130,7 +130,7 @@ DOCKER_TOOLS = {
}, },
} }
# Useful Scripts - Downloaded to ~/scripts # Useful Scripts - Downloaded to ~/scripts/payloads
USEFUL_SCRIPTS = { USEFUL_SCRIPTS = {
"linpeas.sh": "https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh", "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", "jaws-enum.ps1": "https://github.com/411Hall/JAWS/raw/master/jaws-enum.ps1",

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 134 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 117 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 89 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 109 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 64 KiB

BIN
images/toolbelt.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,020 KiB

View file

@ -446,9 +446,9 @@ def download_useful_scripts(
if logger: if logger:
logger.info(f"Downloading scripts: {', '.join(scripts.keys())}") logger.info(f"Downloading scripts: {', '.join(scripts.keys())}")
# Create scripts directory in user's home (not /root!) # Create scripts/payloads directory in user's home (not /root!)
home = get_home_dir() home = get_home_dir()
scripts_dir = os.path.join(home, 'scripts') scripts_dir = os.path.join(home, 'scripts', 'payloads')
ensure_directory(scripts_dir) ensure_directory(scripts_dir)
success_count = 0 success_count = 0

View file

@ -6,6 +6,8 @@ Interactive package manager for pentesting and security research tools
import sys import sys
import os import os
import subprocess
from pathlib import Path
from typing import Optional, List, Dict from typing import Optional, List, Dict
# Import local modules # Import local modules
@ -79,6 +81,8 @@ def show_main_menu(distro_name: str, distro_type: str):
print(colorize("2)", 'green') + " Browse & Select Categories") print(colorize("2)", 'green') + " Browse & Select Categories")
print(colorize("3)", 'green') + " Install Prerequisites (fresh)") print(colorize("3)", 'green') + " Install Prerequisites (fresh)")
print(colorize("4)", 'green') + " View Installed Tools") print(colorize("4)", 'green') + " View Installed Tools")
print(colorize("5)", 'green') + " Check for Tool Updates")
print(colorize("6)", 'green') + " Manage Wordlists")
print() print()
print(colorize("0)", 'red') + " Exit") print(colorize("0)", 'red') + " Exit")
print() print()
@ -98,6 +102,10 @@ def main_menu_loop(distro_name: str, distro_type: str, logger):
prompt_install_fresh() prompt_install_fresh()
elif choice == '4': elif choice == '4':
view_installed_tools() view_installed_tools()
elif choice == '5':
update_tools_menu(logger)
elif choice == '6':
wordlist_menu(logger)
elif choice == '0': elif choice == '0':
print() print()
print_success("Thank you for using Djedi Toolbelt!") print_success("Thank you for using Djedi Toolbelt!")
@ -350,7 +358,7 @@ def install_category_selected(category_id: str, distro_type: str, logger):
elif category_id == 'opt': elif category_id == 'opt':
tools_list = list(config.get_opt_tools_for_distro(distro_type).keys()) tools_list = list(config.get_opt_tools_for_distro(distro_type).keys())
elif category_id == 'python': elif category_id == 'python':
tools_list = list(config.PYTHON_TOOLS.keys()) tools_list = config.PYTHON_TOOLS # Already a list, not a dict
elif category_id == 'docker': elif category_id == 'docker':
tools_list = list(config.DOCKER_TOOLS.keys()) tools_list = list(config.DOCKER_TOOLS.keys())
elif category_id == 'scripts': elif category_id == 'scripts':
@ -457,6 +465,551 @@ def view_installed_tools():
input("Press Enter to continue...") input("Press Enter to continue...")
# ============================================================================
# Tool Update Management
# ============================================================================
def update_tools_menu(logger):
"""Tool update management menu"""
while True:
print_section("🔄 TOOL UPDATE MANAGEMENT")
print(colorize("1)", 'green') + " 📊 Check Versions Only")
print(" Show which tools are outdated")
print()
print(colorize("2)", 'green') + " ⚡ Update All ProjectDiscovery Tools")
print(" Fast bulk update using pdtm")
print()
print(colorize("3)", 'green') + " 🔧 Update All Go Tools")
print(" Update all Go tools to @latest")
print()
print(colorize("4)", 'green') + " 🎯 Select Individual Tools to Update")
print(" Choose specific tools with multi-select")
print()
print(colorize("0)", 'red') + " Back to Main Menu")
print()
choice = input(colorize("Select option: ", 'yellow')).strip()
if choice == '0':
return
elif choice == '1':
check_tool_versions(logger)
elif choice == '2':
update_pd_tools_bulk(logger)
elif choice == '3':
update_all_go_tools(logger)
elif choice == '4':
update_selected_tools(logger)
else:
print_error("Invalid option. Please try again.")
input("\nPress Enter to continue...")
def check_tool_versions(logger):
"""Check and display tool versions vs latest"""
print_section("📊 Checking Tool Versions")
print_info("Checking installed Go tools...")
print()
outdated = []
up_to_date = []
not_installed = []
for tool_name, module_path in config.GO_TOOLS.items():
# Check if tool is installed
if not check_command_exists(tool_name):
not_installed.append(tool_name)
continue
# Get installed version
try:
result = subprocess.run(
[tool_name, '-version'],
capture_output=True,
text=True,
timeout=5
)
# Try to extract just the version number, not the full banner
version_output = result.stdout.strip() or result.stderr.strip()
# Many tools print version on first line - extract it
if version_output:
first_line = version_output.split('\n')[0]
# Look for version patterns like "v1.2.3" or "1.2.3"
import re
version_match = re.search(r'v?\d+\.\d+\.\d+', first_line)
if version_match:
installed_version = version_match.group(0)
else:
# Fallback to first line if no version pattern found
installed_version = first_line[:50]
else:
installed_version = "installed"
up_to_date.append((tool_name, installed_version))
except Exception as e:
logger.debug(f"Could not get version for {tool_name}: {e}")
up_to_date.append((tool_name, "installed"))
# Display results
if up_to_date:
print(colorize("✓ Installed Tools:", 'green'))
for tool, version in up_to_date:
version_str = version[:50] + "..." if len(version) > 50 else version
print(f"{tool}: {version_str}")
print()
if not_installed:
print(colorize("○ Not Installed:", 'yellow'))
for tool in not_installed:
print(f"{tool}")
print()
print_info("💡 To update tools, use options 2-4 from the update menu")
print()
input("Press Enter to continue...")
def update_pd_tools_bulk(logger):
"""Update all ProjectDiscovery tools using pdtm"""
print_section("⚡ Updating ProjectDiscovery Tools")
# Check if pdtm is installed
if not check_command_exists('pdtm'):
print_warning("pdtm not found!")
print_info("Installing pdtm...")
try:
subprocess.run(
['go', 'install', '-v', 'github.com/projectdiscovery/pdtm/cmd/pdtm@latest'],
check=True
)
print_success("pdtm installed successfully")
except Exception as e:
print_error(f"Failed to install pdtm: {e}")
logger.error(f"Failed to install pdtm: {e}")
input("\nPress Enter to continue...")
return
print_info("Running: pdtm -ua (update all)")
print()
try:
# Run pdtm with direct terminal access
result = subprocess.run(
['pdtm', '-ua'],
check=False # Don't raise on non-zero exit
)
print()
if result.returncode == 0:
print_success("ProjectDiscovery tools updated successfully!")
else:
print_warning("Update completed with some issues")
logger.info(f"pdtm update completed with exit code {result.returncode}")
except Exception as e:
print_error(f"Update failed: {e}")
logger.error(f"pdtm update failed: {e}", exc_info=True)
print()
input("Press Enter to continue...")
def update_all_go_tools(logger):
"""Update all Go tools to @latest"""
print_section("🔧 Updating All Go Tools")
print_warning("This will update ALL Go tools to @latest")
print_info(f"Total tools: {len(config.GO_TOOLS)}")
print()
# List all tools that will be updated
print(colorize("Tools to update:", 'cyan'))
for tool_name in config.GO_TOOLS.keys():
# Check if installed
if check_command_exists(tool_name):
print(colorize(f"{tool_name}", 'green'))
else:
print(colorize(f"{tool_name} (not installed, will skip)", 'yellow'))
print()
response = input(colorize("Continue? [y/N]: ", 'yellow')).strip().lower()
if response != 'y':
print_warning("Update cancelled")
input("\nPress Enter to continue...")
return
print()
success_count = 0
fail_count = 0
skipped_count = 0
for tool_name, module_path in config.GO_TOOLS.items():
# Skip if not installed
if not check_command_exists(tool_name):
skipped_count += 1
continue
print(f"Updating {tool_name}...", end=' ')
try:
result = subprocess.run(
['go', 'install', '-v', module_path],
capture_output=True,
text=True,
timeout=300
)
if result.returncode == 0:
print(colorize("", 'green'))
success_count += 1
logger.info(f"Updated {tool_name}")
else:
print(colorize("", 'red'))
fail_count += 1
logger.warning(f"Failed to update {tool_name}: {result.stderr}")
except Exception as e:
print(colorize("", 'red'))
fail_count += 1
logger.error(f"Error updating {tool_name}: {e}")
print()
print_info(f"Updated: {success_count} | Failed: {fail_count} | Skipped: {skipped_count}")
print()
input("Press Enter to continue...")
def update_selected_tools(logger):
"""Update selected Go tools using gum multi-select"""
print_section("🎯 Select Tools to Update")
# Check if gum is available
if not check_command_exists('gum'):
print()
print_error("gum is not installed!")
print_info("gum is required for interactive multi-select")
print()
print_info("Install gum with:")
print(" go install github.com/charmbracelet/gum@latest")
print()
input("Press Enter to continue...")
return
tool_list = list(config.GO_TOOLS.keys())
print_info(f"Available tools: {len(tool_list)}")
print()
print(colorize("TIP: Use SPACE to select, ENTER when done", 'yellow'))
print()
# Use gum for multi-select
selected = gum_multi_select(
tool_list,
header="Select tools to update:"
)
if not selected:
print()
print_warning("No tools selected")
input("\nPress Enter to continue...")
return
# Show selection
print()
print_section(f"Updating {len(selected)} Selected Tools")
for tool in selected:
print(colorize(f"{tool}", 'cyan'))
print()
# Confirm
response = input(colorize("Proceed with update? [Y/n]: ", 'yellow')).strip().lower()
if response == 'n':
print_warning("Update cancelled")
input("\nPress Enter to continue...")
return
print()
success_count = 0
fail_count = 0
for tool_name in selected:
module_path = config.GO_TOOLS[tool_name]
print(f"Updating {tool_name}...", end=' ')
try:
result = subprocess.run(
['go', 'install', '-v', module_path],
capture_output=True,
text=True,
timeout=300
)
if result.returncode == 0:
print(colorize("", 'green'))
success_count += 1
logger.info(f"Updated {tool_name}")
else:
print(colorize("", 'red'))
fail_count += 1
logger.warning(f"Failed to update {tool_name}: {result.stderr}")
except Exception as e:
print(colorize("", 'red'))
fail_count += 1
logger.error(f"Error updating {tool_name}: {e}")
print()
print_info(f"Updated: {success_count} | Failed: {fail_count}")
print()
input("Press Enter to continue...")
# ============================================================================
# Wordlist Management
# ============================================================================
def find_seclists_path():
"""
Find SecLists installation path
Checks common locations:
1. /usr/share/seclists (Kali default, lowercase)
2. ~/wordlists/SecLists (custom install)
Returns:
Tuple of (path, found) - path is the location, found is True if exists
"""
# Check Kali default location first (lowercase)
kali_path = "/usr/share/seclists"
if os.path.isdir(kali_path):
return (kali_path, True)
# Check custom install location
custom_path = os.path.expanduser("~/wordlists/SecLists")
if os.path.isdir(custom_path):
return (custom_path, True)
# Default to custom path if neither exists (for installation)
return (custom_path, False)
def wordlist_menu(logger):
"""Wordlist management menu"""
while True:
print_section("📚 WORDLIST MANAGEMENT")
# Check if SecLists is installed
seclists_path, seclists_installed = find_seclists_path()
print(colorize("1)", 'green') + " Install SecLists")
if seclists_installed:
print(colorize(f" ✓ Already installed at {seclists_path}", 'green'))
else:
print(" Comprehensive wordlist collection")
print()
print(colorize("2)", 'green') + " View Installed Wordlists")
print(" Browse wordlist directory structure")
print()
print(colorize("3)", 'green') + " Update SecLists")
if seclists_installed:
print(" Pull latest updates from GitHub")
else:
print(colorize(" (Requires SecLists to be installed first)", 'yellow'))
print()
print(colorize("0)", 'red') + " Back to Main Menu")
print()
choice = input(colorize("Select option: ", 'yellow')).strip()
if choice == '0':
return
elif choice == '1':
install_seclists(logger)
elif choice == '2':
view_wordlists(logger)
elif choice == '3':
update_seclists(logger, seclists_installed)
else:
print_error("Invalid option. Please try again.")
input("\nPress Enter to continue...")
def install_seclists(logger):
"""Install SecLists wordlist collection"""
print_section("📥 Installing SecLists")
wordlists_dir = os.path.expanduser("~/wordlists")
seclists_path = os.path.join(wordlists_dir, "SecLists")
# Check if already installed
if os.path.isdir(seclists_path):
print_warning("SecLists is already installed!")
print_info(f"Location: {seclists_path}")
print()
response = input(colorize("Reinstall? This will delete and re-clone. [y/N]: ", 'yellow')).strip().lower()
if response != 'y':
print_warning("Installation cancelled")
input("\nPress Enter to continue...")
return
# Remove existing
print_info("Removing existing SecLists...")
try:
subprocess.run(['rm', '-rf', seclists_path], check=True)
except Exception as e:
print_error(f"Failed to remove existing SecLists: {e}")
logger.error(f"Failed to remove SecLists: {e}")
input("\nPress Enter to continue...")
return
# Create wordlists directory
if not os.path.isdir(wordlists_dir):
print_info(f"Creating {wordlists_dir}...")
os.makedirs(wordlists_dir, exist_ok=True)
# Clone SecLists
print_info("Cloning SecLists from GitHub...")
print_warning("This is a large repository (~500MB), it may take a few minutes...")
print()
try:
result = subprocess.run(
['git', 'clone', '--depth', '1', 'https://github.com/danielmiessler/SecLists.git', seclists_path],
check=False
)
if result.returncode == 0:
print()
print_success("SecLists installed successfully!")
print_info(f"Location: {seclists_path}")
print()
print_info("Popular wordlists:")
print(f" • Passwords: {seclists_path}/Passwords/")
print(f" • Usernames: {seclists_path}/Usernames/")
print(f" • Subdomains: {seclists_path}/Discovery/DNS/")
print(f" • Directories: {seclists_path}/Discovery/Web-Content/")
print(f" • Fuzzing: {seclists_path}/Fuzzing/")
logger.info("SecLists installed successfully")
else:
print_error("Failed to clone SecLists repository")
logger.error("SecLists installation failed")
except Exception as e:
print_error(f"Installation failed: {e}")
logger.error(f"SecLists installation error: {e}", exc_info=True)
print()
input("Press Enter to continue...")
def view_wordlists(logger):
"""View installed wordlist directory structure"""
print_section("📂 Installed Wordlists")
seclists_path, seclists_installed = find_seclists_path()
if not seclists_installed:
print_warning("SecLists not found")
print_info("Use option 1 to install SecLists")
print_info(f"Checked locations:")
print_info(f" • /usr/share/seclists (Kali default)")
print_info(f" • ~/wordlists/SecLists (custom install)")
print()
input("Press Enter to continue...")
return
# Show SecLists structure
print(colorize(f"SecLists Location: {seclists_path}", 'cyan'))
print()
categories = [
"Discovery",
"Fuzzing",
"IOCs",
"Miscellaneous",
"Passwords",
"Pattern-Matching",
"Payloads",
"Usernames",
"Web-Shells"
]
for category in categories:
category_path = os.path.join(seclists_path, category)
if os.path.isdir(category_path):
# Count files in category
try:
file_count = sum(1 for _ in Path(category_path).rglob('*') if _.is_file())
print(colorize(f" 📁 {category}/", 'green') + f" ({file_count} files)")
except Exception:
print(colorize(f" 📁 {category}/", 'green'))
print()
print_info(f"Full path: {seclists_path}")
print()
input("Press Enter to continue...")
def update_seclists(logger, seclists_installed: bool):
"""Update SecLists from GitHub"""
print_section("🔄 Updating SecLists")
if not seclists_installed:
print_warning("SecLists is not installed!")
print_info("Use option 1 to install SecLists first")
print()
input("Press Enter to continue...")
return
seclists_path, _ = find_seclists_path()
print_info(f"Updating SecLists at: {seclists_path}")
# Check if this is a system-installed version
if seclists_path.startswith('/usr/'):
print_warning("SecLists is installed in system directory (/usr/share/seclists)")
print_info("This was likely installed via apt package manager")
print_info("To update: sudo apt update && sudo apt upgrade seclists")
print()
input("Press Enter to continue...")
return
print_info("Pulling latest updates from GitHub...")
print()
try:
# Run git pull
result = subprocess.run(
['git', '-C', seclists_path, 'pull'],
check=False
)
print()
if result.returncode == 0:
print_success("SecLists updated successfully!")
else:
print_warning("Update completed with issues")
print_info("If this is a git repository, try: cd {seclists_path} && git pull")
print_info("Otherwise, reinstall with option 1")
logger.info(f"SecLists update completed with exit code {result.returncode}")
except Exception as e:
print_error(f"Update failed: {e}")
logger.error(f"SecLists update error: {e}", exc_info=True)
print()
input("Press Enter to continue...")
# ============================================================================ # ============================================================================
# Main Entry Point # Main Entry Point
# ============================================================================ # ============================================================================

View file

@ -188,9 +188,12 @@ def gum_multi_select(
return [] return []
try: try:
# gum needs direct terminal access - don't redirect stdin/stderr
result = subprocess.run( result = subprocess.run(
['gum', 'choose', '--no-limit', '--header', header] + options, ['gum', 'choose', '--no-limit', '--header', header] + options,
capture_output=True, stdout=subprocess.PIPE,
stderr=None, # Let stderr go to terminal
stdin=None, # Let gum access the terminal directly
text=True, text=True,
timeout=300 # 5 minute timeout timeout=300 # 5 minute timeout
) )