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
<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)
[![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
- Install Prerequisites (fresh)
- View Installed Tools
- Check for Tool Updates
- Manage Wordlists
**Level 2 - Categories:**
- 📦 APT Tools - Package manager tools
@ -54,7 +60,18 @@ python3 toolbelt.py
**Level 3 - Tool Selection:**
- 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
@ -126,7 +143,7 @@ wfuzz, arjun, scrapy, tld, requests, fuzzywuzzy
**RustScan** - Fast port scanner
- Includes alias setup for shell
### Useful Scripts (downloaded to ~/scripts)
### Useful Scripts (downloaded to ~/scripts/payloads)
- **linpeas.sh** - Linux privilege escalation
- **jaws-enum.ps1** - Windows enumeration
@ -190,6 +207,46 @@ python3 toolbelt.py
# 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

View file

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

View file

@ -130,7 +130,7 @@ DOCKER_TOOLS = {
},
}
# Useful Scripts - Downloaded to ~/scripts
# Useful Scripts - Downloaded to ~/scripts/payloads
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",

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:
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()
scripts_dir = os.path.join(home, 'scripts')
scripts_dir = os.path.join(home, 'scripts', 'payloads')
ensure_directory(scripts_dir)
success_count = 0

View file

@ -6,6 +6,8 @@ Interactive package manager for pentesting and security research tools
import sys
import os
import subprocess
from pathlib import Path
from typing import Optional, List, Dict
# 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("3)", 'green') + " Install Prerequisites (fresh)")
print(colorize("4)", 'green') + " View Installed Tools")
print(colorize("5)", 'green') + " Check for Tool Updates")
print(colorize("6)", 'green') + " Manage Wordlists")
print()
print(colorize("0)", 'red') + " Exit")
print()
@ -98,6 +102,10 @@ def main_menu_loop(distro_name: str, distro_type: str, logger):
prompt_install_fresh()
elif choice == '4':
view_installed_tools()
elif choice == '5':
update_tools_menu(logger)
elif choice == '6':
wordlist_menu(logger)
elif choice == '0':
print()
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':
tools_list = list(config.get_opt_tools_for_distro(distro_type).keys())
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':
tools_list = list(config.DOCKER_TOOLS.keys())
elif category_id == 'scripts':
@ -457,6 +465,551 @@ def view_installed_tools():
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
# ============================================================================

View file

@ -188,9 +188,12 @@ def gum_multi_select(
return []
try:
# gum needs direct terminal access - don't redirect stdin/stderr
result = subprocess.run(
['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,
timeout=300 # 5 minute timeout
)