diff --git a/.gitignore b/.gitignore index 0a61c7ff..d52975e0 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ wheels/ # C# / .NET bin/ +!Python/modules/bin/ obj/ *.user *.suo diff --git a/INSTALLATION.md b/INSTALLATION.md index 4c50ea76..751899fa 100644 --- a/INSTALLATION.md +++ b/INSTALLATION.md @@ -11,6 +11,38 @@ EyeWitness now uses **Python virtual environments** for all installations, provi ## Installation Methods +### 🐍 pipx Installation (All Platforms) + +The quickest way to install EyeWitness — no cloning or setup scripts needed: + +```bash +# Install pipx if you don't have it +apt install pipx + +# Install EyeWitness from GitHub +pipx install git+https://github.com/RedSiege/EyeWitness.git + +# Update your PATH environment variable then open a new terminal for the PATH change to take effect +pipx ensurepath +``` + +This creates an `eyewitness` command in an isolated environment. Usage: + +```bash +eyewitness --single https://example.com +eyewitness -f urls.txt +eyewitness -x nmap_scan.xml +``` + +**Requirements:** +- Python 3.8+ with pip +- Chrome/Chromium browser (must be installed separately — pipx only handles Python dependencies) + +**Uninstall:** +```bash +pipx uninstall eyewitness +``` + ### 🐧 Linux/macOS Installation ```bash diff --git a/Python/EyeWitness.py b/Python/EyeWitness.py index 80cfa2c5..ced071e7 100755 --- a/Python/EyeWitness.py +++ b/Python/EyeWitness.py @@ -493,11 +493,11 @@ def exitsig(*args): sort_data_and_write(cli_parsed, results) -if __name__ == "__main__": +def main(): cli_parsed = create_cli_parser() start_time = time.time() title_screen(cli_parsed) - + if cli_parsed.resume: print('[*] Loading Resume Data...') temp = cli_parsed @@ -529,21 +529,21 @@ def exitsig(*args): print('[*] Running in URL validation mode only') from modules.validation import validate_url_list from modules.helpers import target_creator - + url_list = target_creator(cli_parsed) valid_urls, invalid_urls = validate_url_list(url_list, require_scheme=False) - + print(f'\n[*] Validation Results:') print(f' - Valid URLs: {len(valid_urls)}') print(f' - Invalid URLs: {len(invalid_urls)}') - + if invalid_urls: print('\n[!] Invalid URLs found:') for url, error in invalid_urls[:20]: # Show first 20 print(f' - {url}: {error}') if len(invalid_urls) > 20: print(f' ... and {len(invalid_urls) - 20} more') - + # Write valid URLs to file if valid_urls: valid_file = os.path.join(cli_parsed.d, 'valid_urls.txt') @@ -551,14 +551,14 @@ def exitsig(*args): for url in valid_urls: f.write(url + '\n') print(f'\n[*] Valid URLs written to: {valid_file}') - + if invalid_urls: invalid_file = os.path.join(cli_parsed.d, 'invalid_urls.txt') with open(invalid_file, 'w') as f: for url, error in invalid_urls: f.write(f'{url} # {error}\n') print(f'[*] Invalid URLs written to: {invalid_file}') - + print(f'\n[*] Validation completed in {time.time() - start_time:.2f} seconds') sys.exit(0) @@ -592,3 +592,7 @@ def exitsig(*args): sys.exit() class_info() sys.exit() + + +if __name__ == "__main__": + main() diff --git a/Python/ValidateDefinitions.py b/Python/ValidateDefinitions.py index 1f1edf13..0328fb02 100644 --- a/Python/ValidateDefinitions.py +++ b/Python/ValidateDefinitions.py @@ -148,14 +148,14 @@ def find_definition_files(): base = Path.cwd() candidates = { "categories": [ + base / "Python" / "modules" / "categories.txt", base / "Python" / "categories.txt", base / "categories.txt", - base / "categories.txt", ], "signatures": [ + base / "Python" / "modules" / "signatures.txt", base / "Python" / "signatures.txt", base / "signatures.txt", - base / "signatures.txt", ] } paths = {} diff --git a/Python/bin/bootstrap.css b/Python/modules/bin/bootstrap.css similarity index 100% rename from Python/bin/bootstrap.css rename to Python/modules/bin/bootstrap.css diff --git a/Python/bin/bootstrap.min.css b/Python/modules/bin/bootstrap.min.css similarity index 100% rename from Python/bin/bootstrap.min.css rename to Python/modules/bin/bootstrap.min.css diff --git a/Python/bin/bootstrap.min.js b/Python/modules/bin/bootstrap.min.js similarity index 100% rename from Python/bin/bootstrap.min.js rename to Python/modules/bin/bootstrap.min.js diff --git a/Python/bin/dataTables.bootstrap4.min.css b/Python/modules/bin/dataTables.bootstrap4.min.css similarity index 100% rename from Python/bin/dataTables.bootstrap4.min.css rename to Python/modules/bin/dataTables.bootstrap4.min.css diff --git a/Python/bin/dataTables.bootstrap4.min.js b/Python/modules/bin/dataTables.bootstrap4.min.js similarity index 100% rename from Python/bin/dataTables.bootstrap4.min.js rename to Python/modules/bin/dataTables.bootstrap4.min.js diff --git a/Python/bin/dismissauth.xpi b/Python/modules/bin/dismissauth.xpi similarity index 100% rename from Python/bin/dismissauth.xpi rename to Python/modules/bin/dismissauth.xpi diff --git a/Python/bin/jquery-3.7.1.min.js b/Python/modules/bin/jquery-3.7.1.min.js similarity index 100% rename from Python/bin/jquery-3.7.1.min.js rename to Python/modules/bin/jquery-3.7.1.min.js diff --git a/Python/bin/jquery.dataTables.min.js b/Python/modules/bin/jquery.dataTables.min.js similarity index 100% rename from Python/bin/jquery.dataTables.min.js rename to Python/modules/bin/jquery.dataTables.min.js diff --git a/Python/bin/style.css b/Python/modules/bin/style.css similarity index 100% rename from Python/bin/style.css rename to Python/modules/bin/style.css diff --git a/Python/categories.txt b/Python/modules/categories.txt similarity index 100% rename from Python/categories.txt rename to Python/modules/categories.txt diff --git a/Python/modules/helpers.py b/Python/modules/helpers.py index bdc6372e..a945b846 100644 --- a/Python/modules/helpers.py +++ b/Python/modules/helpers.py @@ -618,7 +618,7 @@ def create_folders_css(cli_parsed): # Get paths using pathlib local_path = Path(__file__).parent - bin_path = local_path.parent / 'bin' + bin_path = local_path / 'bin' # Copy CSS and JS files using pathlib shutil.copy2(bin_path / 'jquery-3.7.1.min.js', output_dir) @@ -642,8 +642,8 @@ def default_creds_category(http_object): try: # Use pathlib for cross-platform path handling module_dir = Path(__file__).parent - sigpath = module_dir.parent / 'signatures.txt' - catpath = module_dir.parent / 'categories.txt' + sigpath = module_dir / 'signatures.txt' + catpath = module_dir / 'categories.txt' with open(sigpath) as sig_file: signatures = sig_file.readlines() diff --git a/Python/signatures.txt b/Python/modules/signatures.txt similarity index 100% rename from Python/signatures.txt rename to Python/modules/signatures.txt diff --git a/README.md b/README.md index 0dd454e1..d5aa6f74 100644 --- a/README.md +++ b/README.md @@ -47,6 +47,24 @@ EyeWitness/ > > **Note**: Docker support is currently in development. Please use native installation options below for now. +### 🐍 pipx Installation (Quickest) +**Install directly from GitHub — no cloning, no setup scripts:** + +```bash +pipx install git+https://github.com/RedSiege/EyeWitness.git +``` + +This creates an `eyewitness` command available system-wide in an isolated virtual environment. Then just run: + +```bash +eyewitness --single https://example.com +eyewitness -f urls.txt +``` + +**Requirements:** Python 3.8+, [pipx](https://pipx.pypa.io/), and Chrome/Chromium browser installed on your system. + +> **Note:** pipx handles Python dependencies automatically but does **not** install Chrome/Chromium. You must have a Chrome-based browser installed separately. + ### 🪟 Windows Installation **Automated setup with Python virtual environment:** @@ -133,6 +151,14 @@ python Python/EyeWitness.py --single https://example.com ### 🚀 **How to Use EyeWitness** After running the setup script, activate the virtual environment and run EyeWitness: +**🐍 pipx (no activation needed):** +```bash +eyewitness --single https://example.com +eyewitness -f urls.txt +eyewitness -x nmap_scan.xml +eyewitness -f urls.txt -d /path/to/output +``` + **🐧 Linux/macOS:** ```bash # 1. Activate the virtual environment diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..a398f2c2 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,34 @@ +[build-system] +requires = ["setuptools>=64", "wheel"] +build-backend = "setuptools.build_meta" + +[project] +name = "eyewitness" +version = "0.1.0" +description = "EyeWitness - screenshot websites and collect server header info" +readme = "README.md" +license = {text = "GPL-3.0"} +requires-python = ">=3.8" +dependencies = [ + "netaddr>=0.10.0", + "psutil>=5.9.0", + "selenium>=4.29.0", + "rapidfuzz>=3.0.0", + "pyvirtualdisplay>=3.0; sys_platform != 'win32'", + "argcomplete>=2.0.0", + "requests>=2.28.0", + "urllib3>=1.26.0", +] + +[project.scripts] +eyewitness = "EyeWitness:main" + +[tool.setuptools] +package-dir = {"" = "Python"} +py-modules = ["EyeWitness"] + +[tool.setuptools.packages.find] +where = ["Python"] + +[tool.setuptools.package-data] +modules = ["bin/*", "categories.txt", "signatures.txt"]