diff --git a/README.md b/README.md index 958734d..87714c1 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ python3 toolbelt.py - Install Prerequisites (fresh) - View Installed Tools - Check for Tool Updates +- Manage Wordlists **Level 2 - Categories:** - 📦 APT Tools - Package manager tools @@ -63,6 +64,11 @@ python3 toolbelt.py - 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 **Bug Bounty Hunter** - Web app testing and reconnaissance @@ -214,6 +220,26 @@ python3 toolbelt.py - **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 location:** `~/wordlists/SecLists/` + --- ## 🔗 Integration with Fresh diff --git a/TODO.md b/TODO.md index 7f4e4de..a4cb8f4 100644 --- a/TODO.md +++ b/TODO.md @@ -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 ✅ **COMPLETED** -3. Wordlist Management 🔜 +3. Wordlist Management ✅ **COMPLETED** **v2.2:** 4. Resource Monitoring diff --git a/images/flux_jedi-toolbelt_seed_0_1.jpeg b/images/flux_jedi-toolbelt_seed_0_1.jpeg deleted file mode 100644 index a6542d0..0000000 Binary files a/images/flux_jedi-toolbelt_seed_0_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_10_1.jpeg b/images/flux_jedi-toolbelt_seed_10_1.jpeg deleted file mode 100644 index cd06466..0000000 Binary files a/images/flux_jedi-toolbelt_seed_10_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_11_1.jpeg b/images/flux_jedi-toolbelt_seed_11_1.jpeg deleted file mode 100644 index 16bf4ba..0000000 Binary files a/images/flux_jedi-toolbelt_seed_11_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_12_1.jpeg b/images/flux_jedi-toolbelt_seed_12_1.jpeg deleted file mode 100644 index 357bd0d..0000000 Binary files a/images/flux_jedi-toolbelt_seed_12_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_14_1.jpeg b/images/flux_jedi-toolbelt_seed_14_1.jpeg deleted file mode 100644 index da47608..0000000 Binary files a/images/flux_jedi-toolbelt_seed_14_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_15_1.jpeg b/images/flux_jedi-toolbelt_seed_15_1.jpeg deleted file mode 100644 index 926c697..0000000 Binary files a/images/flux_jedi-toolbelt_seed_15_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_16_1.jpeg b/images/flux_jedi-toolbelt_seed_16_1.jpeg deleted file mode 100644 index 5ccb140..0000000 Binary files a/images/flux_jedi-toolbelt_seed_16_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_17_1.jpeg b/images/flux_jedi-toolbelt_seed_17_1.jpeg deleted file mode 100644 index 407aaa4..0000000 Binary files a/images/flux_jedi-toolbelt_seed_17_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_18_1.jpeg b/images/flux_jedi-toolbelt_seed_18_1.jpeg deleted file mode 100644 index f1ba920..0000000 Binary files a/images/flux_jedi-toolbelt_seed_18_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_19_1.jpeg b/images/flux_jedi-toolbelt_seed_19_1.jpeg deleted file mode 100644 index 1ec4d20..0000000 Binary files a/images/flux_jedi-toolbelt_seed_19_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_1_1.jpeg b/images/flux_jedi-toolbelt_seed_1_1.jpeg deleted file mode 100644 index 624e953..0000000 Binary files a/images/flux_jedi-toolbelt_seed_1_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_2_1.jpeg b/images/flux_jedi-toolbelt_seed_2_1.jpeg deleted file mode 100644 index 54417d1..0000000 Binary files a/images/flux_jedi-toolbelt_seed_2_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_3_1.jpeg b/images/flux_jedi-toolbelt_seed_3_1.jpeg deleted file mode 100644 index dbbd79d..0000000 Binary files a/images/flux_jedi-toolbelt_seed_3_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_4_1.jpeg b/images/flux_jedi-toolbelt_seed_4_1.jpeg deleted file mode 100644 index bad386b..0000000 Binary files a/images/flux_jedi-toolbelt_seed_4_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_5_1.jpeg b/images/flux_jedi-toolbelt_seed_5_1.jpeg deleted file mode 100644 index fedf98f..0000000 Binary files a/images/flux_jedi-toolbelt_seed_5_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_6_1.jpeg b/images/flux_jedi-toolbelt_seed_6_1.jpeg deleted file mode 100644 index bd6eec8..0000000 Binary files a/images/flux_jedi-toolbelt_seed_6_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_7_1.jpeg b/images/flux_jedi-toolbelt_seed_7_1.jpeg deleted file mode 100644 index 820c53c..0000000 Binary files a/images/flux_jedi-toolbelt_seed_7_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_8_1.jpeg b/images/flux_jedi-toolbelt_seed_8_1.jpeg deleted file mode 100644 index f552b31..0000000 Binary files a/images/flux_jedi-toolbelt_seed_8_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_9_1.jpeg b/images/flux_jedi-toolbelt_seed_9_1.jpeg deleted file mode 100644 index 7f9d297..0000000 Binary files a/images/flux_jedi-toolbelt_seed_9_1.jpeg and /dev/null differ diff --git a/images/flux_jedi-toolbelt_seed_13_1.jpeg b/images/toolbelt.jpeg similarity index 99% rename from images/flux_jedi-toolbelt_seed_13_1.jpeg rename to images/toolbelt.jpeg index b19d466..1cee2da 100644 Binary files a/images/flux_jedi-toolbelt_seed_13_1.jpeg and b/images/toolbelt.jpeg differ diff --git a/toolbelt.py b/toolbelt.py index ce1691a..8f698db 100755 --- a/toolbelt.py +++ b/toolbelt.py @@ -7,6 +7,7 @@ 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 @@ -81,6 +82,7 @@ def show_main_menu(distro_name: str, distro_type: str): 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() @@ -102,6 +104,8 @@ def main_menu_loop(distro_name: str, distro_type: str, logger): 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!") @@ -765,6 +769,217 @@ def update_selected_tools(logger): input("Press Enter to continue...") +# ============================================================================ +# Wordlist Management +# ============================================================================ + +def wordlist_menu(logger): + """Wordlist management menu""" + while True: + print_section("📚 WORDLIST MANAGEMENT") + + # Check if SecLists is installed + seclists_path = os.path.expanduser("~/wordlists/SecLists") + seclists_installed = os.path.isdir(seclists_path) + + print(colorize("1)", 'green') + " Install SecLists") + if seclists_installed: + print(colorize(" ✓ Already installed at ~/wordlists/SecLists", '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") + + wordlists_dir = os.path.expanduser("~/wordlists") + + if not os.path.isdir(wordlists_dir): + print_warning("No wordlists directory found") + print_info(f"Expected location: {wordlists_dir}") + print() + input("Press Enter to continue...") + return + + seclists_path = os.path.join(wordlists_dir, "SecLists") + + if not os.path.isdir(seclists_path): + print_warning("SecLists not found") + print_info("Use option 1 to install SecLists") + 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 = os.path.expanduser("~/wordlists/SecLists") + + 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("Try reinstalling if problems persist (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 # ============================================================================