├── tests ├── __init__.py └── scanner │ └── __init__.py ├── docker └── blank.txt ├── feedback └── blank.txt ├── ml_data ├── data │ └── blank.txt ├── feedback │ └── blank.txt ├── models │ └── blank.txt └── results │ └── blank.txt ├── models └── test.md ├── phantomfuzzer.egg-info ├── dependency_links.txt ├── top_level.txt ├── requires.txt ├── entry_points.txt ├── PKG-INFO └── SOURCES.txt ├── phantomfuzzer ├── utils │ ├── helpers.py │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── helper.cpython-311.pyc │ │ └── logging.cpython-311.pyc │ ├── __init__.py │ ├── logging.py │ └── helper.py ├── __pycache__ │ ├── config.cpython-311.pyc │ └── __init__.cpython-311.pyc ├── ml │ ├── __pycache__ │ │ ├── __init__.cpython-311.pyc │ │ ├── feedback.cpython-311.pyc │ │ ├── inference.cpython-311.pyc │ │ └── integration.cpython-311.pyc │ ├── models │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-311.pyc │ │ │ └── pattern_recognizer.cpython-311.pyc │ │ └── __init__.py │ ├── storage │ │ ├── __pycache__ │ │ │ ├── __init__.cpython-311.pyc │ │ │ └── pattern_db.cpython-311.pyc │ │ └── __init__.py │ ├── training │ │ ├── __pycache__ │ │ │ ├── trainer.cpython-311.pyc │ │ │ ├── __init__.cpython-311.pyc │ │ │ └── data_loader.cpython-311.pyc │ │ ├── __init__.py │ │ └── data_loader.py │ ├── __init__.py │ └── inference.py ├── scanner │ ├── __pycache__ │ │ ├── web.cpython-311.pyc │ │ ├── base.cpython-311.pyc │ │ ├── __init__.cpython-311.pyc │ │ ├── network.cpython-311.pyc │ │ ├── api_scanner.cpython-311.pyc │ │ ├── file_scanner.cpython-311.pyc │ │ └── ml_enhanced_scanner.cpython-311.pyc │ └── __init__.py ├── payload │ └── __init__.py ├── fuzzer │ ├── __init__.py │ ├── fuzzer_base.py │ └── protocol_fuzzer.py ├── __init__.py ├── vulnerability │ ├── base_analyzer.py │ ├── reporter.py │ ├── classifier.py │ ├── __init__.py │ ├── models.py │ └── severity.py └── config.py ├── phantomfuzzer.bundle ├── setup.py ├── requirements.txt ├── phantomfuzzer_cmd ├── ascii.txt ├── data ├── wordlists │ ├── common │ │ ├── extensions.txt │ │ └── directories.txt │ ├── sensitive │ │ ├── private.txt │ │ └── credentials.txt │ └── locations.txt └── patterns │ ├── patterns_export_20250321_230401.txt │ └── base_patterns.txt ├── docker-compose.yml ├── scapy_patch.py ├── phantomfuzzer_wrapper.sh ├── phantomfuzzer.1 ├── config └── default.yml ├── Dockerfile ├── examples ├── pattern_db_example.py ├── pattern_recognizer_with_db_example.py ├── ml_scanner_example.py └── ml_example.py ├── usage.txt ├── install.sh └── README.md /tests/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /tests/scanner/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docker/blank.txt: -------------------------------------------------------------------------------- 1 | blankslate 2 | -------------------------------------------------------------------------------- /feedback/blank.txt: -------------------------------------------------------------------------------- 1 | blankslate 2 | -------------------------------------------------------------------------------- /ml_data/data/blank.txt: -------------------------------------------------------------------------------- 1 | BLANKSLATE 2 | -------------------------------------------------------------------------------- /ml_data/feedback/blank.txt: -------------------------------------------------------------------------------- 1 | blankslate 2 | -------------------------------------------------------------------------------- /ml_data/models/blank.txt: -------------------------------------------------------------------------------- 1 | blankslate 2 | -------------------------------------------------------------------------------- /ml_data/results/blank.txt: -------------------------------------------------------------------------------- 1 | blankslate 2 | -------------------------------------------------------------------------------- /models/test.md: -------------------------------------------------------------------------------- 1 | blank file for folder/models 2 | -------------------------------------------------------------------------------- /phantomfuzzer.egg-info/dependency_links.txt: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /phantomfuzzer.egg-info/top_level.txt: -------------------------------------------------------------------------------- 1 | phantomfuzzer 2 | tests 3 | -------------------------------------------------------------------------------- /phantomfuzzer.egg-info/requires.txt: -------------------------------------------------------------------------------- 1 | pyyaml 2 | click 3 | requests 4 | -------------------------------------------------------------------------------- /phantomfuzzer/utils/helpers.py: -------------------------------------------------------------------------------- 1 | # Common utility functions 2 | # Helper methods used across modules -------------------------------------------------------------------------------- /phantomfuzzer.bundle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer.bundle -------------------------------------------------------------------------------- /phantomfuzzer.egg-info/entry_points.txt: -------------------------------------------------------------------------------- 1 | [console_scripts] 2 | phantomfuzzer = phantomfuzzer.cli:cli 3 | -------------------------------------------------------------------------------- /phantomfuzzer/__pycache__/config.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/__pycache__/config.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/__pycache__/feedback.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/__pycache__/feedback.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/web.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/web.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/__pycache__/inference.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/__pycache__/inference.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/__pycache__/integration.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/__pycache__/integration.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/base.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/base.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/utils/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/utils/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/utils/__pycache__/helper.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/utils/__pycache__/helper.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/utils/__pycache__/logging.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/utils/__pycache__/logging.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/network.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/network.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/models/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/models/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/storage/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/storage/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/training/__pycache__/trainer.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/training/__pycache__/trainer.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/api_scanner.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/api_scanner.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/storage/__pycache__/pattern_db.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/storage/__pycache__/pattern_db.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/training/__pycache__/__init__.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/training/__pycache__/__init__.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/file_scanner.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/file_scanner.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/training/__pycache__/data_loader.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/training/__pycache__/data_loader.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/models/__pycache__/pattern_recognizer.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/ml/models/__pycache__/pattern_recognizer.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__pycache__/ml_enhanced_scanner.cpython-311.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ghostsec420/PhantomFuzzer/HEAD/phantomfuzzer/scanner/__pycache__/ml_enhanced_scanner.cpython-311.pyc -------------------------------------------------------------------------------- /phantomfuzzer/ml/storage/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Storage module for ML-related data. 6 | 7 | This module provides storage functionality for ML-related data, 8 | including pattern databases and feature storage. 9 | """ 10 | 11 | from phantomfuzzer.ml.storage.pattern_db import PatternDatabase 12 | 13 | __all__ = ['PatternDatabase'] 14 | -------------------------------------------------------------------------------- /phantomfuzzer/ml/models/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Machine Learning Models for PhantomFuzzer. 6 | 7 | This package contains machine learning model definitions used for 8 | anomaly detection and pattern recognition in the PhantomFuzzer project. 9 | """ 10 | 11 | from phantomfuzzer.ml.models.pattern_recognizer import PatternRecognizer 12 | 13 | __all__ = [ 14 | 'PatternRecognizer' 15 | ] -------------------------------------------------------------------------------- /phantomfuzzer/ml/training/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Machine Learning Training Utilities for PhantomFuzzer. 6 | 7 | This package contains utilities for training machine learning models, 8 | including data loading, preprocessing, and model training orchestration. 9 | """ 10 | 11 | from phantomfuzzer.ml.training.data_loader import DataLoader 12 | from phantomfuzzer.ml.training.trainer import ModelTrainer 13 | 14 | __all__ = [ 15 | 'DataLoader', 16 | 'ModelTrainer' 17 | ] -------------------------------------------------------------------------------- /phantomfuzzer/payload/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Payload Module for PhantomFuzzer. 6 | 7 | This module provides payload generation capabilities for the PhantomFuzzer project, 8 | including various attack vectors and payload types for security testing. 9 | """ 10 | 11 | # Import key components for easy access 12 | from phantomfuzzer.payload.generator import PayloadGenerator 13 | 14 | # Define what's available when using "from phantomfuzzer.payload import *" 15 | __all__ = [ 16 | 'PayloadGenerator' 17 | ] 18 | -------------------------------------------------------------------------------- /phantomfuzzer.egg-info/PKG-INFO: -------------------------------------------------------------------------------- 1 | Metadata-Version: 2.2 2 | Name: phantomfuzzer 3 | Version: 0.1.0 4 | Summary: PhantomFuzzer: Advanced Security Testing Toolkit 5 | Author: Security Research Team 6 | Author-email: info@phantomfuzzer.com 7 | Classifier: Development Status :: 4 - Beta 8 | Classifier: Intended Audience :: Information Technology 9 | Classifier: License :: OSI Approved :: MIT License 10 | Classifier: Programming Language :: Python :: 3 11 | Classifier: Programming Language :: Python :: 3.8 12 | Classifier: Topic :: Security 13 | Requires-Python: >=3.8 14 | Requires-Dist: pyyaml 15 | Requires-Dist: click 16 | Requires-Dist: requests 17 | Dynamic: author 18 | Dynamic: author-email 19 | Dynamic: classifier 20 | Dynamic: requires-dist 21 | Dynamic: requires-python 22 | Dynamic: summary 23 | -------------------------------------------------------------------------------- /phantomfuzzer/fuzzer/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Fuzzer Module for PhantomFuzzer. 6 | 7 | This module provides fuzzing capabilities for the PhantomFuzzer project, 8 | including protocol fuzzing, input field fuzzing, and API fuzzing. 9 | """ 10 | 11 | # Import key components for easy access 12 | from phantomfuzzer.fuzzer.fuzzer_base import BaseFuzzer 13 | from phantomfuzzer.fuzzer.protocol_fuzzer import ProtocolFuzzer 14 | from phantomfuzzer.fuzzer.input_fuzzer import InputFuzzer 15 | from phantomfuzzer.fuzzer.api_fuzzer import ApiFuzzer 16 | from phantomfuzzer.fuzzer.mutation_engine import MutationEngine 17 | 18 | # Define what's available when using "from phantomfuzzer.fuzzer import *" 19 | __all__ = [ 20 | 'BaseFuzzer', 21 | 'ProtocolFuzzer', 22 | 'InputFuzzer', 23 | 'MutationEngine', 24 | 'ApiFuzzer' 25 | ] 26 | -------------------------------------------------------------------------------- /phantomfuzzer/ml/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Machine Learning Module for PhantomFuzzer. 6 | 7 | This module provides machine learning capabilities for the PhantomFuzzer project, 8 | including anomaly detection, pattern recognition, and model training utilities. 9 | """ 10 | 11 | # Import key components for easy access 12 | from phantomfuzzer.ml.integration import MLIntegration 13 | from phantomfuzzer.ml.models.pattern_recognizer import PatternRecognizer 14 | from phantomfuzzer.ml.training.data_loader import DataLoader 15 | from phantomfuzzer.ml.training.trainer import ModelTrainer 16 | from phantomfuzzer.ml.inference import InferenceEngine 17 | from phantomfuzzer.ml.feedback import FeedbackLoop 18 | from phantomfuzzer.ml.storage.pattern_db import PatternDatabase 19 | 20 | # Define what's available when using "from phantomfuzzer.ml import *" 21 | __all__ = [ 22 | 'MLIntegration', 23 | 'PatternRecognizer', 24 | 'DataLoader', 25 | 'ModelTrainer', 26 | 'InferenceEngine', 27 | 'FeedbackLoop', 28 | 'PatternDatabase' 29 | ] 30 | -------------------------------------------------------------------------------- /phantomfuzzer/utils/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Utility modules for PhantomFuzzer. 6 | 7 | This package provides various utility functions and classes used throughout 8 | the PhantomFuzzer toolkit, including logging, output formatting, and helper functions. 9 | """ 10 | 11 | # Import and expose key functions from the logging module 12 | from phantomfuzzer.utils.logging import ( 13 | get_logger, get_module_logger, setup_logger, 14 | log_start_operation, log_end_operation, log_scan_result 15 | ) 16 | 17 | # Import and expose key functions and classes from the helper module 18 | from phantomfuzzer.utils.helper import ( 19 | # Enums and constants 20 | VerbosityLevel, Colors, 21 | 22 | # Configuration functions 23 | set_verbosity, get_verbosity, set_use_colors, 24 | 25 | # Output formatting functions 26 | format_text, print_quiet, print_normal, print_verbose, print_debug, 27 | print_error, print_warning, print_success, print_info, print_status, 28 | print_result, print_json, print_banner, print_section, print_summary, 29 | print_progress 30 | ) -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | from setuptools import setup, find_packages 5 | 6 | # Core dependencies only - minimal set needed for basic functionality 7 | # For full functionality, refer to requirements.txt 8 | core_requirements = [ 9 | "pyyaml", 10 | "click", 11 | "requests" 12 | ] 13 | 14 | setup( 15 | name="phantomfuzzer", 16 | version="0.1.0", 17 | description="PhantomFuzzer: Advanced Security Testing Toolkit", 18 | author="Ghost Security", 19 | author_email="info@phantomfuzzer.com", 20 | packages=find_packages(), 21 | include_package_data=True, 22 | install_requires=core_requirements, 23 | entry_points={ 24 | "console_scripts": [ 25 | "phantomfuzzer=phantomfuzzer.cli:cli", 26 | ], 27 | }, 28 | classifiers=[ 29 | "Development Status :: 4 - Beta", 30 | "Intended Audience :: Information Technology", 31 | "License :: OSI Approved :: MIT License", 32 | "Programming Language :: Python :: 3", 33 | "Programming Language :: Python :: 3.11", 34 | "Topic :: Security", 35 | ], 36 | python_requires=">=3.11", 37 | ) 38 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # Core dependencies 2 | numpy>=1.24.0 3 | pandas>=2.0.0 4 | scipy>=1.11.0 5 | 6 | # Machine Learning 7 | scikit-learn>=1.3.0 8 | tensorflow>=2.12.0 9 | keras>=2.12.0 10 | torch>=2.0.0 11 | transformers>=4.30.0 12 | nltk>=3.8.0 13 | gensim>=4.3.0 14 | spacy>=3.6.0 15 | 16 | # Data processing and visualization 17 | matplotlib>=3.7.0 18 | seaborn>=0.12.0 19 | plotly>=5.15.0 20 | 21 | # Web and networking 22 | requests>=2.31.0 23 | beautifulsoup4>=4.12.0 24 | selenium>=4.11.0 25 | aiohttp>=3.8.0 26 | fastapi>=0.103.0 27 | uvicorn>=0.23.0 28 | httpx>=0.25.0 29 | 30 | # Security and fuzzing tools 31 | pycryptodome>=3.18.0 32 | python-nmap>=0.7.1 33 | scapy>=2.5.0 34 | pyOpenSSL>=23.2.0 35 | pyjwt>=2.8.0 36 | python-magic>=0.4.27 37 | yara-python>=4.2.0 38 | cryptography>=37.0.0 39 | paramiko>=3.3.0 40 | faker>=13.0.0 41 | pillow>=10.0.0 42 | 43 | # Database 44 | sqlalchemy>=2.0.0 45 | pymongo>=4.5.0 46 | 47 | # Utilities 48 | tqdm>=4.66.0 49 | click>=8.1.0 50 | python-dotenv>=1.0.0 51 | pyyaml>=6.0.0 52 | rich>=13.5.0 53 | loguru>=0.7.0 54 | 55 | # Testing 56 | pytest>=7.4.0 57 | pytest-cov>=4.1.0 58 | 59 | # Development 60 | black>=23.7.0 61 | isort>=5.12.0 62 | flake8>=6.1.0 63 | mypy>=1.5.0 64 | -------------------------------------------------------------------------------- /phantomfuzzer_cmd: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # PhantomFuzzer wrapper script 4 | # This script forwards commands to the phantomfuzzer Docker container 5 | 6 | # Suppress warnings 7 | export PYTHONWARNINGS="ignore::DeprecationWarning,ignore::PendingDeprecationWarning" 8 | export MPLCONFIGDIR="/tmp/matplotlib-config" 9 | 10 | # Create temp directory for matplotlib if it doesn't exist 11 | mkdir -p /tmp/matplotlib-config 12 | 13 | # Handle volume mounts for current directory when needed 14 | if [[ "$*" == *"--output"* ]] || [[ "$*" == *"--path"* ]] || [[ "$*" == *"--spec"* ]] || [[ "$*" == *"--target"* ]]; then 15 | # Run with volume mounts 16 | docker run --rm \ 17 | -v "$(pwd):/data/current" \ 18 | -v "$(pwd)/ascii.txt:/app/ascii.txt" \ 19 | -e PYTHONWARNINGS="ignore::DeprecationWarning,ignore::PendingDeprecationWarning" \ 20 | -e MPLCONFIGDIR="/tmp/matplotlib-config" \ 21 | phantomfuzzer "$@" 22 | else 23 | # Run without volume mounts 24 | docker run --rm \ 25 | -v "$(pwd)/ascii.txt:/app/ascii.txt" \ 26 | -e PYTHONWARNINGS="ignore::DeprecationWarning,ignore::PendingDeprecationWarning" \ 27 | -e MPLCONFIGDIR="/tmp/matplotlib-config" \ 28 | phantomfuzzer "$@" 29 | fi 30 | -------------------------------------------------------------------------------- /ascii.txt: -------------------------------------------------------------------------------- 1 | ⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⡿⢿⡿⠃⠀⡐⠀⠘⡻⠿⠋⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 2 | ⣿⣿⣿⣿⣿⣿⣿⡏⠈⣤⡝⠛⢻⣷⡆⠀⠀⠀⠀⠀⣤⣧⠀⠀⠀⠀⠚⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 3 | ⣿⣿⣿⣿⣿⣿⣿⡇⡀⠀⢴⣮⡀⠉⠁⠀⠀⠀⠀⠁⣹⠛⠋⠉⣰⢄⣠⣿⣿⣿⣿⣿⡿⡿⠿⢿⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 4 | ⣿⣿⣿⣿⣿⡿⠿⢇⣗⠀⢈⠙⣷⠀⡐⢀⠀⡀⠀⢀⣴⣦⡄⢂⢀⣺⣿⣿⣿⣿⠏⠁⣠⣤⣤⣤⣭⣕⡲⣌⡋⠻⠿⠿⠿⠛⠛⣛ 5 | ⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠾⢯⡙⢇⠀⢃⢀⣀⠢⡿⠋⢐⠶⠇⣿⣿⣿⣿⠟⠁⣺⣿⣿⣿⣿⣿⣿⣿⣷⣵⡛⣃⣀⣠⣀⣠⣾⣿ 6 | ⣿⣿⣿⣿⣿⣷⠀⠀⢸⣦⠀⠀⠉⠂⠁⢆⣌⠆⡆⢷⡍⠹⠷⠸⠿⠿⠏⠁⣤⡌⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿ 7 | ⣿⣿⣿⣿⣿⣿⣆⠀⠀⠻⣷⣦⡀⠀⢠⠂⢾⠀⠀⠀⠀⢀⠂⠀⣤⣶⣾⣿⣿⣿⣶⣤⣤⣤⣨⡙⢿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿ 8 | ⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠚⠋⢠⣾⣿⡼⣹⣮⣤⣰⡶⠏⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣼⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿ 9 | ⣿⣿⡿⢡⣏⡇⠀⠀⠀⢀⢰⣰⢿⡛⠣⠆⢿⣿⣿⠇⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 10 | ⣿⣿⡇⣸⡇⠿⠀⠀⠀⡀⠸⡀⠘⠃⠀⠀⢾⢿⠇⠀⠀⠀⢀⢰⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 11 | ⣿⣿⢃⣿⡻⡀⣣⠀⠀⠀⠂⠁⠈⠈⠀⠘⠀⠄⣽⠐⠃⠀⠈⡈⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 12 | ⣿⣿⠸⣿⣷⢄⠀⠱⡄⠀⠀⠀⢿⣷⣷⠀⠔⠈⠁⠀⠀⠀⣘⠁⠘⠻⠿⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 13 | ⠋⠴⣬⣨⠣⣾⣷⣥⡽⠆⠀⠀⠁⠉⠀⠀⠀⠀⢀⠀⠀⣼⠁⠀⢀⣄⡦⠭⠤⠶⠤⣬⣍⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 14 | ⣧⣤⣿⡟⢄⡙⠛⠉⠁⢃⠐⠀⠀⠀⠀⠀⠜⠀⠈⣀⡿⠋⠀⣸⡿⠛⠁⠀⠀⠘⠀⢉⠉⠹⢿⢟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 15 | ⡿⣿⣿⣿⣎⠀⠀⠀⠀⠘⠀⠁⠀⠀⠀⠀⠀⠀⠀⠟⠑⠀⠀⠈⠀⠀⠀⠀⠠⢤⠤⣨⣷⡀⠀⣚⡋⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 16 | 17 | ██████╗░██╗░░██╗░█████╗░███╗░░██╗████████╗░█████╗░███╗░░░███╗ 18 | ██╔══██╗██║░░██║██╔══██╗████╗░██║╚══██╔══╝██╔══██╗████╗░████║ 19 | ██████╔╝███████║███████║██╔██╗██║░░░██║░░░██║░░██║██╔████╔██║ 20 | ██╔═══╝░██╔══██║██╔══██║██║╚████║░░░██║░░░██║░░██║██║╚██╔╝██║ 21 | ██║░░░░░██║░░██║██║░░██║██║░╚███║░░░██║░░░╚█████╔╝██║░╚═╝░██║ 22 | ╚═╝░░░░░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝░░░╚═╝░░░░╚════╝░╚═╝░░░░░╚═╝ 23 | ███████╗██╗░░░██╗███████╗███████╗███████╗██████╗░ 24 | ██╔════╝██║░░░██║╚════██║╚════██║██╔════╝██╔══██╗ 25 | █████╗░░██║░░░██║░░███╔═╝░░███╔═╝█████╗░░██████╔╝ 26 | ██╔══╝░░██║░░░██║██╔══╝░░██╔══╝░░██╔══╝░░██╔══██╗ 27 | ██║░░░░░╚██████╔╝███████╗███████╗███████╗██║░░██║ 28 | ╚═╝░░░░░░╚═════╝░╚══════╝╚══════╝╚══════╝╚═╝░░╚═╝ 29 | [*]Enhanced ML Web Scanner, Fuzzer, and Payload Generator 30 | by Ghost Security 31 | -------------------------------------------------------------------------------- /data/wordlists/common/extensions.txt: -------------------------------------------------------------------------------- 1 | # Common file extensions to check 2 | # Format: extension:weight (1-10, higher = more likely) 3 | 4 | # Configuration files 5 | .conf:9 6 | .config:9 7 | .cfg:8 8 | .ini:8 9 | .env:10 10 | .json:8 11 | .yaml:8 12 | .yml:8 13 | .xml:7 14 | .properties:7 15 | 16 | # Web files 17 | .php:9 18 | .asp:8 19 | .aspx:8 20 | .jsp:8 21 | .html:7 22 | .htm:7 23 | .shtml:7 24 | .phtml:7 25 | .cgi:8 26 | .pl:7 27 | .py:8 28 | .rb:7 29 | 30 | # Backup files 31 | .bak:9 32 | .backup:9 33 | .old:8 34 | .orig:8 35 | .copy:7 36 | .tmp:8 37 | .temp:8 38 | .swp:7 39 | .save:7 40 | ~:6 41 | 42 | # Log files 43 | .log:9 44 | .logs:9 45 | .error:8 46 | .debug:8 47 | .trace:7 48 | .access:8 49 | 50 | # Database files 51 | .sql:9 52 | .db:9 53 | .sqlite:8 54 | .sqlite3:8 55 | .mdb:7 56 | .accdb:7 57 | .mysql:7 58 | .pgsql:7 59 | 60 | # Archive files 61 | .zip:8 62 | .tar:8 63 | .gz:8 64 | .tgz:8 65 | .rar:7 66 | .7z:7 67 | .bz2:7 68 | 69 | # Documentation 70 | .txt:7 71 | .md:7 72 | .pdf:6 73 | .doc:6 74 | .docx:6 75 | .rtf:5 76 | .csv:7 77 | .xls:6 78 | .xlsx:6 79 | 80 | # Development 81 | .git:10 82 | .svn:8 83 | .htaccess:9 84 | .htpasswd:9 85 | .sh:8 86 | .bash:7 87 | .npmrc:8 88 | .yarnrc:7 89 | .env.local:9 90 | .env.development:8 91 | .env.production:9 92 | 93 | # Security 94 | .key:10 95 | .pem:10 96 | .crt:9 97 | .cer:9 98 | .csr:8 99 | .p12:8 100 | .pfx:8 101 | .jks:8 102 | 103 | # Application specific 104 | .dll:7 105 | .so:7 106 | .exe:7 107 | .bin:7 108 | .pid:7 109 | .socket:7 110 | .lock:7 111 | -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3.8' 2 | 3 | services: 4 | phantomfuzzer: 5 | build: 6 | context: . 7 | dockerfile: Dockerfile 8 | image: phantomfuzzer:latest 9 | container_name: phantomfuzzer 10 | restart: unless-stopped 11 | # Resource constraints to avoid overloading the host machine 12 | deploy: 13 | resources: 14 | limits: 15 | cpus: '2.0' # Limit to 2 CPU cores 16 | memory: 4G # Limit to 4GB of RAM 17 | reservations: 18 | cpus: '0.5' # Reserve at least 0.5 CPU cores 19 | memory: 1G # Reserve at least 1GB of RAM 20 | volumes: 21 | # Mount data directories for persistence 22 | - ./data/wordlists:/data/wordlists 23 | - ./data/payloads:/data/payloads 24 | - ./data/training:/data/training 25 | - ./data/vulnerabilities:/data/vulnerabilities 26 | - ./data/patterns:/data/patterns 27 | # Mount configuration files 28 | - ./config:/app/config 29 | # Mount logs directory 30 | - ./logs:/app/logs 31 | ports: 32 | - "8080:8080" # Web interface/API 33 | environment: 34 | - PYTHONPATH=/app 35 | - LOG_LEVEL=INFO 36 | - MAX_THREADS=10 37 | - SCAN_TIMEOUT=300 38 | - ML_MODEL_PATH=/data/training/models 39 | # Health check to monitor container status 40 | healthcheck: 41 | test: ["CMD", "curl", "-f", "http://localhost:8080/health"] 42 | interval: 30s 43 | timeout: 10s 44 | retries: 3 45 | start_period: 40s 46 | # Command can be overridden when running the container 47 | command: ["--config", "/app/config/default.yml"] 48 | -------------------------------------------------------------------------------- /data/wordlists/common/directories.txt: -------------------------------------------------------------------------------- 1 | # Common directory names to check 2 | # Format: directory_name:weight (1-10, higher = more likely) 3 | 4 | # Admin and management 5 | admin:9 6 | administrator:8 7 | manager:7 8 | management:7 9 | dashboard:7 10 | console:6 11 | control:6 12 | panel:6 13 | 14 | # Common web directories 15 | api:9 16 | docs:8 17 | static:8 18 | media:7 19 | uploads:7 20 | images:7 21 | css:6 22 | js:6 23 | assets:6 24 | public:6 25 | private:8 26 | backup:9 27 | temp:7 28 | cache:7 29 | 30 | # Development 31 | dev:8 32 | development:7 33 | staging:7 34 | test:7 35 | testing:6 36 | beta:6 37 | debug:7 38 | 39 | # Security related 40 | .git:10 41 | .svn:8 42 | .env:10 43 | .config:9 44 | .settings:8 45 | .vscode:7 46 | .idea:7 47 | 48 | # Logs and data 49 | logs:8 50 | log:8 51 | data:7 52 | db:8 53 | database:8 54 | sql:7 55 | mysql:7 56 | postgres:7 57 | mongodb:7 58 | 59 | # Configuration 60 | conf:9 61 | config:9 62 | settings:8 63 | setup:7 64 | install:7 65 | 66 | # Common CMS directories 67 | wp-admin:8 68 | wp-content:7 69 | wp-includes:7 70 | administrator:8 71 | joomla:7 72 | drupal:7 73 | magento:7 74 | wordpress:7 75 | 76 | # Application specific 77 | app:8 78 | application:7 79 | src:7 80 | source:7 81 | includes:6 82 | modules:6 83 | components:6 84 | plugins:6 85 | extensions:6 86 | themes:6 87 | templates:6 88 | 89 | # User related 90 | user:7 91 | users:7 92 | accounts:7 93 | profile:6 94 | members:6 95 | login:8 96 | register:7 97 | signup:7 98 | auth:8 99 | 100 | # System 101 | cgi-bin:8 102 | bin:7 103 | etc:8 104 | proc:8 105 | sys:8 106 | system:7 107 | tmp:8 108 | var:7 109 | -------------------------------------------------------------------------------- /data/wordlists/sensitive/private.txt: -------------------------------------------------------------------------------- 1 | # Private wordlist for additional patterns 2 | # Add your custom patterns here, one per line 3 | 4 | # Nginx specific 5 | nginx-manager 6 | nginx-status 7 | nginx-admin 8 | nginx.sock 9 | nginx.pid.oldbin 10 | nginx.conf.compiled 11 | nginx.conf.default.orig 12 | nginx_signing.key 13 | nginx.htpasswd 14 | nginx.htaccess 15 | nginx.users 16 | nginx.acl 17 | nginx.rules 18 | nginx.whitelist 19 | nginx.blacklist 20 | 21 | # Development and staging 22 | dev.conf 23 | staging.conf 24 | test.conf 25 | uat.conf 26 | prod.conf 27 | local.conf 28 | debug.conf 29 | maintenance.conf 30 | 31 | # SSL/TLS 32 | ssl.conf 33 | ssl.key 34 | ssl.crt 35 | ssl.pem 36 | ssl.csr 37 | ssl.ca 38 | ssl.bundle 39 | ssl.combined 40 | ssl.chain 41 | ssl.dhparam 42 | 43 | # Security 44 | security.conf 45 | firewall.conf 46 | rate-limit.conf 47 | blacklist.conf 48 | whitelist.conf 49 | acl.conf 50 | auth.conf 51 | basic-auth.conf 52 | ldap.conf 53 | oauth.conf 54 | 55 | # Optimization 56 | cache.conf 57 | compression.conf 58 | gzip.conf 59 | headers.conf 60 | expires.conf 61 | proxy-cache.conf 62 | fastcgi-cache.conf 63 | microcache.conf 64 | pagespeed.conf 65 | 66 | # Custom locations 67 | custom-locations.conf 68 | rewrites.conf 69 | redirects.conf 70 | maps.conf 71 | geo.conf 72 | upstream.conf 73 | 74 | # Monitoring 75 | status.conf 76 | metrics.conf 77 | prometheus.conf 78 | grafana.conf 79 | kibana.conf 80 | elastic.conf 81 | logging.conf 82 | 83 | # Application specific 84 | php-fpm.conf 85 | php.conf 86 | python.conf 87 | ruby.conf 88 | node.conf 89 | java.conf 90 | tomcat.conf 91 | wordpress.conf 92 | drupal.conf 93 | laravel.conf 94 | django.conf 95 | 96 | # Temporary and backup 97 | .nginx.swp 98 | .nginx.swo 99 | .nginx.swn 100 | .nginx.swm 101 | .nginx.swl 102 | .nginx.bk 103 | .nginx.old 104 | .nginx.orig 105 | .nginx.save 106 | .nginx.backup 107 | .nginx.copy 108 | .nginx.tmp 109 | -------------------------------------------------------------------------------- /data/wordlists/locations.txt: -------------------------------------------------------------------------------- 1 | # Common NGINX locations to check 2 | # Format: location:weight (1-10, higher = more likely) 3 | 4 | # Status and metrics 5 | /nginx_status:9 6 | /status:8 7 | /metrics:8 8 | /stub_status:9 9 | /server-status:8 10 | /server-info:7 11 | /stats:7 12 | /health:7 13 | /ping:6 14 | 15 | # Proxy and upstream 16 | /proxy:8 17 | /backend:8 18 | /upstream:8 19 | /balancer:7 20 | /lb_status:7 21 | /proxy_status:8 22 | 23 | # Admin and control 24 | /nginx-admin:9 25 | /nginx-manager:8 26 | /nginx-control:8 27 | /nginx-console:7 28 | /nginx-panel:7 29 | /nginx-dashboard:7 30 | 31 | # Configuration 32 | /nginx.conf:10 33 | /conf:9 34 | /config:9 35 | /nginx.config:9 36 | /nginx.cfg:8 37 | /settings:8 38 | /nginx-settings:8 39 | 40 | # SSL/TLS 41 | /ssl:8 42 | /certificates:8 43 | /certs:8 44 | /.well-known:7 45 | /acme-challenge:7 46 | 47 | # Logs 48 | /logs:9 49 | /log:9 50 | /access.log:9 51 | /error.log:9 52 | /debug.log:8 53 | /nginx-logs:8 54 | /nginx-access:8 55 | /nginx-error:8 56 | 57 | # Cache 58 | /cache:8 59 | /fastcgi_cache:8 60 | /proxy_cache:8 61 | /temp:7 62 | /tmp:7 63 | 64 | # Development 65 | /dev:7 66 | /development:7 67 | /staging:7 68 | /test:7 69 | /testing:6 70 | /debug:7 71 | 72 | # Security 73 | /.git:10 74 | /.svn:8 75 | /.env:10 76 | /.config:9 77 | /security:8 78 | /auth:8 79 | /login:8 80 | 81 | # API and docs 82 | /api:9 83 | /docs:8 84 | /swagger:7 85 | /openapi:7 86 | /redoc:7 87 | /documentation:7 88 | 89 | # Common web paths 90 | /static:7 91 | /media:7 92 | /uploads:8 93 | /files:8 94 | /download:7 95 | /public:7 96 | /private:8 97 | 98 | # Application specific 99 | /app:7 100 | /web:7 101 | /www:7 102 | /html:7 103 | /public_html:7 104 | /webroot:7 105 | 106 | # PHP specific 107 | /php:8 108 | /php-status:8 109 | /php-fpm:8 110 | /php-info:8 111 | /phpinfo:8 112 | /php.ini:9 113 | 114 | # Server info 115 | /server:7 116 | /info:7 117 | /phpinfo.php:9 118 | /test.php:8 119 | /info.php:8 120 | -------------------------------------------------------------------------------- /phantomfuzzer.egg-info/SOURCES.txt: -------------------------------------------------------------------------------- 1 | README.md 2 | setup.py 3 | phantomfuzzer/__init__.py 4 | phantomfuzzer/cli.py 5 | phantomfuzzer/config.py 6 | phantomfuzzer.egg-info/PKG-INFO 7 | phantomfuzzer.egg-info/SOURCES.txt 8 | phantomfuzzer.egg-info/dependency_links.txt 9 | phantomfuzzer.egg-info/entry_points.txt 10 | phantomfuzzer.egg-info/requires.txt 11 | phantomfuzzer.egg-info/top_level.txt 12 | phantomfuzzer/fuzzer/__init__.py 13 | phantomfuzzer/fuzzer/api_fuzzer.py 14 | phantomfuzzer/fuzzer/fuzzer_base.py 15 | phantomfuzzer/fuzzer/input_fuzzer.py 16 | phantomfuzzer/fuzzer/mutation_engine.py 17 | phantomfuzzer/fuzzer/protocol_fuzzer.py 18 | phantomfuzzer/ml/__init__.py 19 | phantomfuzzer/ml/feedback.py 20 | phantomfuzzer/ml/inference.py 21 | phantomfuzzer/ml/integration.py 22 | phantomfuzzer/ml/payload_enhancement.py 23 | phantomfuzzer/ml/models/__init__.py 24 | phantomfuzzer/ml/models/pattern_recognizer.py 25 | phantomfuzzer/ml/storage/__init__.py 26 | phantomfuzzer/ml/storage/pattern_db.py 27 | phantomfuzzer/ml/training/__init__.py 28 | phantomfuzzer/ml/training/data_loader.py 29 | phantomfuzzer/ml/training/trainer.py 30 | phantomfuzzer/payload/__init__.py 31 | phantomfuzzer/payload/generator.py 32 | phantomfuzzer/scanner/__init__.py 33 | phantomfuzzer/scanner/api_scanner.py 34 | phantomfuzzer/scanner/base.py 35 | phantomfuzzer/scanner/file_scanner.py 36 | phantomfuzzer/scanner/ml_enhanced_scanner.py 37 | phantomfuzzer/scanner/ml_enhanced_web_scanner.py 38 | phantomfuzzer/scanner/network.py 39 | phantomfuzzer/scanner/web.py 40 | phantomfuzzer/utils/__init__.py 41 | phantomfuzzer/utils/helper.py 42 | phantomfuzzer/utils/helpers.py 43 | phantomfuzzer/utils/logging.py 44 | phantomfuzzer/vulnerability/__init__.py 45 | phantomfuzzer/vulnerability/analyzer.py 46 | phantomfuzzer/vulnerability/api_analyzer.py 47 | phantomfuzzer/vulnerability/base_analyzer.py 48 | phantomfuzzer/vulnerability/classifier.py 49 | phantomfuzzer/vulnerability/file_analyzer.py 50 | phantomfuzzer/vulnerability/models.py 51 | phantomfuzzer/vulnerability/network_analyzer.py 52 | phantomfuzzer/vulnerability/reporter.py 53 | phantomfuzzer/vulnerability/severity.py 54 | phantomfuzzer/vulnerability/web_analyzer.py 55 | tests/__init__.py 56 | tests/scanner/__init__.py 57 | tests/scanner/test_file_scanner.py -------------------------------------------------------------------------------- /phantomfuzzer/scanner/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | Scanner module for PhantomFuzzer. 3 | 4 | This module provides various scanner implementations for different targets: 5 | base.py - Base scanner implementation and common utilities 6 | file_scanner.py - File scanner for detecting malware and vulnerabilities in files 7 | network.py - Network scanner for port scanning and service detection 8 | web.py - Web scanner for web application security testing 9 | api_scanner.py - API scanner for API security testing 10 | 11 | Classes: 12 | BaseScanner - Base class for all scanners 13 | ScanResult - Class representing scan results 14 | FileScanner - Scanner for files and directories 15 | NetworkScanner - Scanner for network targets 16 | WebScanner - Scanner for web applications 17 | APIScanner - Scanner for API endpoints 18 | 19 | Constants: 20 | STATUS_* - Scanner status constants 21 | SEVERITY_* - Vulnerability severity levels 22 | """ 23 | 24 | # Import scanner classes for direct import 25 | from phantomfuzzer.scanner.base import ( 26 | BaseScanner, 27 | ScanResult, 28 | # Scanner status constants 29 | STATUS_IDLE, 30 | STATUS_RUNNING, 31 | STATUS_COMPLETED, 32 | STATUS_FAILED, 33 | STATUS_STOPPED, 34 | # Vulnerability severity levels 35 | SEVERITY_CRITICAL, 36 | SEVERITY_HIGH, 37 | SEVERITY_MEDIUM, 38 | SEVERITY_LOW, 39 | SEVERITY_INFO 40 | ) 41 | from phantomfuzzer.scanner.file_scanner import FileScanner 42 | from phantomfuzzer.scanner.network import NetworkScanner 43 | from phantomfuzzer.scanner.web import WebScanner 44 | from phantomfuzzer.scanner.api_scanner import APIScanner 45 | from phantomfuzzer.scanner.ml_enhanced_scanner import MLEnhancedScanner 46 | 47 | # Define exported symbols 48 | __all__ = [ 49 | # Scanner classes 50 | 'BaseScanner', 51 | 'ScanResult', 52 | 'FileScanner', 53 | 'NetworkScanner', 54 | 'WebScanner', 55 | 'APIScanner', 56 | 'MLEnhancedScanner', 57 | # Scanner status constants 58 | 'STATUS_IDLE', 59 | 'STATUS_RUNNING', 60 | 'STATUS_COMPLETED', 61 | 'STATUS_FAILED', 62 | 'STATUS_STOPPED', 63 | # Vulnerability severity levels 64 | 'SEVERITY_CRITICAL', 65 | 'SEVERITY_HIGH', 66 | 'SEVERITY_MEDIUM', 67 | 'SEVERITY_LOW', 68 | 'SEVERITY_INFO' 69 | ] 70 | -------------------------------------------------------------------------------- /scapy_patch.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | """ 3 | Patch script for Scapy to suppress cryptography warnings. 4 | This script should be run during the Docker build process. 5 | """ 6 | import os 7 | import sys 8 | import re 9 | import warnings 10 | 11 | # Find the scapy installation directory 12 | try: 13 | import scapy 14 | scapy_dir = os.path.dirname(scapy.__file__) 15 | ipsec_file = os.path.join(scapy_dir, 'layers', 'ipsec.py') 16 | 17 | if not os.path.exists(ipsec_file): 18 | print(f"Error: Could not find {ipsec_file}") 19 | sys.exit(1) 20 | 21 | # Read the file content 22 | with open(ipsec_file, 'r') as f: 23 | content = f.read() 24 | 25 | # Check if already patched 26 | if "warnings.filterwarnings('ignore', category=CryptographyDeprecationWarning)" in content: 27 | print(f"File {ipsec_file} already patched") 28 | sys.exit(0) 29 | 30 | # Find the position after all __future__ imports 31 | future_imports = re.findall(r'from __future__ import .*?\n', content) 32 | if future_imports: 33 | # Get the position after the last __future__ import 34 | last_future_import = future_imports[-1] 35 | position = content.find(last_future_import) + len(last_future_import) 36 | 37 | # Insert our warning suppression code after all __future__ imports 38 | new_content = content[:position] + \ 39 | "\n# Added by PhantomFuzzer to suppress cryptography warnings\nimport warnings\nfrom cryptography.utils import CryptographyDeprecationWarning\nwarnings.filterwarnings('ignore', category=CryptographyDeprecationWarning)\n\n" + \ 40 | content[position:] 41 | else: 42 | # No __future__ imports, add at the beginning 43 | new_content = """# Added by PhantomFuzzer to suppress cryptography warnings 44 | import warnings 45 | from cryptography.utils import CryptographyDeprecationWarning 46 | warnings.filterwarnings('ignore', category=CryptographyDeprecationWarning) 47 | 48 | """ + content 49 | 50 | # Write the modified content back 51 | with open(ipsec_file, 'w') as f: 52 | f.write(new_content) 53 | 54 | print(f"Successfully patched {ipsec_file} to suppress cryptography warnings") 55 | 56 | except ImportError: 57 | print("Error: Scapy module not found") 58 | sys.exit(1) 59 | except Exception as e: 60 | print(f"Error: {str(e)}") 61 | sys.exit(1) 62 | -------------------------------------------------------------------------------- /phantomfuzzer/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | PhantomFuzzer - Advanced Security Testing Framework 6 | 7 | PhantomFuzzer is a comprehensive security testing framework designed for 8 | identifying vulnerabilities in web applications, APIs, networks, and files. 9 | It provides various scanning and fuzzing capabilities with customizable 10 | output control options. 11 | 12 | Modules: 13 | scanner - Various scanner implementations for different targets 14 | fuzzer - Fuzzing engines for different protocols and inputs 15 | utils - Utility functions for logging, output formatting, and more 16 | payloads - Collection of payloads for various attack vectors 17 | config - Configuration management 18 | cli - Command-line interface 19 | """ 20 | 21 | __version__ = '1.0.0' 22 | __author__ = 'PhantomFuzzer Team' 23 | __email__ = 'info@phantomfuzzer.io' 24 | __license__ = 'MIT' 25 | 26 | # Import key modules for easy access 27 | from phantomfuzzer.scanner import ( 28 | BaseScanner, ScanResult, 29 | FileScanner, NetworkScanner, WebScanner, APIScanner, MLEnhancedScanner, 30 | # Scanner status constants 31 | STATUS_IDLE, STATUS_RUNNING, STATUS_COMPLETED, STATUS_FAILED, STATUS_STOPPED, 32 | # Vulnerability severity levels 33 | SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO 34 | ) 35 | 36 | from phantomfuzzer.utils import ( 37 | # Logging functions 38 | get_logger, get_module_logger, setup_logger, 39 | 40 | # Output control 41 | VerbosityLevel, Colors, set_verbosity, get_verbosity, set_use_colors, 42 | 43 | # Output formatting 44 | print_error, print_warning, print_success, print_info, 45 | print_section, print_summary 46 | ) 47 | 48 | # Define exported symbols 49 | __all__ = [ 50 | # Scanner classes 51 | 'BaseScanner', 'ScanResult', 52 | 'FileScanner', 'NetworkScanner', 'WebScanner', 'APIScanner', 'MLEnhancedScanner', 53 | 54 | # Scanner status constants 55 | 'STATUS_IDLE', 'STATUS_RUNNING', 'STATUS_COMPLETED', 'STATUS_FAILED', 'STATUS_STOPPED', 56 | 57 | # Vulnerability severity levels 58 | 'SEVERITY_CRITICAL', 'SEVERITY_HIGH', 'SEVERITY_MEDIUM', 'SEVERITY_LOW', 'SEVERITY_INFO', 59 | 60 | # Logging functions 61 | 'get_logger', 'get_module_logger', 'setup_logger', 62 | 63 | # Output control 64 | 'VerbosityLevel', 'Colors', 'set_verbosity', 'get_verbosity', 'set_use_colors', 65 | 66 | # Output formatting 67 | 'print_error', 'print_warning', 'print_success', 'print_info', 68 | 'print_section', 'print_summary' 69 | ] -------------------------------------------------------------------------------- /phantomfuzzer_wrapper.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # PhantomFuzzer wrapper script 4 | # This script forwards commands to the PhantomFuzzer Docker container (command: phantomfuzzer) 5 | 6 | # Set environment variables to suppress warnings 7 | export PYTHONWARNINGS="ignore::DeprecationWarning" 8 | 9 | # Check if this is a 'man' command 10 | if [[ "$1" == "man" ]]; then 11 | # For man command, try to use the system man if available 12 | if command -v man &> /dev/null && [ -f "/usr/local/share/man/man1/phantomfuzzer.1" ]; then 13 | man phantomfuzzer 14 | else 15 | # Fall back to Docker container with improved warning filtering 16 | # Redirect stderr to a temporary file to filter warnings 17 | temp_err=$(mktemp) 18 | docker run --rm \ 19 | -e PYTHONWARNINGS=ignore \ 20 | -e MPLCONFIGDIR=/tmp \ 21 | -e CRYPTOGRAPHY_SUPPRESS_DEPRECATION_WARNINGS=1 \ 22 | phantomfuzzer "$@" 2> "$temp_err" 23 | 24 | # Filter out warnings and only show actual errors if any 25 | if [ -s "$temp_err" ]; then 26 | grep -v -E "WARNING|Matplotlib|cryptography|Blowfish|TripleDES|CAST5|decrepit|CryptographyDeprecationWarning" "$temp_err" >&2 27 | fi 28 | 29 | # Clean up 30 | rm -f "$temp_err" 31 | fi 32 | # Handle volume mounts for current directory when needed 33 | elif [[ "$*" == *"--output"* ]] || [[ "$*" == *"--path"* ]] || [[ "$*" == *"--spec"* ]] || [[ "$*" == *"--target"* ]]; then 34 | # Run with volume mount and improved warning filtering 35 | # Redirect stderr to a temporary file to filter warnings 36 | temp_err=$(mktemp) 37 | docker run --rm \ 38 | -e PYTHONWARNINGS=ignore \ 39 | -e MPLCONFIGDIR=/tmp \ 40 | -e CRYPTOGRAPHY_SUPPRESS_DEPRECATION_WARNINGS=1 \ 41 | -v "$(pwd):/data/current" \ 42 | phantomfuzzer "$@" 2> "$temp_err" 43 | 44 | # Filter out warnings and only show actual errors if any 45 | if [ -s "$temp_err" ]; then 46 | grep -v -E "WARNING|Matplotlib|cryptography|Blowfish|TripleDES|CAST5|decrepit|CryptographyDeprecationWarning" "$temp_err" >&2 47 | fi 48 | 49 | # Clean up 50 | rm -f "$temp_err" 51 | else 52 | # Run without volume mount and improved warning filtering 53 | # Redirect stderr to a temporary file to filter warnings 54 | temp_err=$(mktemp) 55 | docker run --rm \ 56 | -e PYTHONWARNINGS=ignore \ 57 | -e MPLCONFIGDIR=/tmp \ 58 | -e CRYPTOGRAPHY_SUPPRESS_DEPRECATION_WARNINGS=1 \ 59 | phantomfuzzer "$@" 2> "$temp_err" 60 | 61 | # Filter out warnings and only show actual errors if any 62 | if [ -s "$temp_err" ]; then 63 | grep -v -E "WARNING|Matplotlib|cryptography|Blowfish|TripleDES|CAST5|decrepit|CryptographyDeprecationWarning" "$temp_err" >&2 64 | fi 65 | 66 | # Clean up 67 | rm -f "$temp_err" 68 | fi 69 | -------------------------------------------------------------------------------- /phantomfuzzer.1: -------------------------------------------------------------------------------- 1 | .TH PHANTOMFUZZER 1 "March 2025" "PhantomFuzzer 0.1.0" "User Commands" 2 | .SH NAME 3 | phantomfuzzer \- Advanced Security Testing Toolkit 4 | .SH SYNOPSIS 5 | .B phantomfuzzer 6 | [\fIOPTIONS\fR] 7 | \fICOMMAND \fR[\fIARGS\fR]... 8 | .SH DESCRIPTION 9 | .PP 10 | PhantomFuzzer is a comprehensive toolkit for security testing, fuzzing, and vulnerability discovery. It provides multiple modules for security professionals: 11 | .PP 12 | .IP \(bu 4 13 | \fBFUZZER\fR: Test applications for vulnerabilities by sending unexpected inputs 14 | .IP \(bu 4 15 | \fBSCANNER\fR: Identify security issues in web applications, APIs, and files 16 | .IP \(bu 4 17 | \fBPAYLOAD\fR: Generate attack payloads for various security testing scenarios 18 | .SH OPTIONS 19 | .TP 20 | .B \-\-version 21 | Show the version and exit. 22 | .TP 23 | .B \-\-debug 24 | Enable debug logging. 25 | .TP 26 | .B \-\-help 27 | Show help message and exit. 28 | .SH COMMANDS 29 | .SS "payload" 30 | Generate attack payloads for security testing. 31 | .PP 32 | This command provides access to the PayloadGenerator functionality, allowing you to generate various types of attack payloads for security testing. All generated payloads will be output to ensure comprehensive results. 33 | .PP 34 | Subcommands: 35 | .TP 36 | .B list 37 | List available payload categories and subcategories. 38 | .TP 39 | .B generate 40 | Generate payloads of a specific type. 41 | .SS "fuzzer" 42 | Run various types of fuzzers against targets. 43 | .PP 44 | This command provides access to different fuzzer types in PhantomFuzzer, including API fuzzing, protocol fuzzing, and input fuzzing. All findings will be outputted to ensure comprehensive results. 45 | .PP 46 | Subcommands: 47 | .TP 48 | .B api 49 | Fuzz API endpoints for vulnerabilities. 50 | .TP 51 | .B protocol 52 | Fuzz network protocols for vulnerabilities. 53 | .TP 54 | .B input 55 | Fuzz application inputs for vulnerabilities. 56 | .SS "scanner" 57 | Run various types of scanners against targets. 58 | .PP 59 | This command provides access to different scanner types in PhantomFuzzer, including web scanning, API scanning, and file scanning. All findings will be outputted to ensure comprehensive results. 60 | .PP 61 | Subcommands: 62 | .TP 63 | .B web 64 | Scan web applications for vulnerabilities. 65 | .TP 66 | .B api 67 | Scan API endpoints for vulnerabilities. 68 | .TP 69 | .B file 70 | Scan files for malicious content. 71 | .SH EXAMPLES 72 | .TP 73 | List available payload categories: 74 | .B phantomfuzzer payload list 75 | .TP 76 | Generate SQL injection payloads: 77 | .B phantomfuzzer payload generate --category sql_injection --output payloads.txt 78 | .TP 79 | Scan a web application: 80 | .B phantomfuzzer scanner web --url https://example.com --depth 3 81 | .TP 82 | Fuzz an API endpoint: 83 | .B phantomfuzzer fuzzer api --target https://api.example.com/v1/users --method POST --data '{"user":"test"}' 84 | .SH FILES 85 | .TP 86 | .I /usr/local/bin/phantomfuzzer 87 | The wrapper script that forwards commands to the Docker container. 88 | .SH BUGS 89 | Report bugs to the GitHub repository: https://github.com/ghostsecurity/PhantomFuzzer 90 | .SH AUTHORS 91 | Ghost Security 92 | -------------------------------------------------------------------------------- /data/wordlists/sensitive/credentials.txt: -------------------------------------------------------------------------------- 1 | # Common credential patterns to check 2 | # Format: pattern:weight:description (1-10, higher = more critical) 3 | 4 | # Username patterns 5 | admin:9:Administrator account 6 | administrator:9:Full administrator account 7 | root:10:Root account 8 | superuser:8:Superuser account 9 | webmaster:7:Web administrator 10 | sysadmin:8:System administrator 11 | user:6:Basic user account 12 | guest:5:Guest account 13 | test:7:Test account 14 | demo:6:Demo account 15 | 16 | # Default credentials (username:password) 17 | admin:admin:10:Default admin credentials 18 | admin:password:10:Common admin password 19 | root:root:10:Default root credentials 20 | admin:123456:9:Simple admin password 21 | administrator:administrator:9:Default administrator 22 | test:test:8:Test account credentials 23 | demo:demo:7:Demo account credentials 24 | 25 | # Password patterns 26 | pass:8:Basic password 27 | passwd:8:Unix password 28 | password:9:Full password 29 | pwd:7:Short password 30 | secret:8:Secret value 31 | credentials:9:Credential storage 32 | 33 | # Authentication files 34 | .htpasswd:10:Apache password file 35 | passwd:9:Password file 36 | shadow:10:Shadow password file 37 | credentials.txt:9:Plain text credentials 38 | users.txt:8:User list file 39 | passwords.txt:9:Password list file 40 | 41 | # Database credentials 42 | dbuser:8:Database username 43 | dbpass:9:Database password 44 | db_user:8:Alternative database user 45 | db_password:9:Alternative database password 46 | mysql_user:8:MySQL username 47 | mysql_pass:9:MySQL password 48 | postgres_user:8:PostgreSQL username 49 | postgres_pass:9:PostgreSQL password 50 | 51 | # API credentials 52 | api_key:9:API key 53 | api_secret:9:API secret 54 | client_id:8:OAuth client ID 55 | client_secret:9:OAuth client secret 56 | access_token:9:Access token 57 | refresh_token:8:Refresh token 58 | 59 | # Service accounts 60 | service_account:8:Service account 61 | bot_user:7:Bot account 62 | system_user:8:System service account 63 | app_user:7:Application user 64 | worker_user:7:Worker account 65 | 66 | # Encrypted/hashed patterns 67 | $1$:9:MD5 hash 68 | $2a$:9:Bcrypt hash 69 | $2y$:9:Bcrypt hash 70 | $5$:9:SHA-256 hash 71 | $6$:9:SHA-512 hash 72 | {SSHA}:8:Salted SHA hash 73 | {MD5}:8:MD5 hash marker 74 | 75 | # Session identifiers 76 | PHPSESSID:8:PHP session ID 77 | JSESSIONID:8:Java session ID 78 | ASP.NET_SessionId:8:ASP.NET session 79 | session_id:8:Generic session ID 80 | auth_token:9:Authentication token 81 | bearer_token:9:Bearer token 82 | 83 | # Cookie credentials 84 | remember_token:8:Remember me token 85 | auth_cookie:8:Authentication cookie 86 | login_token:8:Login token 87 | user_token:8:User token 88 | admin_cookie:9:Admin cookie 89 | 90 | # Configuration credentials 91 | smtp_user:8:SMTP username 92 | smtp_pass:9:SMTP password 93 | ftp_user:8:FTP username 94 | ftp_pass:9:FTP password 95 | ssh_user:8:SSH username 96 | ssh_key:9:SSH key file 97 | 98 | # Cloud credentials 99 | aws_access_key:10:AWS access key 100 | aws_secret_key:10:AWS secret key 101 | azure_key:10:Azure key 102 | gcp_key:10:Google Cloud key 103 | do_token:9:DigitalOcean token 104 | cf_token:9:Cloudflare token 105 | -------------------------------------------------------------------------------- /config/default.yml: -------------------------------------------------------------------------------- 1 | # PhantomFuzzer Default Configuration 2 | 3 | # General settings 4 | general: 5 | log_level: INFO 6 | output_format: json 7 | max_threads: 10 8 | scan_timeout: 300 # seconds 9 | user_agent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36" 10 | 11 | # Scanner settings 12 | scanner: 13 | modes: 14 | - basic 15 | - ml_enhanced 16 | - stealth 17 | - full_attack 18 | default_mode: basic 19 | port_scan: 20 | enabled: true 21 | port_range: "1-1000" 22 | scan_type: "SYN" 23 | web_scan: 24 | crawl_depth: 3 25 | form_submission: true 26 | file_discovery: true 27 | api_scan: 28 | methods: 29 | - GET 30 | - POST 31 | - PUT 32 | - DELETE 33 | parameter_testing: true 34 | 35 | # Fuzzer settings 36 | fuzzer: 37 | mutation_rate: 0.1 38 | max_mutations: 100 39 | strategies: 40 | - boundary_testing 41 | - type_confusion 42 | - injection 43 | - format_string 44 | - overflow 45 | input_types: 46 | - form_fields 47 | - url_parameters 48 | - headers 49 | - cookies 50 | - json_body 51 | - xml_data 52 | 53 | # ML settings 54 | ml: 55 | enabled: true 56 | models: 57 | vulnerability_classifier: 58 | path: "/data/training/models/vuln_classifier.h5" 59 | confidence_threshold: 0.7 60 | pattern_recognizer: 61 | path: "/data/training/models/pattern_rec.pkl" 62 | confidence_threshold: 0.6 63 | payload_generator: 64 | path: "/data/training/models/payload_gen.h5" 65 | temperature: 0.8 66 | training: 67 | batch_size: 32 68 | epochs: 20 69 | validation_split: 0.2 70 | early_stopping: true 71 | feedback: 72 | collect_results: true 73 | auto_retrain: false 74 | 75 | # Stealth settings 76 | stealth: 77 | browser_emulation: true 78 | random_delays: 79 | enabled: true 80 | min_delay: 0.5 # seconds 81 | max_delay: 3.0 # seconds 82 | ip_rotation: 83 | enabled: false 84 | proxy_list: "/data/proxies.txt" 85 | request_distribution: 86 | enabled: true 87 | max_rate: 10 # requests per second 88 | bandwidth_control: 89 | enabled: true 90 | max_bandwidth: 500 # KB/s 91 | 92 | # Payload settings 93 | payload: 94 | templates: 95 | enabled: true 96 | path: "/data/payloads/templates" 97 | custom_generation: 98 | enabled: true 99 | max_length: 1000 100 | effectiveness_testing: 101 | enabled: true 102 | metrics: 103 | - success_rate 104 | - evasion_rate 105 | - performance 106 | 107 | # Wordlists 108 | wordlists: 109 | usernames: "/data/wordlists/usernames/common.txt" 110 | passwords: "/data/wordlists/passwords/top10000.txt" 111 | directories: "/data/wordlists/directories/web-dirs.txt" 112 | endpoints: "/data/wordlists/endpoints/api-endpoints.txt" 113 | parameters: "/data/wordlists/parameters/web-params.txt" 114 | 115 | # Reporting 116 | reporting: 117 | formats: 118 | - json 119 | - html 120 | - pdf 121 | include: 122 | - summary 123 | - details 124 | - remediation 125 | - evidence 126 | severity_levels: 127 | - critical 128 | - high 129 | - medium 130 | - low 131 | - info 132 | 133 | # API/Web Interface 134 | api: 135 | enabled: true 136 | host: "0.0.0.0" 137 | port: 8080 138 | authentication: 139 | enabled: true 140 | method: "jwt" 141 | secret_key_env: "API_SECRET_KEY" 142 | rate_limiting: 143 | enabled: true 144 | max_requests: 100 145 | period: 60 # seconds 146 | -------------------------------------------------------------------------------- /phantomfuzzer/vulnerability/base_analyzer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Base vulnerability analyzer for PhantomFuzzer. 6 | 7 | This module provides the abstract base class for all vulnerability analyzers. 8 | """ 9 | 10 | import json 11 | from abc import ABC, abstractmethod 12 | from typing import Dict, List, Any, Optional, Union 13 | 14 | # Import from phantomfuzzer package 15 | from phantomfuzzer.utils.logging import get_module_logger 16 | from phantomfuzzer.utils.helper import print_info, print_warning, print_error, print_success 17 | 18 | # Import from vulnerability module 19 | from phantomfuzzer.vulnerability.models import Vulnerability 20 | 21 | 22 | class BaseAnalyzer(ABC): 23 | """Abstract base class for vulnerability analyzers. 24 | 25 | This class defines the interface that all analyzer implementations must follow, 26 | as well as common functionality for configuration, logging, and pattern handling. 27 | """ 28 | 29 | def __init__(self, config: Optional[Dict[str, Any]] = None): 30 | """Initialize the base analyzer. 31 | 32 | Args: 33 | config: Optional configuration dictionary. 34 | """ 35 | self.logger = get_module_logger(self.__class__.__name__.lower()) 36 | self.config = config or {} 37 | 38 | # Initialize patterns 39 | self.patterns = self._load_patterns() 40 | 41 | # Initialize ML integration if available and enabled 42 | self.ml_enabled = self.config.get('ml_enabled', False) 43 | self.ml_integration = None 44 | 45 | if self.ml_enabled: 46 | self._init_ml_integration() 47 | 48 | def _init_ml_integration(self) -> None: 49 | """Initialize ML integration if available.""" 50 | try: 51 | from phantomfuzzer.ml import MLIntegration 52 | self.ml_integration = MLIntegration() 53 | self.logger.info("ML integration initialized for vulnerability analysis") 54 | print_info("ML integration initialized for vulnerability analysis") 55 | except ImportError: 56 | self.logger.warning("ML integration not available") 57 | print_warning("ML integration not available for vulnerability analysis") 58 | self.ml_enabled = False 59 | 60 | @abstractmethod 61 | def _load_patterns(self) -> Dict[str, Any]: 62 | """Load vulnerability patterns. 63 | 64 | This method should be implemented by subclasses to load patterns 65 | specific to the type of analysis they perform. 66 | 67 | Returns: 68 | A dictionary of vulnerability patterns. 69 | """ 70 | pass 71 | 72 | @abstractmethod 73 | def analyze(self, target: Any, scan_context: Optional[Dict[str, Any]] = None) -> List[Vulnerability]: 74 | """Analyze a target for vulnerabilities. 75 | 76 | This method should be implemented by subclasses to perform 77 | analysis specific to the type of target they handle. 78 | 79 | Args: 80 | target: The target to analyze. 81 | scan_context: Optional context information about the scan. 82 | 83 | Returns: 84 | A list of detected vulnerabilities. 85 | """ 86 | pass 87 | 88 | def _handle_exception(self, e: Exception, message: str) -> None: 89 | """Handle exceptions in a consistent way. 90 | 91 | Args: 92 | e: The exception that was raised. 93 | message: A message describing what was happening when the exception occurred. 94 | """ 95 | self.logger.error(f"{message}: {str(e)}") 96 | print_error(f"{message}: {str(e)}") 97 | -------------------------------------------------------------------------------- /phantomfuzzer/vulnerability/reporter.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Vulnerability Reporter for PhantomFuzzer. 6 | 7 | This module provides functionality for generating vulnerability reports 8 | in various formats, including text, JSON, HTML, and PDF. 9 | """ 10 | 11 | import os 12 | import json 13 | import time 14 | import datetime 15 | from pathlib import Path 16 | from typing import Dict, List, Any, Optional, Union, Set, Tuple 17 | 18 | # Import from phantomfuzzer package 19 | from phantomfuzzer.utils.logging import get_module_logger 20 | from phantomfuzzer.utils.helper import print_info, print_warning, print_error, print_success 21 | 22 | # Import vulnerability constants 23 | from phantomfuzzer.vulnerability import ( 24 | # Severity levels 25 | SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO 26 | ) 27 | 28 | # Import vulnerability models 29 | from phantomfuzzer.vulnerability.models import Vulnerability 30 | 31 | 32 | class VulnerabilityReporter: 33 | """Reporter for vulnerabilities found by PhantomFuzzer. 34 | 35 | This class handles generating reports in various formats for vulnerabilities 36 | detected by the PhantomFuzzer scanners. 37 | """ 38 | 39 | def __init__(self, config: Optional[Dict[str, Any]] = None): 40 | """Initialize the vulnerability reporter. 41 | 42 | Args: 43 | config: Configuration parameters for the reporter. 44 | """ 45 | self.logger = get_module_logger('vulnerability_reporter') 46 | self.config = config or {} 47 | 48 | # Default configuration 49 | self.report_dir = self.config.get('report_dir', 'reports') 50 | self.report_formats = self.config.get('report_formats', ['text', 'json']) 51 | self.include_remediation = self.config.get('include_remediation', True) 52 | self.include_evidence = self.config.get('include_evidence', True) 53 | 54 | # Create report directory if it doesn't exist 55 | Path(self.report_dir).mkdir(parents=True, exist_ok=True) 56 | 57 | self.logger.info("Vulnerability reporter initialized") 58 | 59 | def generate_report(self, vulnerabilities: List[Vulnerability], 60 | target: str, scan_id: str, 61 | scan_time: Optional[datetime.datetime] = None) -> Dict[str, str]: 62 | """Generate vulnerability reports in the configured formats. 63 | 64 | Args: 65 | vulnerabilities: List of vulnerabilities to include in the report. 66 | target: The target that was scanned. 67 | scan_id: Unique identifier for the scan. 68 | scan_time: Time when the scan was performed. 69 | 70 | Returns: 71 | Dictionary mapping report formats to file paths. 72 | """ 73 | report_files = {} 74 | 75 | # Use current time if scan_time is not provided 76 | if scan_time is None: 77 | scan_time = datetime.datetime.now() 78 | 79 | # Generate reports in each configured format 80 | for report_format in self.report_formats: 81 | if report_format == 'text': 82 | report_file = self._generate_text_report(vulnerabilities, target, scan_id, scan_time) 83 | report_files['text'] = report_file 84 | elif report_format == 'json': 85 | report_file = self._generate_json_report(vulnerabilities, target, scan_id, scan_time) 86 | report_files['json'] = report_file 87 | elif report_format == 'html': 88 | report_file = self._generate_html_report(vulnerabilities, target, scan_id, scan_time) 89 | report_files['html'] = report_file 90 | elif report_format == 'pdf': 91 | report_file = self._generate_pdf_report(vulnerabilities, target, scan_id, scan_time) 92 | report_files['pdf'] = report_file 93 | 94 | return report_files 95 | -------------------------------------------------------------------------------- /phantomfuzzer/vulnerability/classifier.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Vulnerability Classifier for PhantomFuzzer. 6 | 7 | This module provides functionality for classifying vulnerabilities 8 | according to industry standards such as OWASP Top 10 and CWE. 9 | """ 10 | 11 | import os 12 | import json 13 | from pathlib import Path 14 | from typing import Dict, List, Any, Optional, Union, Set, Tuple 15 | 16 | # Import from phantomfuzzer package 17 | from phantomfuzzer.utils.logging import get_module_logger 18 | from phantomfuzzer.utils.helper import print_info, print_warning, print_error, print_success 19 | 20 | # Import vulnerability constants 21 | from phantomfuzzer.vulnerability import ( 22 | # Severity levels 23 | SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO, 24 | 25 | # Vulnerability categories 26 | CATEGORY_BROKEN_ACCESS_CONTROL, CATEGORY_CRYPTO_FAILURES, CATEGORY_INJECTION, 27 | CATEGORY_INSECURE_DESIGN, CATEGORY_SECURITY_MISCONFIG, CATEGORY_VULNERABLE_COMPONENTS, 28 | CATEGORY_AUTH_FAILURES, CATEGORY_SOFTWARE_DATA_INTEGRITY, CATEGORY_LOGGING_MONITORING, 29 | CATEGORY_SSRF 30 | ) 31 | 32 | # Import vulnerability models 33 | from phantomfuzzer.vulnerability.models import Vulnerability 34 | 35 | 36 | class VulnerabilityClassifier: 37 | """Classifier for vulnerabilities found by PhantomFuzzer. 38 | 39 | This class handles classifying vulnerabilities according to industry 40 | standards such as OWASP Top 10 and CWE. 41 | """ 42 | 43 | def __init__(self, config: Optional[Dict[str, Any]] = None): 44 | """Initialize the vulnerability classifier. 45 | 46 | Args: 47 | config: Configuration parameters for the classifier. 48 | """ 49 | self.logger = get_module_logger('vulnerability_classifier') 50 | self.config = config or {} 51 | 52 | # Load classification mappings 53 | self.mappings = self._load_mappings() 54 | 55 | self.logger.info("Vulnerability classifier initialized") 56 | 57 | def _load_mappings(self) -> Dict[str, Dict[str, Any]]: 58 | """Load classification mappings from configuration or default. 59 | 60 | Returns: 61 | Dictionary of classification mappings. 62 | """ 63 | # Default mappings if not provided in config 64 | default_mappings = { 65 | # Map vulnerability types to OWASP Top 10 categories 66 | 'owasp_top10': { 67 | 'sql_injection': CATEGORY_INJECTION, 68 | 'xss': CATEGORY_INJECTION, 69 | 'command_injection': CATEGORY_INJECTION, 70 | 'path_traversal': CATEGORY_BROKEN_ACCESS_CONTROL, 71 | 'insecure_deserialization': CATEGORY_INSECURE_DESIGN, 72 | 'xml_external_entity': CATEGORY_SECURITY_MISCONFIG, 73 | 'open_redirect': CATEGORY_BROKEN_ACCESS_CONTROL, 74 | 'csrf': CATEGORY_BROKEN_ACCESS_CONTROL, 75 | 'broken_auth': CATEGORY_AUTH_FAILURES, 76 | 'sensitive_info': CATEGORY_CRYPTO_FAILURES, 77 | 'insecure_headers': CATEGORY_SECURITY_MISCONFIG, 78 | 'outdated_component': CATEGORY_VULNERABLE_COMPONENTS, 79 | 'missing_logging': CATEGORY_LOGGING_MONITORING, 80 | 'ssrf': CATEGORY_SSRF 81 | }, 82 | 83 | # Map vulnerability types to CWE IDs 84 | 'cwe': { 85 | 'sql_injection': 'CWE-89', 86 | 'xss': 'CWE-79', 87 | 'command_injection': 'CWE-77', 88 | 'path_traversal': 'CWE-22', 89 | 'insecure_deserialization': 'CWE-502', 90 | 'xml_external_entity': 'CWE-611', 91 | 'open_redirect': 'CWE-601', 92 | 'csrf': 'CWE-352', 93 | 'broken_auth': 'CWE-287', 94 | 'sensitive_info': 'CWE-200', 95 | 'insecure_headers': 'CWE-693', 96 | 'outdated_component': 'CWE-1104', 97 | 'missing_logging': 'CWE-778', 98 | 'ssrf': 'CWE-918' 99 | } 100 | } 101 | 102 | # Use mappings from config if provided, otherwise use defaults 103 | return self.config.get('mappings', default_mappings) 104 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM python:3.11-slim AS builder 2 | 3 | # Set environment variables 4 | ENV PYTHONDONTWRITEBYTECODE=1 \ 5 | PYTHONUNBUFFERED=1 \ 6 | PIP_NO_CACHE_DIR=1 \ 7 | PIP_DISABLE_PIP_VERSION_CHECK=1 8 | 9 | # Install system dependencies 10 | RUN apt-get update && apt-get install -y --no-install-recommends \ 11 | build-essential \ 12 | gcc \ 13 | g++ \ 14 | libffi-dev \ 15 | libssl-dev \ 16 | git \ 17 | curl \ 18 | wget \ 19 | nmap \ 20 | libpq-dev \ 21 | libmagic1 \ 22 | libyaml-dev \ 23 | python3-dev \ 24 | && apt-get clean \ 25 | && rm -rf /var/lib/apt/lists/* 26 | 27 | # Create a virtual environment 28 | RUN python -m venv /opt/venv 29 | ENV PATH="/opt/venv/bin:$PATH" 30 | 31 | # Install Python dependencies in stages for better caching and reliability 32 | COPY requirements.txt . 33 | 34 | # Stage 1: Core dependencies 35 | RUN pip install --upgrade pip && \ 36 | pip install wheel setuptools && \ 37 | pip install "numpy>=1.24.0" "pandas>=2.0.0" "scipy>=1.11.0" "requests>=2.31.0" "click>=8.1.0" "pyyaml>=6.0.0" 38 | 39 | # Stage 2: Security and networking tools 40 | RUN pip install "pycryptodome>=3.18.0" "python-nmap>=0.7.1" "scapy>=2.5.0" "pyOpenSSL>=23.2.0" "pyjwt>=2.8.0" && \ 41 | pip install "python-magic>=0.4.27" "cryptography>=37.0.0" "paramiko>=3.3.0" "faker>=13.0.0" "pillow>=10.0.0" 42 | 43 | # Stage 3: Web and utilities 44 | RUN pip install "beautifulsoup4>=4.12.0" "aiohttp>=3.8.0" "fastapi>=0.103.0" "uvicorn>=0.23.0" "httpx>=0.25.0" && \ 45 | pip install "tqdm>=4.66.0" "python-dotenv>=1.0.0" 46 | 47 | # Stage 4: Data visualization 48 | RUN pip install "matplotlib>=3.7.0" "seaborn>=0.12.0" "plotly>=5.15.0" 49 | 50 | # Stage 5: Critical dependencies and basic ML 51 | RUN apt-get update && apt-get install -y --no-install-recommends libffi-dev && \ 52 | pip install cffi && \ 53 | pip install joblib && \ 54 | pip install "scikit-learn>=1.3.0" "nltk>=3.8.0" 55 | 56 | # Stage 6: Advanced ML libraries - install with CPU-only option when possible 57 | RUN pip install "gensim>=4.3.0" && \ 58 | pip install "tensorflow-cpu>=2.12.0" && \ 59 | pip install "torch>=2.0.0" --extra-index-url https://download.pytorch.org/whl/cpu && \ 60 | pip install "transformers>=4.30.0" && \ 61 | pip install "spacy>=3.6.0" 62 | 63 | # Final stage: Install any remaining dependencies 64 | RUN pip install -r requirements.txt 65 | 66 | # Second stage for a smaller final image 67 | FROM python:3.11-slim 68 | 69 | # Set environment variables 70 | ENV PYTHONDONTWRITEBYTECODE=1 \ 71 | PYTHONUNBUFFERED=1 \ 72 | PATH="/opt/venv/bin:$PATH" \ 73 | PYTHONWARNINGS="ignore::DeprecationWarning,ignore::PendingDeprecationWarning" \ 74 | CRYPTOGRAPHY_SUPPRESS_DEPRECATION_WARNINGS=1 75 | 76 | # Install runtime dependencies 77 | RUN apt-get update && apt-get install -y --no-install-recommends \ 78 | nmap \ 79 | curl \ 80 | wget \ 81 | libpq-dev \ 82 | libmagic1 \ 83 | libyaml-dev \ 84 | python3-yaml \ 85 | man-db \ 86 | && apt-get clean \ 87 | && rm -rf /var/lib/apt/lists/* 88 | 89 | # Copy virtual environment from builder stage 90 | COPY --from=builder /opt/venv /opt/venv 91 | 92 | # Create non-root user for security 93 | RUN groupadd -r phantomfuzzer && useradd -r -g phantomfuzzer phantomfuzzer 94 | 95 | # Create necessary directories with proper permissions 96 | RUN mkdir -p /app /data/wordlists /data/payloads /data/training /data/vulnerabilities /data/patterns 97 | RUN chown -R phantomfuzzer:phantomfuzzer /app /data 98 | 99 | # Set working directory 100 | WORKDIR /app 101 | 102 | # Copy application code 103 | COPY --chown=phantomfuzzer:phantomfuzzer . /app/ 104 | 105 | # Copy and apply the Scapy patch to suppress cryptography warnings 106 | COPY scapy_patch.py /tmp/scapy_patch.py 107 | RUN python /tmp/scapy_patch.py 108 | 109 | # Verify critical dependencies are installed 110 | RUN echo "Verifying critical dependencies..." && \ 111 | python -c "import yaml; print('PyYAML is properly installed')" && \ 112 | python -c "import numpy; print('NumPy is properly installed')" && \ 113 | python -c "import pandas; print('Pandas is properly installed')" && \ 114 | python -c "import requests; print('Requests is properly installed')" && \ 115 | python -c "import click; print('Click is properly installed')" 116 | 117 | # Switch to non-root user 118 | USER phantomfuzzer 119 | 120 | # Expose port for API/Web interface 121 | EXPOSE 8080 122 | 123 | # Command to run the application 124 | ENTRYPOINT ["python", "-m", "phantomfuzzer.cli"] 125 | CMD ["--help"] 126 | -------------------------------------------------------------------------------- /examples/pattern_db_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Example script demonstrating the usage of the PatternDatabase. 6 | 7 | This script shows how to use the PatternDatabase class to manage patterns 8 | for anomaly detection and pattern recognition. 9 | """ 10 | 11 | import os 12 | import sys 13 | from pathlib import Path 14 | 15 | # Add project root to path 16 | sys.path.insert(0, str(Path(__file__).parent.parent)) 17 | 18 | # Import PhantomFuzzer modules 19 | from phantomfuzzer.ml.storage.pattern_db import PatternDatabase 20 | from phantomfuzzer.ml.models.pattern_recognizer import PatternRecognizer 21 | 22 | 23 | def main(): 24 | """Run the pattern database example.""" 25 | print("=== PhantomFuzzer Pattern Database Example ===") 26 | 27 | # Initialize the pattern database 28 | print("\nInitializing pattern database...") 29 | pattern_db = PatternDatabase() 30 | 31 | # Display pattern count 32 | pattern_count = len(pattern_db.patterns) 33 | print(f"Loaded {pattern_count} patterns from database") 34 | 35 | # Add a new pattern 36 | print("\nAdding a new pattern...") 37 | new_pattern = "admin_backup.zip" 38 | pattern_id = pattern_db.add_pattern( 39 | pattern=new_pattern, 40 | source='example', 41 | confidence=0.9, 42 | metadata={'type': 'backup_file', 'risk': 'high', 'description': 'Admin backup file'} 43 | ) 44 | print(f"Added pattern with ID: {pattern_id}") 45 | 46 | # Find similar patterns 47 | print("\nFinding similar patterns...") 48 | similar_patterns = pattern_db.find_similar_patterns(new_pattern, threshold=0.7) 49 | print(f"Found {len(similar_patterns)} similar patterns:") 50 | for i, p in enumerate(similar_patterns[:5], 1): # Show top 5 51 | print(f" {i}. {p['entry']['pattern']} (similarity: {p['similarity']:.2f})") 52 | 53 | # Get patterns by confidence 54 | print("\nGetting high-confidence patterns...") 55 | high_confidence = pattern_db.get_patterns_by_confidence(min_confidence=0.8) 56 | print(f"Found {len(high_confidence)} high-confidence patterns") 57 | for i, p in enumerate(high_confidence[:5], 1): # Show top 5 58 | print(f" {i}. {p['entry']['pattern']} (confidence: {p['entry']['confidence']:.2f})") 59 | 60 | # Update pattern confidence 61 | print("\nUpdating pattern confidence...") 62 | pattern_db.update_pattern(pattern_id, confidence=0.95) 63 | updated_pattern = pattern_db.get_pattern(pattern_id) 64 | print(f"Updated confidence: {updated_pattern['confidence']}") 65 | 66 | # Increment usage count 67 | print("\nIncrementing usage count...") 68 | pattern_db.increment_usage_count(pattern_id) 69 | updated_pattern = pattern_db.get_pattern(pattern_id) 70 | print(f"New usage count: {updated_pattern['usage_count']}") 71 | 72 | # Export patterns 73 | print("\nExporting patterns...") 74 | export_path = pattern_db.export_patterns() 75 | print(f"Exported patterns to: {export_path}") 76 | 77 | # Integration with PatternRecognizer 78 | print("\nIntegrating with PatternRecognizer...") 79 | 80 | # Create a simple function to check if a file matches any pattern 81 | def check_file_against_patterns(file_path, pattern_db): 82 | """Check if a file matches any pattern in the database.""" 83 | file_name = Path(file_path).name 84 | 85 | # Check for exact matches 86 | pattern_entry = pattern_db.get_pattern_by_value(file_name) 87 | if pattern_entry: 88 | return True, pattern_entry 89 | 90 | # Check for similar patterns 91 | similar_patterns = pattern_db.find_similar_patterns(file_name, threshold=0.8) 92 | if similar_patterns: 93 | return True, similar_patterns[0]['entry'] 94 | 95 | return False, None 96 | 97 | # Example files 98 | example_files = [ 99 | "admin.zip", 100 | "normal_file.txt", 101 | "config.bak", 102 | "admin_backup.zip" 103 | ] 104 | 105 | print("\nChecking example files against patterns:") 106 | for file in example_files: 107 | matches, pattern = check_file_against_patterns(file, pattern_db) 108 | if matches: 109 | print(f" {file}: MATCH! Pattern: {pattern['pattern']} (confidence: {pattern['confidence']:.2f})") 110 | else: 111 | print(f" {file}: No match") 112 | 113 | print("\n=== Pattern Database Example Complete ===") 114 | 115 | 116 | if __name__ == "__main__": 117 | main() 118 | -------------------------------------------------------------------------------- /phantomfuzzer/vulnerability/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Vulnerability analysis module for PhantomFuzzer. 6 | 7 | This module provides a centralized system for vulnerability analysis, 8 | classification, severity assessment, and reporting. It integrates with 9 | the scanner, fuzzer, and payload modules to provide a comprehensive 10 | vulnerability management system. 11 | """ 12 | 13 | from typing import Dict, List, Any, Optional, Union, Set, Tuple 14 | 15 | # Vulnerability severity levels 16 | # These match the levels in scanner/base.py for consistency 17 | SEVERITY_CRITICAL = 'critical' 18 | SEVERITY_HIGH = 'high' 19 | SEVERITY_MEDIUM = 'medium' 20 | SEVERITY_LOW = 'low' 21 | SEVERITY_INFO = 'info' 22 | 23 | # Vulnerability categories (OWASP Top 10 2021) 24 | CATEGORY_BROKEN_ACCESS_CONTROL = 'A01:2021-Broken Access Control' 25 | CATEGORY_CRYPTO_FAILURES = 'A02:2021-Cryptographic Failures' 26 | CATEGORY_INJECTION = 'A03:2021-Injection' 27 | CATEGORY_INSECURE_DESIGN = 'A04:2021-Insecure Design' 28 | CATEGORY_SECURITY_MISCONFIG = 'A05:2021-Security Misconfiguration' 29 | CATEGORY_VULNERABLE_COMPONENTS = 'A06:2021-Vulnerable and Outdated Components' 30 | CATEGORY_AUTH_FAILURES = 'A07:2021-Identification and Authentication Failures' 31 | CATEGORY_SOFTWARE_DATA_INTEGRITY = 'A08:2021-Software and Data Integrity Failures' 32 | CATEGORY_LOGGING_MONITORING = 'A09:2021-Security Logging and Monitoring Failures' 33 | CATEGORY_SSRF = 'A10:2021-Server-Side Request Forgery' 34 | 35 | # Consolidated vulnerability types from all scanners 36 | # File-related vulnerabilities 37 | VULN_MALWARE_SIGNATURE = 'Malware Signature' 38 | VULN_SENSITIVE_INFO = 'Sensitive Information' 39 | VULN_CODE_VULNERABILITY = 'Code Vulnerability' 40 | VULN_INSECURE_PERMISSION = 'Insecure File Permission' 41 | VULN_SUSPICIOUS_EXTENSION = 'Suspicious File Extension' 42 | 43 | # API-related vulnerabilities 44 | VULN_INJECTION = 'API Injection' 45 | VULN_BROKEN_AUTH = 'Broken Authentication' 46 | VULN_BROKEN_OBJECT_AUTH = 'Broken Object Level Authorization' 47 | VULN_EXCESSIVE_DATA = 'Excessive Data Exposure' 48 | VULN_RATE_LIMIT = 'Lack of Rate Limiting' 49 | VULN_MASS_ASSIGNMENT = 'Mass Assignment' 50 | VULN_SECURITY_MISCONFIG = 'Security Misconfiguration' 51 | 52 | # ML-specific vulnerabilities 53 | VULN_ML_ANOMALY = 'ML-Detected Anomaly' 54 | VULN_PATTERN_MATCH = 'Suspicious Pattern Match' 55 | 56 | # Web-specific vulnerabilities 57 | VULN_XSS = 'Cross-Site Scripting' 58 | VULN_CSRF = 'Cross-Site Request Forgery' 59 | VULN_SQL_INJECTION = 'SQL Injection' 60 | VULN_COMMAND_INJECTION = 'Command Injection' 61 | VULN_PATH_TRAVERSAL = 'Path Traversal' 62 | VULN_OPEN_REDIRECT = 'Open Redirect' 63 | VULN_INSECURE_DESERIALIZATION = 'Insecure Deserialization' 64 | VULN_XML_EXTERNAL_ENTITY = 'XML External Entity' 65 | 66 | # Import analyzer, classifier, severity, and reporter modules 67 | # These will be implemented in their respective files 68 | try: 69 | from phantomfuzzer.vulnerability.analyzer import VulnerabilityAnalyzer 70 | from phantomfuzzer.vulnerability.classifier import VulnerabilityClassifier 71 | from phantomfuzzer.vulnerability.severity import SeverityAssessor 72 | from phantomfuzzer.vulnerability.reporter import VulnerabilityReporter 73 | 74 | # Define the Vulnerability class for representing vulnerabilities 75 | from phantomfuzzer.vulnerability.analyzer import Vulnerability 76 | 77 | __all__ = [ 78 | # Classes 79 | 'VulnerabilityAnalyzer', 80 | 'VulnerabilityClassifier', 81 | 'SeverityAssessor', 82 | 'VulnerabilityReporter', 83 | 'Vulnerability', 84 | 85 | # Severity levels 86 | 'SEVERITY_CRITICAL', 87 | 'SEVERITY_HIGH', 88 | 'SEVERITY_MEDIUM', 89 | 'SEVERITY_LOW', 90 | 'SEVERITY_INFO', 91 | 92 | # Categories 93 | 'CATEGORY_BROKEN_ACCESS_CONTROL', 94 | 'CATEGORY_CRYPTO_FAILURES', 95 | 'CATEGORY_INJECTION', 96 | 'CATEGORY_INSECURE_DESIGN', 97 | 'CATEGORY_SECURITY_MISCONFIG', 98 | 'CATEGORY_VULNERABLE_COMPONENTS', 99 | 'CATEGORY_AUTH_FAILURES', 100 | 'CATEGORY_SOFTWARE_DATA_INTEGRITY', 101 | 'CATEGORY_LOGGING_MONITORING', 102 | 'CATEGORY_SSRF', 103 | 104 | # Vulnerability types 105 | 'VULN_MALWARE_SIGNATURE', 106 | 'VULN_SENSITIVE_INFO', 107 | 'VULN_CODE_VULNERABILITY', 108 | 'VULN_INSECURE_PERMISSION', 109 | 'VULN_SUSPICIOUS_EXTENSION', 110 | 'VULN_INJECTION', 111 | 'VULN_BROKEN_AUTH', 112 | 'VULN_BROKEN_OBJECT_AUTH', 113 | 'VULN_EXCESSIVE_DATA', 114 | 'VULN_RATE_LIMIT', 115 | 'VULN_MASS_ASSIGNMENT', 116 | 'VULN_SECURITY_MISCONFIG', 117 | 'VULN_ML_ANOMALY', 118 | 'VULN_PATTERN_MATCH', 119 | 'VULN_XSS', 120 | 'VULN_CSRF', 121 | 'VULN_SQL_INJECTION', 122 | 'VULN_COMMAND_INJECTION', 123 | 'VULN_PATH_TRAVERSAL', 124 | 'VULN_OPEN_REDIRECT', 125 | 'VULN_INSECURE_DESERIALIZATION', 126 | 'VULN_XML_EXTERNAL_ENTITY' 127 | ] 128 | except ImportError: 129 | # This allows the module to be imported even if the implementation files 130 | # haven't been created yet 131 | pass -------------------------------------------------------------------------------- /usage.txt: -------------------------------------------------------------------------------- 1 | Scanning Operations 2 | Web Application Scanning 3 | 4 | PhantomFuzzer allows you to scan web applications for vulnerabilities: 5 | Basic Web Scanning 6 | 7 | phantomfuzzer scanner web --url https://example.com 8 | 9 | Scan with Authentication 10 | 11 | phantomfuzzer scanner web --url https://example.com --auth '{"username":"user","password":"pass"}' 12 | 13 | Control Scan Depth 14 | 15 | phantomfuzzer scanner web --url https://example.com --depth 2 16 | 17 | Save Results to a File 18 | 19 | phantomfuzzer scanner web --url https://example.com --output web_results.json --format json 20 | 21 | API Scanning 22 | 23 | Scan your APIs for potential vulnerabilities: 24 | 25 | phantomfuzzer scanner api --url https://api.example.com 26 | 27 | With OpenAPI/Swagger Specification 28 | 29 | phantomfuzzer scanner api --url https://api.example.com --spec openapi.json 30 | 31 | With Authentication 32 | 33 | phantomfuzzer scanner api --url https://api.example.com --auth '{"token":"your-api-token"}' 34 | 35 | Save Results to a File 36 | 37 | phantomfuzzer scanner api --url https://api.example.com --output api_results.json --format json 38 | 39 | File Scanning 40 | 41 | Scan files and directories for vulnerabilities: 42 | Scan a Single File 43 | 44 | phantomfuzzer scanner file --path ./target/file.php 45 | 46 | Recursive Directory Scan 47 | 48 | phantomfuzzer scanner file --path ./target --recursive 49 | 50 | Scan with File Pattern Matching 51 | 52 | phantomfuzzer scanner file --path ./target --recursive --pattern "*.php" 53 | 54 | Enable Machine Learning Enhanced Detection 55 | 56 | phantomfuzzer scanner file --path ./target --ml-enhanced 57 | 58 | Save Results to a File 59 | 60 | phantomfuzzer scanner file --path ./target --output file_results.json --format json 61 | 62 | Fuzzing Operations 63 | API Fuzzing 64 | 65 | PhantomFuzzer provides the ability to fuzz APIs by sending crafted requests. Here's how to perform API fuzzing: 66 | Basic API Fuzzing 67 | 68 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --method GET 69 | 70 | POST Request Fuzzing 71 | 72 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --method POST --data '{"username":"test"}' 73 | 74 | Fuzz with Custom Headers 75 | 76 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --headers '{"Authorization":"Bearer token"}' 77 | 78 | With Authentication 79 | 80 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --auth '{"username":"user","password":"pass"}' 81 | 82 | Control Fuzzing Intensity 83 | 84 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --iterations 200 --delay 0.2 --timeout 10 85 | 86 | Save Results to a File 87 | 88 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --output results.json --format json 89 | 90 | Protocol Fuzzing 91 | 92 | You can fuzz different protocols like TCP, SSH, and FTP. Below are examples: 93 | TCP Protocol Fuzzing 94 | 95 | phantomfuzzer fuzzer protocol --target example.com --port 80 --protocol tcp 96 | 97 | SSH Protocol Fuzzing 98 | 99 | phantomfuzzer fuzzer protocol --target example.com --port 22 --protocol ssh 100 | 101 | FTP Protocol Fuzzing 102 | 103 | phantomfuzzer fuzzer protocol --target example.com --port 21 --protocol ftp 104 | 105 | Control Protocol Fuzzing Intensity 106 | 107 | phantomfuzzer fuzzer protocol --target example.com --port 80 --protocol http --iterations 100 --delay 0.5 --timeout 15 108 | 109 | Input Fuzzing 110 | 111 | You can fuzz various types of inputs, including files, stdin, and command-line arguments. 112 | File Input Fuzzing 113 | 114 | phantomfuzzer fuzzer input --target ./target/application --input-type file 115 | 116 | Command-Line Argument Fuzzing 117 | 118 | phantomfuzzer fuzzer input --target ./target/application --input-type argument 119 | 120 | Save Results to a File 121 | 122 | phantomfuzzer fuzzer input --target ./target/application --input-type file --output input_results.json --output-format json 123 | 124 | Payload Generation 125 | 126 | PhantomFuzzer allows you to generate different types of attack payloads for various categories. Here's how you can use it: 127 | List Available Payload Categories 128 | 129 | phantomfuzzer payload list 130 | 131 | Generate Specific Payloads 132 | 133 | SQL Injection (Basic) 134 | 135 | phantomfuzzer payload generate --category sql_injection --subcategory basic 136 | 137 | Generate Multiple XSS Payloads 138 | 139 | phantomfuzzer payload generate --category xss --count 5 --output xss_payloads.txt 140 | 141 | Generate Command Injection Payloads in JSON Format 142 | 143 | phantomfuzzer payload generate --category command_injection --format json 144 | 145 | Generate Random Payloads 146 | 147 | phantomfuzzer payload random --count 3 148 | 149 | Advanced Usage 150 | Combining Operations 151 | 152 | You can chain multiple operations for more comprehensive testing: 153 | 154 | # Generate payloads and use them for API fuzzing 155 | phantomfuzzer payload generate --category sql_injection --output sql_payloads.txt 156 | phantomfuzzer fuzzer api --target https://api.example.com/query --method POST --data @sql_payloads.txt 157 | 158 | # Scan and then fuzz discovered endpoints 159 | phantomfuzzer scanner api --url https://api.example.com --output discovered_apis.json 160 | phantomfuzzer fuzzer api --target https://api.example.com/query --method POST --data @discovered_apis.json 161 | 162 | Debug Mode 163 | 164 | Enable debug logging for more detailed output: 165 | 166 | phantomfuzzer --debug scanner web --url https://example.com 167 | -------------------------------------------------------------------------------- /phantomfuzzer/vulnerability/models.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Vulnerability models for PhantomFuzzer. 6 | 7 | This module provides data models for representing vulnerabilities 8 | and related concepts in the vulnerability analysis system. 9 | """ 10 | 11 | import json 12 | import uuid 13 | import hashlib 14 | from datetime import datetime 15 | from typing import Dict, List, Any, Optional, Union 16 | 17 | # Import vulnerability constants 18 | from phantomfuzzer.vulnerability import ( 19 | # Severity levels 20 | SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO, 21 | 22 | # Vulnerability categories 23 | CATEGORY_BROKEN_ACCESS_CONTROL, CATEGORY_CRYPTO_FAILURES, CATEGORY_INJECTION, 24 | CATEGORY_INSECURE_DESIGN, CATEGORY_SECURITY_MISCONFIG, CATEGORY_VULNERABLE_COMPONENTS, 25 | CATEGORY_AUTH_FAILURES, CATEGORY_SOFTWARE_DATA_INTEGRITY, CATEGORY_LOGGING_MONITORING, 26 | CATEGORY_SSRF 27 | ) 28 | 29 | 30 | class Vulnerability: 31 | """Class representing a vulnerability. 32 | 33 | This class provides a standardized representation of vulnerabilities 34 | across different scanners and target types. 35 | """ 36 | 37 | def __init__(self, name: str, description: str, severity: str, 38 | location: str, category: Optional[str] = None, 39 | evidence: Optional[str] = None, remediation: Optional[str] = None, 40 | cwe_id: Optional[str] = None, cvss_score: Optional[float] = None, 41 | detection_method: Optional[str] = None, confidence: float = 1.0, 42 | **details): 43 | """Initialize a vulnerability. 44 | 45 | Args: 46 | name: The name/type of the vulnerability. 47 | description: A description of the vulnerability. 48 | severity: The severity level (one of the SEVERITY_* constants). 49 | location: The location of the vulnerability (e.g., URL, file path). 50 | category: Optional category (e.g., OWASP Top 10 category). 51 | evidence: Optional evidence of the vulnerability. 52 | remediation: Optional remediation advice. 53 | cwe_id: Optional Common Weakness Enumeration ID. 54 | cvss_score: Optional Common Vulnerability Scoring System score. 55 | detection_method: Optional method used to detect the vulnerability. 56 | confidence: Confidence level (0.0 to 1.0) in the detection. 57 | **details: Additional details about the vulnerability. 58 | """ 59 | self.id = str(uuid.uuid4()) 60 | self.name = name 61 | self.description = description 62 | self.severity = severity 63 | self.location = location 64 | self.category = category 65 | self.evidence = evidence 66 | self.remediation = remediation 67 | self.cwe_id = cwe_id 68 | self.cvss_score = cvss_score 69 | self.detection_method = detection_method 70 | self.confidence = confidence 71 | self.details = details 72 | self.timestamp = datetime.now() 73 | 74 | # Generate a hash of the vulnerability for deduplication 75 | self.hash = self._generate_hash() 76 | 77 | def _generate_hash(self) -> str: 78 | """Generate a hash of the vulnerability for deduplication. 79 | 80 | Returns: 81 | A hash string uniquely identifying this vulnerability. 82 | """ 83 | # Create a string with the key attributes 84 | hash_str = f"{self.name}|{self.location}|{self.description}" 85 | 86 | # Add evidence if available 87 | if self.evidence: 88 | hash_str += f"|{self.evidence}" 89 | 90 | # Generate a hash 91 | return hashlib.md5(hash_str.encode()).hexdigest() 92 | 93 | def to_dict(self) -> Dict[str, Any]: 94 | """Convert the vulnerability to a dictionary. 95 | 96 | Returns: 97 | A dictionary representation of the vulnerability. 98 | """ 99 | return { 100 | 'id': self.id, 101 | 'name': self.name, 102 | 'description': self.description, 103 | 'severity': self.severity, 104 | 'location': self.location, 105 | 'category': self.category, 106 | 'evidence': self.evidence, 107 | 'remediation': self.remediation, 108 | 'cwe_id': self.cwe_id, 109 | 'cvss_score': self.cvss_score, 110 | 'detection_method': self.detection_method, 111 | 'confidence': self.confidence, 112 | 'details': self.details, 113 | 'timestamp': self.timestamp.isoformat(), 114 | 'hash': self.hash 115 | } 116 | 117 | def to_json(self, pretty: bool = False) -> str: 118 | """Convert the vulnerability to a JSON string. 119 | 120 | Args: 121 | pretty: Whether to format the JSON with indentation. 122 | 123 | Returns: 124 | A JSON string representation of the vulnerability. 125 | """ 126 | indent = 4 if pretty else None 127 | return json.dumps(self.to_dict(), indent=indent) 128 | 129 | def __eq__(self, other): 130 | """Check if two vulnerabilities are equal. 131 | 132 | Args: 133 | other: Another vulnerability to compare with. 134 | 135 | Returns: 136 | True if the vulnerabilities are equal, False otherwise. 137 | """ 138 | if not isinstance(other, Vulnerability): 139 | return False 140 | 141 | return self.hash == other.hash 142 | 143 | def __hash__(self): 144 | """Get the hash of the vulnerability. 145 | 146 | Returns: 147 | The hash of the vulnerability. 148 | """ 149 | return hash(self.hash) 150 | -------------------------------------------------------------------------------- /phantomfuzzer/vulnerability/severity.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Vulnerability Severity Assessor for PhantomFuzzer. 6 | 7 | This module provides functionality for assessing the severity of vulnerabilities 8 | using industry standard scoring systems such as CVSS. 9 | """ 10 | 11 | import os 12 | import json 13 | import math 14 | from pathlib import Path 15 | from typing import Dict, List, Any, Optional, Union, Set, Tuple 16 | 17 | # Import from phantomfuzzer package 18 | from phantomfuzzer.utils.logging import get_module_logger 19 | from phantomfuzzer.utils.helper import print_info, print_warning, print_error, print_success 20 | 21 | # Import vulnerability constants 22 | from phantomfuzzer.vulnerability import ( 23 | # Severity levels 24 | SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO 25 | ) 26 | 27 | # Import vulnerability models 28 | from phantomfuzzer.vulnerability.models import Vulnerability 29 | 30 | 31 | class SeverityAssessor: 32 | """Assessor for vulnerability severity in PhantomFuzzer. 33 | 34 | This class handles assessing the severity of vulnerabilities using 35 | industry standard scoring systems such as CVSS. 36 | """ 37 | 38 | def __init__(self, config: Optional[Dict[str, Any]] = None): 39 | """Initialize the severity assessor. 40 | 41 | Args: 42 | config: Configuration parameters for the assessor. 43 | """ 44 | self.logger = get_module_logger('severity_assessor') 45 | self.config = config or {} 46 | 47 | # Default configuration 48 | self.scoring_system = self.config.get('scoring_system', 'cvss') 49 | self.cvss_version = self.config.get('cvss_version', '3.1') 50 | 51 | # Load severity mappings 52 | self.mappings = self._load_mappings() 53 | 54 | self.logger.info("Severity assessor initialized") 55 | 56 | def _load_mappings(self) -> Dict[str, Dict[str, Any]]: 57 | """Load severity mappings from configuration or default. 58 | 59 | Returns: 60 | Dictionary of severity mappings. 61 | """ 62 | # Default mappings if not provided in config 63 | default_mappings = { 64 | # Map vulnerability types to default CVSS scores 65 | 'cvss': { 66 | 'sql_injection': 8.5, # High 67 | 'xss': 6.5, # Medium 68 | 'command_injection': 9.0, # Critical 69 | 'path_traversal': 7.5, # High 70 | 'insecure_deserialization': 8.0, # High 71 | 'xml_external_entity': 7.5, # High 72 | 'open_redirect': 5.5, # Medium 73 | 'csrf': 6.0, # Medium 74 | 'broken_auth': 8.0, # High 75 | 'sensitive_info': 7.0, # High 76 | 'insecure_headers': 5.0, # Medium 77 | 'outdated_component': 6.5, # Medium 78 | 'missing_logging': 4.0, # Medium 79 | 'ssrf': 7.0 # High 80 | }, 81 | 82 | # Map CVSS scores to severity levels 83 | 'cvss_to_severity': { 84 | 'critical': (9.0, 10.0), 85 | 'high': (7.0, 8.9), 86 | 'medium': (4.0, 6.9), 87 | 'low': (1.0, 3.9), 88 | 'info': (0.0, 0.9) 89 | } 90 | } 91 | 92 | # Use mappings from config if provided, otherwise use defaults 93 | return self.config.get('mappings', default_mappings) 94 | 95 | def assess_severity(self, vulnerability: Vulnerability) -> str: 96 | """Assess the severity of a vulnerability. 97 | 98 | Args: 99 | vulnerability: The vulnerability to assess. 100 | 101 | Returns: 102 | The severity level (one of the SEVERITY_* constants). 103 | """ 104 | # If severity is already set, return it 105 | if vulnerability.severity and vulnerability.severity in [ 106 | SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO 107 | ]: 108 | return vulnerability.severity 109 | 110 | # If CVSS score is provided, use it to determine severity 111 | if vulnerability.cvss_score is not None: 112 | return self._cvss_to_severity(vulnerability.cvss_score) 113 | 114 | # Otherwise, determine severity based on vulnerability type 115 | vuln_type = vulnerability.name.lower() 116 | for key in self.mappings['cvss']: 117 | if key in vuln_type: 118 | cvss_score = self.mappings['cvss'][key] 119 | return self._cvss_to_severity(cvss_score) 120 | 121 | # Default to medium if no mapping is found 122 | return SEVERITY_MEDIUM 123 | 124 | def _cvss_to_severity(self, cvss_score: float) -> str: 125 | """Convert a CVSS score to a severity level. 126 | 127 | Args: 128 | cvss_score: The CVSS score (0.0-10.0). 129 | 130 | Returns: 131 | The severity level (one of the SEVERITY_* constants). 132 | """ 133 | for severity, (min_score, max_score) in self.mappings['cvss_to_severity'].items(): 134 | if min_score <= cvss_score <= max_score: 135 | if severity == 'critical': 136 | return SEVERITY_CRITICAL 137 | elif severity == 'high': 138 | return SEVERITY_HIGH 139 | elif severity == 'medium': 140 | return SEVERITY_MEDIUM 141 | elif severity == 'low': 142 | return SEVERITY_LOW 143 | elif severity == 'info': 144 | return SEVERITY_INFO 145 | 146 | # Default to medium if no mapping is found 147 | return SEVERITY_MEDIUM 148 | -------------------------------------------------------------------------------- /data/patterns/patterns_export_20250321_230401.txt: -------------------------------------------------------------------------------- 1 | # PhantomFuzzer Pattern Database Export 2 | # Generated: 2025-03-21T23:04:01.710212 3 | # Total Patterns: 449 4 | 5 | nginx.conf 6 | .nginx 7 | nginx_status 8 | nginx.pid 9 | nginx.access 10 | nginx.error 11 | nginx.log 12 | nginx.cache 13 | proxy.conf 14 | vhost.conf 15 | sites-enabled 16 | sites-available 17 | conf.d 18 | fastcgi.conf 19 | fastcgi_params 20 | mime.types 21 | nginx_temp 22 | nginx.bak 23 | nginx.old 24 | nginx.debug 25 | nginx.test 26 | nginx.local 27 | nginx.dev 28 | nginx.prod 29 | nginx.staging 30 | nginx.backup 31 | nginx.master 32 | nginx.worker 33 | nginx.default 34 | nginx.template 35 | nginx.original 36 | nginx.save 37 | nginx.copy 38 | nginx.conf~ 39 | nginx.conf.bak 40 | nginx.conf.old 41 | nginx.conf.orig 42 | nginx.conf.rpmsave 43 | nginx.conf.rpmnew 44 | nginx.conf.swp 45 | nginx.conf.default 46 | nginx.conf.template 47 | nginx.conf.sample 48 | nginx.conf.example 49 | nginx.conf.local 50 | nginx.conf.dev 51 | nginx.conf.prod 52 | nginx.conf.staging 53 | nginx.conf.backup 54 | nginx.conf.master 55 | nginx.conf.worker 56 | nginx.conf.debug 57 | nginx.conf.test 58 | nginx.conf.save 59 | nginx.conf.copy 60 | nginx/conf 61 | nginx/logs 62 | nginx/temp 63 | nginx/cache 64 | nginx/run 65 | nginx/html 66 | nginx/www 67 | nginx/backup 68 | nginx/sites 69 | nginx/vhosts 70 | nginx/ssl 71 | nginx/certs 72 | nginx/modules 73 | nginx/scripts 74 | nginx/proxy 75 | admin 76 | administrator 77 | admincp 78 | admins 79 | administrador 80 | adm 81 | backend 82 | backoffice 83 | control 84 | cpanel 85 | manage 86 | management 87 | manager 88 | portal 89 | webadmin 90 | sysadmin 91 | admin-console 92 | admin-panel 93 | admin-area 94 | admin-login 95 | admin-interface 96 | admin-dashboard 97 | admin-center 98 | admin-cp 99 | admin_area 100 | admin_login 101 | admin_console 102 | admin_panel 103 | adminarea 104 | adminlogin 105 | adminconsole 106 | adminpanel 107 | administration 108 | administrative 109 | administrator-login 110 | administrator-panel 111 | administrator-console 112 | administrator-area 113 | administrador-login 114 | administrador-panel 115 | administrador-console 116 | index.php 117 | index.html 118 | index.htm 119 | index.asp 120 | index.aspx 121 | index.jsp 122 | index.do 123 | index.action 124 | index.cfm 125 | index.rb 126 | index.py 127 | index.pl 128 | index.cgi 129 | index.shtml 130 | index.jspx 131 | default.php 132 | default.html 133 | default.htm 134 | default.asp 135 | home.php 136 | home.html 137 | home.htm 138 | home.asp 139 | home.aspx 140 | main.php 141 | main.html 142 | main.htm 143 | main.asp 144 | main.aspx 145 | dev 146 | development 147 | test 148 | testing 149 | staging 150 | beta 151 | debug 152 | demo 153 | example 154 | sample 155 | temp 156 | tmp 157 | backup 158 | bak 159 | dev-admin 160 | dev-console 161 | dev-panel 162 | dev-login 163 | dev-api 164 | test-admin 165 | test-console 166 | test-panel 167 | test-login 168 | test-api 169 | staging-admin 170 | staging-console 171 | staging-panel 172 | staging-login 173 | beta-admin 174 | beta-console 175 | beta-panel 176 | beta-login 177 | beta-api 178 | debug-console 179 | debug-panel 180 | debug-log 181 | debug-info 182 | demo-admin 183 | demo-console 184 | demo-panel 185 | demo-login 186 | demo-api 187 | log 188 | logs 189 | error_log 190 | error.log 191 | access_log 192 | access.log 193 | debug_log 194 | debug.log 195 | app.log 196 | application.log 197 | web.log 198 | server.log 199 | event.log 200 | system.log 201 | security.log 202 | admin.log 203 | php_error.log 204 | php-error.log 205 | php_errors.log 206 | php-errors.log 207 | error-log 208 | error_logs 209 | error-logs 210 | errorlog 211 | error.logs 212 | log/error 213 | log/access 214 | log/debug 215 | log/app 216 | log/web 217 | logs/error 218 | logs/access 219 | logs/debug 220 | logs/app 221 | logs/web 222 | var/log 223 | var/logs 224 | var/log/nginx 225 | var/log/apache 226 | var/log/httpd 227 | var/log/apache2 228 | var/log/php 229 | var/log/mysql 230 | backups 231 | old 232 | save 233 | saved 234 | backup_db 235 | backup-db 236 | db_backup 237 | db-backup 238 | mysql_backup 239 | sql_backup 240 | database_backup 241 | site_backup 242 | web_backup 243 | backup_files 244 | backup-files 245 | files_backup 246 | files-backup 247 | backup_config 248 | backup-config 249 | config_backup 250 | config-backup 251 | backup_system 252 | backup-system 253 | system_backup 254 | system-backup 255 | backup.sql 256 | backup.gz 257 | backup.tar 258 | backup.zip 259 | backup.7z 260 | backup.tar.gz 261 | backup.tar.bz2 262 | backup.tgz 263 | backup.tbz2 264 | config 265 | conf 266 | settings 267 | setup 268 | install 269 | configuration 270 | configure 271 | env 272 | environment 273 | .env 274 | .git 275 | .svn 276 | .htaccess 277 | web.config 278 | robots.txt 279 | sitemap.xml 280 | crossdomain.xml 281 | config.php 282 | config.inc.php 283 | config.inc 284 | config.ini 285 | config.json 286 | config.yml 287 | config.yaml 288 | config.xml 289 | config.js 290 | config.conf 291 | config.local 292 | config.dev 293 | config.prod 294 | config.staging 295 | config.test 296 | config.debug 297 | config.default 298 | config.template 299 | config.sample 300 | config.example 301 | config.bak 302 | config.old 303 | config.orig 304 | config.backup 305 | settings.php 306 | settings.inc.php 307 | settings.ini 308 | settings.json 309 | settings.yml 310 | settings.yaml 311 | settings.xml 312 | settings.js 313 | settings.conf 314 | settings.local 315 | settings.dev 316 | settings.prod 317 | api 318 | api/v1 319 | api/v2 320 | api/v3 321 | api/v4 322 | api/v5 323 | api/latest 324 | api/beta 325 | api/alpha 326 | api/test 327 | api/dev 328 | api/staging 329 | api/prod 330 | api/docs 331 | api/swagger 332 | api/graphql 333 | api/rest 334 | api/soap 335 | api/json 336 | api/xml 337 | api/rpc 338 | api/internal 339 | api/external 340 | api/public 341 | api/private 342 | api/open 343 | api/secure 344 | api/auth 345 | api/oauth 346 | api/jwt 347 | login 348 | logout 349 | signin 350 | signout 351 | register 352 | signup 353 | password 354 | passwd 355 | forgot-password 356 | reset-password 357 | change-password 358 | update-password 359 | password-reset 360 | auth 361 | authentication 362 | authorize 363 | authorization 364 | oauth 365 | oauth2 366 | openid 367 | saml 368 | sso 369 | security 370 | login.php 371 | login.asp 372 | login.jsp 373 | login.html 374 | login.htm 375 | user-login 376 | member-login 377 | customer-login 378 | phpmyadmin 379 | phpMyAdmin 380 | myadmin 381 | mysql 382 | sql 383 | database 384 | db 385 | dbadmin 386 | web/phpMyAdmin 387 | mysql/admin 388 | mysql/db 389 | mysqladmin 390 | mysql-admin 391 | mysql_admin 392 | sqlweb 393 | webdb 394 | websql 395 | sqladmin 396 | sql-admin 397 | db-admin 398 | database-admin 399 | dbmanager 400 | db-manager 401 | sql-manager 402 | server-status 403 | server-info 404 | status 405 | stats 406 | statistics 407 | info 408 | phpinfo.php 409 | php_info.php 410 | info.php 411 | test.php 412 | probe.php 413 | status.php 414 | monitor 415 | monitoring 416 | health 417 | healthcheck 418 | health-check 419 | ping 420 | server 421 | host 422 | system 423 | sysinfo 424 | sys-info 425 | serverinfo 426 | wp-admin 427 | wp-login 428 | wp-config 429 | wp-content 430 | wp-includes 431 | wordpress 432 | wp 433 | blog 434 | joomla 435 | drupal 436 | magento 437 | laravel 438 | symfony 439 | django 440 | flask 441 | rails 442 | spring 443 | struts 444 | node 445 | angular 446 | react 447 | vue 448 | cms 449 | site 450 | web 451 | app 452 | application 453 | admin_backup.zip 454 | -------------------------------------------------------------------------------- /data/patterns/base_patterns.txt: -------------------------------------------------------------------------------- 1 | # Nginx specific paths and files 2 | nginx.conf 3 | .nginx 4 | nginx_status 5 | nginx.pid 6 | nginx.access 7 | nginx.error 8 | nginx.log 9 | nginx.cache 10 | proxy.conf 11 | vhost.conf 12 | sites-enabled 13 | sites-available 14 | conf.d 15 | fastcgi.conf 16 | fastcgi_params 17 | mime.types 18 | nginx_temp 19 | nginx.bak 20 | nginx.old 21 | nginx.debug 22 | nginx.test 23 | nginx.local 24 | nginx.dev 25 | nginx.prod 26 | nginx.staging 27 | nginx.backup 28 | nginx.master 29 | nginx.worker 30 | nginx.default 31 | nginx.template 32 | nginx.original 33 | nginx.save 34 | nginx.copy 35 | nginx.conf~ 36 | nginx.conf.bak 37 | nginx.conf.old 38 | nginx.conf.orig 39 | nginx.conf.rpmsave 40 | nginx.conf.rpmnew 41 | nginx.conf.swp 42 | nginx.conf.default 43 | nginx.conf.template 44 | nginx.conf.sample 45 | nginx.conf.example 46 | nginx.conf.local 47 | nginx.conf.dev 48 | nginx.conf.prod 49 | nginx.conf.staging 50 | nginx.conf.backup 51 | nginx.conf.master 52 | nginx.conf.worker 53 | nginx.conf.debug 54 | nginx.conf.test 55 | nginx.conf.save 56 | nginx.conf.copy 57 | nginx/conf 58 | nginx/logs 59 | nginx/temp 60 | nginx/cache 61 | nginx/run 62 | nginx/html 63 | nginx/www 64 | nginx/backup 65 | nginx/sites 66 | nginx/vhosts 67 | nginx/ssl 68 | nginx/certs 69 | nginx/modules 70 | nginx/scripts 71 | nginx/proxy 72 | 73 | # Admin panels 74 | admin 75 | administrator 76 | admincp 77 | admins 78 | administrador 79 | adm 80 | backend 81 | backoffice 82 | control 83 | cpanel 84 | manage 85 | management 86 | manager 87 | portal 88 | webadmin 89 | sysadmin 90 | admin-console 91 | admin-panel 92 | admin-area 93 | admin-login 94 | admin-interface 95 | admin-dashboard 96 | admin-center 97 | admin-cp 98 | admin_area 99 | admin_login 100 | admin_console 101 | admin_panel 102 | adminarea 103 | adminlogin 104 | adminconsole 105 | adminpanel 106 | administration 107 | administrative 108 | administrator-login 109 | administrator-panel 110 | administrator-console 111 | administrator-area 112 | administrador-login 113 | administrador-panel 114 | administrador-console 115 | 116 | # Common web files 117 | index.php 118 | index.html 119 | index.htm 120 | index.asp 121 | index.aspx 122 | index.jsp 123 | index.do 124 | index.action 125 | index.cfm 126 | index.rb 127 | index.py 128 | index.pl 129 | index.cgi 130 | index.shtml 131 | index.jspx 132 | default.php 133 | default.html 134 | default.htm 135 | default.asp 136 | home.php 137 | home.html 138 | home.htm 139 | home.asp 140 | home.aspx 141 | main.php 142 | main.html 143 | main.htm 144 | main.asp 145 | main.aspx 146 | 147 | # Development and debug 148 | dev 149 | development 150 | test 151 | testing 152 | staging 153 | beta 154 | debug 155 | demo 156 | example 157 | sample 158 | temp 159 | tmp 160 | backup 161 | bak 162 | dev-admin 163 | dev-console 164 | dev-panel 165 | dev-login 166 | dev-api 167 | test-admin 168 | test-console 169 | test-panel 170 | test-login 171 | test-api 172 | staging-admin 173 | staging-console 174 | staging-panel 175 | staging-login 176 | beta-admin 177 | beta-console 178 | beta-panel 179 | beta-login 180 | beta-api 181 | debug-console 182 | debug-panel 183 | debug-log 184 | debug-info 185 | demo-admin 186 | demo-console 187 | demo-panel 188 | demo-login 189 | demo-api 190 | 191 | # Log files 192 | log 193 | logs 194 | error_log 195 | error.log 196 | access_log 197 | access.log 198 | debug_log 199 | debug.log 200 | app.log 201 | application.log 202 | web.log 203 | server.log 204 | event.log 205 | system.log 206 | security.log 207 | admin.log 208 | php_error.log 209 | php-error.log 210 | php_errors.log 211 | php-errors.log 212 | error-log 213 | error_logs 214 | error-logs 215 | errorlog 216 | error.logs 217 | log/error 218 | log/access 219 | log/debug 220 | log/app 221 | log/web 222 | logs/error 223 | logs/access 224 | logs/debug 225 | logs/app 226 | logs/web 227 | var/log 228 | var/logs 229 | var/log/nginx 230 | var/log/apache 231 | var/log/httpd 232 | var/log/apache2 233 | var/log/php 234 | var/log/mysql 235 | 236 | # Backup files 237 | backup 238 | backups 239 | bak 240 | old 241 | save 242 | saved 243 | temp 244 | tmp 245 | backup_db 246 | backup-db 247 | db_backup 248 | db-backup 249 | mysql_backup 250 | sql_backup 251 | database_backup 252 | site_backup 253 | web_backup 254 | backup_files 255 | backup-files 256 | files_backup 257 | files-backup 258 | backup_config 259 | backup-config 260 | config_backup 261 | config-backup 262 | backup_system 263 | backup-system 264 | system_backup 265 | system-backup 266 | backup.sql 267 | backup.gz 268 | backup.tar 269 | backup.zip 270 | backup.7z 271 | backup.tar.gz 272 | backup.tar.bz2 273 | backup.tgz 274 | backup.tbz2 275 | 276 | # Configuration files 277 | config 278 | conf 279 | settings 280 | setup 281 | install 282 | configuration 283 | configure 284 | env 285 | environment 286 | .env 287 | .git 288 | .svn 289 | .htaccess 290 | web.config 291 | robots.txt 292 | sitemap.xml 293 | crossdomain.xml 294 | config.php 295 | config.inc.php 296 | config.inc 297 | config.ini 298 | config.json 299 | config.yml 300 | config.yaml 301 | config.xml 302 | config.js 303 | config.conf 304 | config.local 305 | config.dev 306 | config.prod 307 | config.staging 308 | config.test 309 | config.debug 310 | config.default 311 | config.template 312 | config.sample 313 | config.example 314 | config.bak 315 | config.old 316 | config.orig 317 | config.backup 318 | settings.php 319 | settings.inc.php 320 | settings.ini 321 | settings.json 322 | settings.yml 323 | settings.yaml 324 | settings.xml 325 | settings.js 326 | settings.conf 327 | settings.local 328 | settings.dev 329 | settings.prod 330 | 331 | # API endpoints 332 | api 333 | api/v1 334 | api/v2 335 | api/v3 336 | api/v4 337 | api/v5 338 | api/latest 339 | api/beta 340 | api/alpha 341 | api/test 342 | api/dev 343 | api/staging 344 | api/prod 345 | api/docs 346 | api/swagger 347 | api/graphql 348 | api/rest 349 | api/soap 350 | api/json 351 | api/xml 352 | api/rpc 353 | api/internal 354 | api/external 355 | api/public 356 | api/private 357 | api/open 358 | api/secure 359 | api/auth 360 | api/oauth 361 | api/jwt 362 | 363 | # Security and authentication 364 | login 365 | logout 366 | signin 367 | signout 368 | register 369 | signup 370 | password 371 | passwd 372 | forgot-password 373 | reset-password 374 | change-password 375 | update-password 376 | password-reset 377 | auth 378 | authentication 379 | authorize 380 | authorization 381 | oauth 382 | oauth2 383 | openid 384 | saml 385 | sso 386 | security 387 | login.php 388 | login.asp 389 | login.jsp 390 | login.html 391 | login.htm 392 | admin-login 393 | user-login 394 | member-login 395 | customer-login 396 | 397 | # Database related 398 | phpmyadmin 399 | phpMyAdmin 400 | myadmin 401 | mysql 402 | sql 403 | database 404 | db 405 | dbadmin 406 | web/phpMyAdmin 407 | mysql/admin 408 | mysql/db 409 | mysqladmin 410 | mysql-admin 411 | mysql_admin 412 | sqlweb 413 | webdb 414 | websql 415 | webadmin 416 | sqladmin 417 | sql-admin 418 | db-admin 419 | database-admin 420 | dbmanager 421 | db-manager 422 | sql-manager 423 | 424 | # Server information 425 | server-status 426 | server-info 427 | status 428 | stats 429 | statistics 430 | info 431 | phpinfo.php 432 | php_info.php 433 | info.php 434 | test.php 435 | probe.php 436 | status.php 437 | monitor 438 | monitoring 439 | health 440 | healthcheck 441 | health-check 442 | ping 443 | server 444 | host 445 | system 446 | sysinfo 447 | sys-info 448 | serverinfo 449 | server-info 450 | 451 | # Common frameworks and CMS 452 | wp-admin 453 | wp-login 454 | wp-config 455 | wp-content 456 | wp-includes 457 | wordpress 458 | wp 459 | blog 460 | joomla 461 | administrator 462 | drupal 463 | magento 464 | laravel 465 | symfony 466 | django 467 | flask 468 | rails 469 | spring 470 | struts 471 | node 472 | angular 473 | react 474 | vue 475 | cms 476 | portal 477 | site 478 | web 479 | app 480 | application 481 | -------------------------------------------------------------------------------- /phantomfuzzer/utils/logging.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Custom logging setup for PhantomFuzzer. 6 | 7 | This module provides a customized logging setup with colored output, 8 | configurable log levels, and file output capabilities. 9 | """ 10 | 11 | import os 12 | import sys 13 | import logging 14 | import datetime 15 | from typing import Optional, Dict, Any, Union 16 | from pathlib import Path 17 | 18 | # Try to import colorama for cross-platform colored terminal output 19 | try: 20 | import colorama 21 | from colorama import Fore, Back, Style 22 | colorama.init(autoreset=True) 23 | COLORS_AVAILABLE = True 24 | except ImportError: 25 | COLORS_AVAILABLE = False 26 | # Define dummy color constants if colorama is not available 27 | class DummyColor: 28 | def __getattr__(self, name): 29 | return '' 30 | Fore = DummyColor() 31 | Back = DummyColor() 32 | Style = DummyColor() 33 | 34 | # Log level mapping 35 | LOG_LEVELS = { 36 | 'DEBUG': logging.DEBUG, 37 | 'INFO': logging.INFO, 38 | 'WARNING': logging.WARNING, 39 | 'ERROR': logging.ERROR, 40 | 'CRITICAL': logging.CRITICAL 41 | } 42 | 43 | # Default log format 44 | DEFAULT_LOG_FORMAT = '%(asctime)s - %(name)s - %(levelname)s - %(message)s' 45 | 46 | # Colored log format 47 | COLORED_LOG_FORMAT = { 48 | 'DEBUG': f'{Fore.CYAN}%(asctime)s - %(name)s - %(levelname)s - %(message)s{Style.RESET_ALL}', 49 | 'INFO': f'{Fore.GREEN}%(asctime)s - %(name)s - %(levelname)s - %(message)s{Style.RESET_ALL}', 50 | 'WARNING': f'{Fore.YELLOW}%(asctime)s - %(name)s - %(levelname)s - %(message)s{Style.RESET_ALL}', 51 | 'ERROR': f'{Fore.RED}%(asctime)s - %(name)s - %(levelname)s - %(message)s{Style.RESET_ALL}', 52 | 'CRITICAL': f'{Back.RED}{Fore.WHITE}%(asctime)s - %(name)s - %(levelname)s - %(message)s{Style.RESET_ALL}' 53 | } 54 | 55 | class ColoredFormatter(logging.Formatter): 56 | """Custom formatter for colored log output.""" 57 | 58 | def format(self, record): 59 | log_format = COLORED_LOG_FORMAT.get(record.levelname, DEFAULT_LOG_FORMAT) if COLORS_AVAILABLE else DEFAULT_LOG_FORMAT 60 | formatter = logging.Formatter(log_format) 61 | return formatter.format(record) 62 | 63 | def get_logger(name: str, log_level: str = 'INFO', log_file: Optional[str] = None, use_colors: bool = True) -> logging.Logger: 64 | """Get a configured logger instance. 65 | 66 | Args: 67 | name: The name of the logger. 68 | log_level: The log level to use. Must be one of 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'. 69 | log_file: Optional path to a log file. If provided, logs will be written to this file. 70 | use_colors: Whether to use colored output. Only applicable to console output. 71 | 72 | Returns: 73 | A configured logger instance. 74 | """ 75 | # Convert log level string to logging constant 76 | level = LOG_LEVELS.get(log_level.upper(), logging.INFO) 77 | 78 | # Get or create logger 79 | logger = logging.getLogger(name) 80 | logger.setLevel(level) 81 | 82 | # Remove existing handlers to avoid duplicates 83 | for handler in logger.handlers[:]: # Make a copy of the list 84 | logger.removeHandler(handler) 85 | 86 | # Create console handler 87 | console_handler = logging.StreamHandler(sys.stdout) 88 | console_handler.setLevel(level) 89 | 90 | # Set formatter based on color preference 91 | if use_colors and COLORS_AVAILABLE: 92 | console_formatter = ColoredFormatter() 93 | else: 94 | console_formatter = logging.Formatter(DEFAULT_LOG_FORMAT) 95 | 96 | console_handler.setFormatter(console_formatter) 97 | logger.addHandler(console_handler) 98 | 99 | # Add file handler if log_file is provided 100 | if log_file: 101 | # Ensure the directory exists 102 | log_dir = os.path.dirname(log_file) 103 | if log_dir and not os.path.exists(log_dir): 104 | os.makedirs(log_dir) 105 | 106 | file_handler = logging.FileHandler(log_file) 107 | file_handler.setLevel(level) 108 | file_formatter = logging.Formatter(DEFAULT_LOG_FORMAT) 109 | file_handler.setFormatter(file_formatter) 110 | logger.addHandler(file_handler) 111 | 112 | return logger 113 | 114 | def setup_logging(config: Dict[str, Any] = None) -> logging.Logger: 115 | """Set up logging based on configuration. 116 | 117 | Args: 118 | config: Configuration dictionary. If None, default values will be used. 119 | 120 | Returns: 121 | The root logger instance. 122 | """ 123 | if config is None: 124 | config = {} 125 | 126 | # Get configuration values with defaults 127 | log_level = config.get('log_level', 'INFO') 128 | log_file = config.get('log_file', None) 129 | use_colors = config.get('use_colors', True) 130 | 131 | # Set up the root logger 132 | root_logger = get_logger('phantomfuzzer', log_level, log_file, use_colors) 133 | 134 | # Configure the logging module's root logger 135 | logging.root = root_logger 136 | 137 | return root_logger 138 | 139 | def get_module_logger(module_name: str) -> logging.Logger: 140 | """Get a logger for a specific module. 141 | 142 | This is a convenience function for getting a logger with the module's name. 143 | The logger will inherit settings from the root logger. 144 | 145 | Args: 146 | module_name: The name of the module. 147 | 148 | Returns: 149 | A logger instance for the module. 150 | """ 151 | return logging.getLogger(f'phantomfuzzer.{module_name}') 152 | 153 | # Helper functions for common log messages 154 | 155 | def log_start_operation(logger: logging.Logger, operation: str) -> None: 156 | """Log the start of an operation. 157 | 158 | Args: 159 | logger: The logger to use. 160 | operation: The name of the operation. 161 | """ 162 | logger.info(f"Starting operation: {operation}") 163 | 164 | def log_end_operation(logger: logging.Logger, operation: str, success: bool = True) -> None: 165 | """Log the end of an operation. 166 | 167 | Args: 168 | logger: The logger to use. 169 | operation: The name of the operation. 170 | success: Whether the operation was successful. 171 | """ 172 | if success: 173 | logger.info(f"Operation completed successfully: {operation}") 174 | else: 175 | logger.error(f"Operation failed: {operation}") 176 | 177 | def log_scan_result(logger: logging.Logger, target: str, vulnerabilities: int) -> None: 178 | """Log the result of a scan. 179 | 180 | Args: 181 | logger: The logger to use. 182 | target: The target of the scan. 183 | vulnerabilities: The number of vulnerabilities found. 184 | """ 185 | if vulnerabilities > 0: 186 | logger.warning(f"Scan of {target} found {vulnerabilities} vulnerabilities") 187 | else: 188 | logger.info(f"Scan of {target} completed with no vulnerabilities found") 189 | 190 | # Initialize a default logger 191 | default_logger = get_logger('phantomfuzzer') 192 | 193 | def setup_logger(name: str, log_level: str = 'INFO', log_file: Optional[str] = None, use_colors: bool = True) -> logging.Logger: 194 | """ 195 | Set up a logger with a specific name and configuration. 196 | 197 | This is a convenience function for setting up a logger with common settings. 198 | 199 | Args: 200 | name: The name of the logger. 201 | log_level: The log level to use. Must be one of 'DEBUG', 'INFO', 'WARNING', 'ERROR', 'CRITICAL'. 202 | log_file: Optional path to a log file. If provided, logs will be written to this file. 203 | use_colors: Whether to use colored output. Only applicable to console output. 204 | 205 | Returns: 206 | A configured logger instance. 207 | """ 208 | return get_logger(name, log_level, log_file, use_colors) -------------------------------------------------------------------------------- /examples/pattern_recognizer_with_db_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Example script demonstrating the integration of PatternRecognizer with PatternDatabase. 6 | 7 | This script shows how to: 8 | 1. Initialize a PatternRecognizer with a PatternDatabase 9 | 2. Train the model with sample data 10 | 3. Use both ML-based predictions and pattern matching 11 | 4. Discover and store new patterns automatically 12 | 5. Export and import patterns for reuse 13 | """ 14 | 15 | import os 16 | import sys 17 | import argparse 18 | from pathlib import Path 19 | from datetime import datetime 20 | from typing import List, Dict, Any, Optional, Union, Tuple 21 | 22 | # Add project root to path if needed 23 | sys.path.insert(0, str(Path(__file__).parent.parent)) 24 | 25 | # Import PhantomFuzzer ML components 26 | from phantomfuzzer.ml import PatternRecognizer, PatternDatabase 27 | 28 | 29 | def setup_argparse(): 30 | """Set up command line argument parsing.""" 31 | parser = argparse.ArgumentParser( 32 | description='PhantomFuzzer PatternRecognizer with PatternDatabase Example' 33 | ) 34 | 35 | parser.add_argument('--train', action='store_true', 36 | help='Train a new model') 37 | parser.add_argument('--train-dir', type=str, default='data/benign', 38 | help='Directory with benign files for training') 39 | parser.add_argument('--analyze', action='store_true', 40 | help='Analyze files for anomalies') 41 | parser.add_argument('--analyze-dir', type=str, default='data/test', 42 | help='Directory with files to analyze') 43 | parser.add_argument('--model-path', type=str, default='models/pattern_recognizer.pkl', 44 | help='Path to save/load the model') 45 | parser.add_argument('--pattern-db-path', type=str, default='data/patterns/patterns.json', 46 | help='Path to the pattern database file') 47 | parser.add_argument('--import-patterns', type=str, 48 | help='Import patterns from the specified file') 49 | parser.add_argument('--export-patterns', type=str, 50 | help='Export patterns to the specified file') 51 | 52 | return parser.parse_args() 53 | 54 | 55 | def initialize_components(args): 56 | """Initialize the PatternRecognizer and PatternDatabase components. 57 | 58 | Args: 59 | args: Command line arguments. 60 | 61 | Returns: 62 | Tuple of (PatternRecognizer, PatternDatabase). 63 | """ 64 | # Create pattern database 65 | pattern_db = PatternDatabase( 66 | db_path=args.pattern_db_path, 67 | config={ 68 | 'auto_save': True, 69 | 'similarity_threshold': 0.7 70 | } 71 | ) 72 | 73 | # Import patterns if specified 74 | if args.import_patterns: 75 | print(f"Importing patterns from {args.import_patterns}") 76 | pattern_db.import_patterns(args.import_patterns) 77 | 78 | # Create pattern recognizer with the pattern database 79 | recognizer = PatternRecognizer( 80 | config={ 81 | 'n_estimators': 100, 82 | 'contamination': 0.1, 83 | 'pattern_match_threshold': 0.7, 84 | 'pattern_weight': 0.3 # Weight for pattern matching vs ML model 85 | }, 86 | pattern_db=pattern_db 87 | ) 88 | 89 | # Load existing model if available and not training 90 | if not args.train and os.path.exists(args.model_path): 91 | print(f"Loading model from {args.model_path}") 92 | recognizer.load_model(args.model_path) 93 | 94 | return recognizer, pattern_db 95 | 96 | 97 | def train_model(recognizer, args): 98 | """Train the PatternRecognizer model with sample data. 99 | 100 | Args: 101 | recognizer: PatternRecognizer instance. 102 | args: Command line arguments. 103 | """ 104 | train_dir = Path(args.train_dir) 105 | if not train_dir.exists(): 106 | print(f"Training directory {train_dir} does not exist") 107 | return 108 | 109 | # Get list of files for training 110 | file_paths = [] 111 | for root, _, files in os.walk(train_dir): 112 | for file in files: 113 | file_paths.append(os.path.join(root, file)) 114 | 115 | if not file_paths: 116 | print(f"No files found in {train_dir}") 117 | return 118 | 119 | print(f"Training model with {len(file_paths)} files from {train_dir}") 120 | recognizer.train(file_paths) 121 | 122 | # Save the trained model 123 | model_dir = os.path.dirname(args.model_path) 124 | if model_dir and not os.path.exists(model_dir): 125 | os.makedirs(model_dir) 126 | 127 | recognizer.save_model(args.model_path) 128 | print(f"Model saved to {args.model_path}") 129 | 130 | 131 | def analyze_files(recognizer, args): 132 | """Analyze files for anomalies using both ML and pattern matching. 133 | 134 | Args: 135 | recognizer: PatternRecognizer instance. 136 | args: Command line arguments. 137 | """ 138 | analyze_dir = Path(args.analyze_dir) 139 | if not analyze_dir.exists(): 140 | print(f"Analysis directory {analyze_dir} does not exist") 141 | return 142 | 143 | # Get list of files to analyze 144 | file_paths = [] 145 | for root, _, files in os.walk(analyze_dir): 146 | for file in files: 147 | file_paths.append(os.path.join(root, file)) 148 | 149 | if not file_paths: 150 | print(f"No files found in {analyze_dir}") 151 | return 152 | 153 | print(f"Analyzing {len(file_paths)} files from {analyze_dir}") 154 | 155 | # Analyze each file 156 | for file_path in file_paths: 157 | is_anomaly, score, details = recognizer.predict(file_path) 158 | 159 | # Print results 160 | print(f"\nFile: {file_path}") 161 | print(f" Is Anomaly: {is_anomaly}") 162 | print(f" Anomaly Score: {score:.4f}") 163 | 164 | # Print ML model details if available 165 | if recognizer.model is not None: 166 | print(f" ML Model Prediction: {'Anomaly' if details['ml_is_anomaly'] else 'Normal'}") 167 | print(f" ML Score: {details['ml_score']:.4f}") 168 | 169 | # Print pattern matching details 170 | print(f" Pattern Match: {'Yes' if details['pattern_is_match'] else 'No'}") 171 | if details['pattern_is_match']: 172 | print(f" Pattern Confidence: {details['pattern_confidence']:.4f}") 173 | print(f" Matched Pattern: {details['pattern_info']['pattern']}") 174 | 175 | # Print if a new pattern was discovered 176 | if 'discovered_pattern_id' in details: 177 | print(f" New Pattern Discovered: {details['discovered_pattern_id']}") 178 | 179 | 180 | def export_patterns(pattern_db, args): 181 | """Export patterns to a file. 182 | 183 | Args: 184 | pattern_db: PatternDatabase instance. 185 | args: Command line arguments. 186 | """ 187 | if args.export_patterns: 188 | print(f"Exporting patterns to {args.export_patterns}") 189 | pattern_db.export_patterns(args.export_patterns) 190 | print(f"Exported {len(pattern_db.patterns)} patterns") 191 | 192 | 193 | def main(): 194 | """Main function.""" 195 | args = setup_argparse() 196 | 197 | # Initialize components 198 | recognizer, pattern_db = initialize_components(args) 199 | 200 | # Train model if requested 201 | if args.train: 202 | train_model(recognizer, args) 203 | 204 | # Analyze files if requested 205 | if args.analyze: 206 | analyze_files(recognizer, args) 207 | 208 | # Export patterns if requested 209 | if args.export_patterns: 210 | export_patterns(pattern_db, args) 211 | 212 | # Print pattern database statistics 213 | print(f"\nPattern Database Statistics:") 214 | print(f" Total Patterns: {len(pattern_db.patterns)}") 215 | print(f" Database Path: {pattern_db.db_path}") 216 | 217 | 218 | if __name__ == "__main__": 219 | main() 220 | -------------------------------------------------------------------------------- /phantomfuzzer/fuzzer/fuzzer_base.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Base Fuzzer Class for PhantomFuzzer. 6 | 7 | This module provides the foundation for all fuzzer types in the PhantomFuzzer project, 8 | including common functionality for configuration, logging, and result tracking. 9 | """ 10 | 11 | import os 12 | import time 13 | import random 14 | import uuid 15 | from pathlib import Path 16 | from typing import Dict, List, Tuple, Union, Optional, Any, Callable 17 | from abc import ABC, abstractmethod 18 | 19 | # Local imports 20 | from phantomfuzzer.utils.logging import get_logger 21 | 22 | 23 | class BaseFuzzer(ABC): 24 | """Base class for all fuzzer implementations. 25 | 26 | This abstract class defines the common interface and functionality for all 27 | fuzzer types in the PhantomFuzzer project. Specialized fuzzers should inherit 28 | from this class and implement the required abstract methods. 29 | """ 30 | 31 | def __init__(self, config: Optional[Dict[str, Any]] = None): 32 | """Initialize the base fuzzer. 33 | 34 | Args: 35 | config: Configuration parameters for the fuzzer. 36 | """ 37 | self.logger = get_logger(__name__) 38 | self.config = config or {} 39 | 40 | # Default configuration 41 | self.target = self.config.get('target', None) 42 | self.timeout = self.config.get('timeout', 30) # Default timeout in seconds 43 | self.max_retries = self.config.get('max_retries', 3) 44 | self.delay_between_requests = self.config.get('delay', 0.5) # Default delay in seconds 45 | self.random_delay = self.config.get('random_delay', False) 46 | self.min_delay = self.config.get('min_delay', 0.1) 47 | self.max_delay = self.config.get('max_delay', 2.0) 48 | 49 | # Fuzzing parameters 50 | self.fuzz_iterations = self.config.get('iterations', 100) 51 | self.fuzz_seed = self.config.get('seed', None) 52 | if self.fuzz_seed is not None: 53 | random.seed(self.fuzz_seed) 54 | 55 | # Result tracking 56 | self.results = [] 57 | self.session_id = str(uuid.uuid4()) 58 | self.start_time = None 59 | self.end_time = None 60 | 61 | self.logger.info(f"Initialized {self.__class__.__name__} with session ID: {self.session_id}") 62 | 63 | def set_target(self, target: str) -> None: 64 | """Set the target for fuzzing. 65 | 66 | Args: 67 | target: Target to fuzz (URL, API endpoint, etc.) 68 | """ 69 | self.target = target 70 | self.logger.info(f"Target set to: {target}") 71 | 72 | def get_delay(self) -> float: 73 | """Get the delay to use between requests. 74 | 75 | Returns: 76 | Delay in seconds. 77 | """ 78 | if self.random_delay: 79 | return random.uniform(self.min_delay, self.max_delay) 80 | return self.delay_between_requests 81 | 82 | @abstractmethod 83 | def generate_fuzz_data(self) -> Any: 84 | """Generate data for fuzzing. 85 | 86 | This method should be implemented by subclasses to generate 87 | appropriate fuzzing data for the specific fuzzer type. 88 | 89 | Returns: 90 | Data to use for fuzzing. 91 | """ 92 | pass 93 | 94 | @abstractmethod 95 | def execute_fuzz(self, fuzz_data: Any) -> Dict[str, Any]: 96 | """Execute a single fuzzing operation. 97 | 98 | This method should be implemented by subclasses to perform 99 | the actual fuzzing operation with the provided data. 100 | 101 | Args: 102 | fuzz_data: Data to use for fuzzing. 103 | 104 | Returns: 105 | Dictionary with results of the fuzzing operation. 106 | """ 107 | pass 108 | 109 | def track_result(self, result: Dict[str, Any]) -> None: 110 | """Track a fuzzing result. 111 | 112 | Args: 113 | result: Result of a fuzzing operation. 114 | """ 115 | self.results.append(result) 116 | 117 | def run(self, iterations: Optional[int] = None) -> List[Dict[str, Any]]: 118 | """Run the fuzzer for the specified number of iterations. 119 | 120 | Args: 121 | iterations: Number of fuzzing iterations to perform. 122 | If None, use the value from config. 123 | 124 | Returns: 125 | List of results from all fuzzing operations. 126 | """ 127 | if self.target is None: 128 | self.logger.error("No target specified. Call set_target() first.") 129 | return [] 130 | 131 | iterations = iterations or self.fuzz_iterations 132 | self.logger.info(f"Starting fuzzing session with {iterations} iterations") 133 | 134 | self.start_time = time.time() 135 | self.results = [] 136 | 137 | try: 138 | for i in range(iterations): 139 | self.logger.debug(f"Fuzzing iteration {i+1}/{iterations}") 140 | 141 | # Generate fuzz data 142 | fuzz_data = self.generate_fuzz_data() 143 | 144 | # Execute fuzzing 145 | result = self.execute_fuzz(fuzz_data) 146 | 147 | # Track result 148 | self.track_result(result) 149 | 150 | # Apply delay between requests 151 | if i < iterations - 1: # No need to delay after the last iteration 152 | time.sleep(self.get_delay()) 153 | 154 | except KeyboardInterrupt: 155 | self.logger.info("Fuzzing interrupted by user") 156 | except Exception as e: 157 | self.logger.error(f"Error during fuzzing: {str(e)}") 158 | 159 | self.end_time = time.time() 160 | duration = self.end_time - self.start_time 161 | self.logger.info(f"Fuzzing session completed in {duration:.2f} seconds") 162 | 163 | return self.results 164 | 165 | def get_summary(self) -> Dict[str, Any]: 166 | """Get a summary of the fuzzing session. 167 | 168 | Returns: 169 | Dictionary with summary information. 170 | """ 171 | if not self.start_time or not self.end_time: 172 | return { 173 | 'session_id': self.session_id, 174 | 'status': 'Not run', 175 | 'iterations': 0, 176 | 'duration': 0, 177 | 'results': [] 178 | } 179 | 180 | return { 181 | 'session_id': self.session_id, 182 | 'status': 'Completed', 183 | 'target': self.target, 184 | 'iterations': len(self.results), 185 | 'duration': self.end_time - self.start_time, 186 | 'start_time': self.start_time, 187 | 'end_time': self.end_time, 188 | 'results': self.results 189 | } 190 | 191 | def save_results(self, output_path: Union[str, Path]) -> bool: 192 | """Save fuzzing results to a file. 193 | 194 | Args: 195 | output_path: Path to save results to. 196 | 197 | Returns: 198 | True if successful, False otherwise. 199 | """ 200 | import json 201 | 202 | try: 203 | output_path = Path(output_path) 204 | 205 | # Create directory if it doesn't exist 206 | output_dir = output_path.parent 207 | if not output_dir.exists(): 208 | output_dir.mkdir(parents=True) 209 | 210 | # Save summary as JSON 211 | with open(output_path, 'w') as f: 212 | json.dump(self.get_summary(), f, indent=2) 213 | 214 | self.logger.info(f"Results saved to {output_path}") 215 | return True 216 | 217 | except Exception as e: 218 | self.logger.error(f"Error saving results: {str(e)}") 219 | return False -------------------------------------------------------------------------------- /examples/ml_scanner_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Example script demonstrating the use of the ML-enhanced scanner in PhantomFuzzer. 6 | 7 | This script shows how to: 8 | 1. Initialize the ML-enhanced scanner 9 | 2. Scan files and directories with ML capabilities 10 | 3. Interpret the scan results 11 | 4. Train a model based on scan results 12 | """ 13 | 14 | import os 15 | import sys 16 | import argparse 17 | import json 18 | from pathlib import Path 19 | 20 | # Add project root to path if needed 21 | sys.path.insert(0, str(Path(__file__).parent.parent)) 22 | 23 | # Import PhantomFuzzer components 24 | from phantomfuzzer.scanner import MLEnhancedScanner 25 | from phantomfuzzer.scanner import SEVERITY_CRITICAL, SEVERITY_HIGH, SEVERITY_MEDIUM, SEVERITY_LOW, SEVERITY_INFO 26 | 27 | 28 | def setup_argparse(): 29 | """Set up command line argument parsing.""" 30 | parser = argparse.ArgumentParser(description='PhantomFuzzer ML-Enhanced Scanner Example') 31 | 32 | parser.add_argument('--target-dir', type=str, default=None, 33 | help='Directory containing files to scan') 34 | parser.add_argument('--target-file', type=str, default=None, 35 | help='Single file to scan') 36 | 37 | parser.add_argument('--ml-enabled', action='store_true', default=True, 38 | help='Enable ML-based scanning (default: True)') 39 | parser.add_argument('--ml-model', type=str, default=None, 40 | help='Specific ML model to use') 41 | parser.add_argument('--ml-threshold', type=float, default=0.6, 42 | help='Threshold for ML anomaly detection (default: 0.6)') 43 | 44 | parser.add_argument('--output', type=str, default=None, 45 | help='Output file for scan results (JSON format)') 46 | 47 | parser.add_argument('--train-from-results', action='store_true', 48 | help='Train a new model from scan results') 49 | parser.add_argument('--new-model-name', type=str, default=None, 50 | help='Name for the newly trained model') 51 | 52 | return parser 53 | 54 | 55 | def initialize_scanner(args): 56 | """Initialize the ML-enhanced scanner with the specified configuration.""" 57 | # Create scanner configuration 58 | config = { 59 | 'ml_enabled': args.ml_enabled, 60 | 'ml_model_name': args.ml_model, 61 | 'ml_threshold': args.ml_threshold, 62 | 'max_file_size': 10 * 1024 * 1024, # 10 MB 63 | 'scan_archives': True, 64 | 'extract_metadata': True 65 | } 66 | 67 | # Initialize scanner 68 | scanner = MLEnhancedScanner(config) 69 | print("ML-Enhanced Scanner initialized") 70 | 71 | if args.ml_enabled: 72 | print(f"ML scanning enabled with threshold: {args.ml_threshold}") 73 | if args.ml_model: 74 | print(f"Using ML model: {args.ml_model}") 75 | else: 76 | print(f"Using default ML model: {scanner.ml_integration.default_model if scanner.ml_integration else 'None'}") 77 | 78 | return scanner 79 | 80 | 81 | def scan_target(scanner, args): 82 | """Scan the specified target (file or directory).""" 83 | target = args.target_file or args.target_dir 84 | if not target: 85 | print("Error: No target specified. Use --target-file or --target-dir") 86 | return None 87 | 88 | print(f"Scanning target: {target}") 89 | 90 | # Set up scan options 91 | options = { 92 | 'recursive': True, 93 | 'file_pattern': '*' 94 | } 95 | 96 | # Perform scan 97 | scan_result = scanner.scan(target, options) 98 | 99 | return scan_result 100 | 101 | 102 | def print_scan_summary(scan_result): 103 | """Print a summary of the scan results.""" 104 | if not scan_result: 105 | print("No scan results available") 106 | return 107 | 108 | print("\nScan Summary:") 109 | print(f"Target: {scan_result.target}") 110 | print(f"Status: {scan_result.status}") 111 | print(f"Start Time: {scan_result.start_time}") 112 | print(f"End Time: {scan_result.end_time}") 113 | print(f"Duration: {(scan_result.end_time - scan_result.start_time).total_seconds():.2f} seconds") 114 | 115 | # Print scan info 116 | if hasattr(scan_result, 'scan_info'): 117 | print("\nScan Information:") 118 | print(f"Files Scanned: {scan_result.scan_info.get('files_scanned', 0)}") 119 | print(f"Files Skipped: {scan_result.scan_info.get('files_skipped', 0)}") 120 | print(f"Total Size: {scan_result.scan_info.get('total_size', 0) / 1024 / 1024:.2f} MB") 121 | 122 | # Print vulnerabilities 123 | if hasattr(scan_result, 'vulnerabilities'): 124 | vuln_count = len(scan_result.vulnerabilities) 125 | print(f"\nVulnerabilities Found: {vuln_count}") 126 | 127 | if vuln_count > 0: 128 | # Count vulnerabilities by severity 129 | severity_counts = { 130 | SEVERITY_CRITICAL: 0, 131 | SEVERITY_HIGH: 0, 132 | SEVERITY_MEDIUM: 0, 133 | SEVERITY_LOW: 0, 134 | SEVERITY_INFO: 0 135 | } 136 | 137 | # Count vulnerabilities by type 138 | type_counts = {} 139 | 140 | for vuln in scan_result.vulnerabilities: 141 | severity = vuln.get('severity', SEVERITY_INFO) 142 | severity_counts[severity] = severity_counts.get(severity, 0) + 1 143 | 144 | vuln_type = vuln.get('name', 'Unknown') 145 | type_counts[vuln_type] = type_counts.get(vuln_type, 0) + 1 146 | 147 | # Print severity breakdown 148 | print("\nSeverity Breakdown:") 149 | for severity, count in severity_counts.items(): 150 | if count > 0: 151 | print(f" {severity.capitalize()}: {count}") 152 | 153 | # Print type breakdown 154 | print("\nVulnerability Types:") 155 | for vuln_type, count in type_counts.items(): 156 | print(f" {vuln_type}: {count}") 157 | 158 | # Print ML-specific vulnerabilities 159 | ml_vulns = [v for v in scan_result.vulnerabilities if v.get('name') == 'ML-Detected Anomaly'] 160 | if ml_vulns: 161 | print(f"\nML-Detected Anomalies: {len(ml_vulns)}") 162 | for vuln in ml_vulns[:5]: # Show first 5 163 | print(f" {vuln.get('location')} - Score: {vuln.get('evidence')}") 164 | 165 | if len(ml_vulns) > 5: 166 | print(f" ... and {len(ml_vulns) - 5} more") 167 | 168 | 169 | def save_results(scan_result, output_file): 170 | """Save scan results to a file.""" 171 | if not scan_result: 172 | print("No scan results to save") 173 | return 174 | 175 | try: 176 | scan_result.save_to_file(output_file) 177 | print(f"Scan results saved to {output_file}") 178 | except Exception as e: 179 | print(f"Error saving scan results: {str(e)}") 180 | 181 | 182 | def train_model_from_results(scanner, scan_result, model_name): 183 | """Train a new model from scan results.""" 184 | if not scanner.ml_enabled or not scanner.ml_integration: 185 | print("ML is not enabled or ML integration failed to initialize") 186 | return 187 | 188 | print("Training new model from scan results...") 189 | 190 | # Train model 191 | new_model_name = scanner.train_model_from_scan_results([scan_result], model_name) 192 | 193 | if new_model_name: 194 | print(f"Successfully trained new model: {new_model_name}") 195 | print(f"Set {new_model_name} as the default model") 196 | else: 197 | print("Failed to train new model") 198 | 199 | 200 | def main(): 201 | """Main function.""" 202 | parser = setup_argparse() 203 | args = parser.parse_args() 204 | 205 | # Initialize scanner 206 | scanner = initialize_scanner(args) 207 | 208 | # Scan target 209 | scan_result = scan_target(scanner, args) 210 | 211 | # Print scan summary 212 | print_scan_summary(scan_result) 213 | 214 | # Save results if output file specified 215 | if args.output and scan_result: 216 | save_results(scan_result, args.output) 217 | 218 | # Train model from results if requested 219 | if args.train_from_results and scan_result: 220 | train_model_from_results(scanner, scan_result, args.new_model_name) 221 | 222 | 223 | if __name__ == "__main__": 224 | main() 225 | -------------------------------------------------------------------------------- /phantomfuzzer/fuzzer/protocol_fuzzer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Protocol Fuzzer for PhantomFuzzer. 6 | 7 | This module provides protocol-specific fuzzing capabilities for the PhantomFuzzer project, 8 | including TCP, UDP, HTTP, and other network protocols. 9 | """ 10 | 11 | import socket 12 | import random 13 | import struct 14 | from typing import Dict, List, Tuple, Union, Optional, Any 15 | 16 | # Local imports 17 | from phantomfuzzer.fuzzer.fuzzer_base import BaseFuzzer 18 | 19 | 20 | class ProtocolFuzzer(BaseFuzzer): 21 | """Protocol fuzzer for network protocols. 22 | 23 | This class extends the BaseFuzzer to provide protocol-specific fuzzing 24 | capabilities for various network protocols including TCP, UDP, HTTP, etc. 25 | """ 26 | 27 | def __init__(self, config: Optional[Dict[str, Any]] = None): 28 | """Initialize the protocol fuzzer. 29 | 30 | Args: 31 | config: Configuration parameters for the fuzzer. 32 | """ 33 | super().__init__(config) 34 | 35 | # Protocol-specific configuration 36 | self.protocol = self.config.get('protocol', 'tcp').lower() 37 | self.port = self.config.get('port', 80) 38 | self.data_size_min = self.config.get('data_size_min', 10) 39 | self.data_size_max = self.config.get('data_size_max', 1024) 40 | self.mutation_rate = self.config.get('mutation_rate', 0.1) 41 | self.use_valid_data = self.config.get('use_valid_data', True) 42 | 43 | # Protocol templates 44 | self.protocol_templates = self.config.get('protocol_templates', {}) 45 | 46 | # Socket settings 47 | self.socket = None 48 | self.socket_timeout = self.config.get('socket_timeout', 5.0) 49 | 50 | self.logger.info(f"Initialized ProtocolFuzzer for {self.protocol} protocol") 51 | 52 | def _create_socket(self): 53 | """Create a socket for the specified protocol. 54 | 55 | Returns: 56 | Socket object. 57 | """ 58 | if self.protocol == 'tcp': 59 | return socket.socket(socket.AF_INET, socket.SOCK_STREAM) 60 | elif self.protocol == 'udp': 61 | return socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 62 | else: 63 | self.logger.error(f"Unsupported protocol: {self.protocol}") 64 | return None 65 | 66 | def _get_template_data(self): 67 | """Get template data for the current protocol. 68 | 69 | Returns: 70 | Template data as bytes. 71 | """ 72 | if not self.protocol_templates or self.protocol not in self.protocol_templates: 73 | # Generate random data if no template is available 74 | size = random.randint(self.data_size_min, self.data_size_max) 75 | return bytes([random.randint(0, 255) for _ in range(size)]) 76 | 77 | # Get template data 78 | template = self.protocol_templates[self.protocol] 79 | if isinstance(template, list): 80 | # If multiple templates are available, choose one randomly 81 | template = random.choice(template) 82 | 83 | # Convert to bytes if it's a string 84 | if isinstance(template, str): 85 | return template.encode('utf-8', errors='ignore') 86 | 87 | return template 88 | 89 | def generate_fuzz_data(self) -> bytes: 90 | """Generate data for protocol fuzzing. 91 | 92 | Returns: 93 | Fuzzed data as bytes. 94 | """ 95 | # Get template data 96 | if self.use_valid_data: 97 | data = self._get_template_data() 98 | else: 99 | # Generate completely random data 100 | size = random.randint(self.data_size_min, self.data_size_max) 101 | data = bytes([random.randint(0, 255) for _ in range(size)]) 102 | 103 | # Apply mutations 104 | data = self._mutate_data(data) 105 | 106 | return data 107 | 108 | def _mutate_data(self, data: bytes) -> bytes: 109 | """Apply mutations to the data. 110 | 111 | Args: 112 | data: Original data as bytes. 113 | 114 | Returns: 115 | Mutated data as bytes. 116 | """ 117 | # Convert to bytearray for mutation 118 | data_array = bytearray(data) 119 | 120 | # Determine how many bytes to mutate 121 | num_bytes_to_mutate = max(1, int(len(data_array) * self.mutation_rate)) 122 | 123 | # Randomly select bytes to mutate 124 | for _ in range(num_bytes_to_mutate): 125 | idx = random.randint(0, len(data_array) - 1) 126 | data_array[idx] = random.randint(0, 255) 127 | 128 | return bytes(data_array) 129 | 130 | def execute_fuzz(self, fuzz_data: bytes) -> Dict[str, Any]: 131 | """Execute protocol fuzzing with the provided data. 132 | 133 | Args: 134 | fuzz_data: Data to use for fuzzing. 135 | 136 | Returns: 137 | Dictionary with results of the fuzzing operation. 138 | """ 139 | if not self.target: 140 | self.logger.error("No target specified") 141 | return {'status': 'error', 'message': 'No target specified'} 142 | 143 | result = { 144 | 'target': self.target, 145 | 'port': self.port, 146 | 'protocol': self.protocol, 147 | 'data_size': len(fuzz_data), 148 | 'timestamp': self._get_timestamp(), 149 | 'status': 'unknown', 150 | 'response': None, 151 | 'error': None 152 | } 153 | 154 | try: 155 | # Create socket 156 | self.socket = self._create_socket() 157 | if not self.socket: 158 | result['status'] = 'error' 159 | result['error'] = f"Failed to create socket for protocol: {self.protocol}" 160 | return result 161 | 162 | # Set timeout 163 | self.socket.settimeout(self.socket_timeout) 164 | 165 | # Connect and send data 166 | if self.protocol == 'tcp': 167 | self._execute_tcp_fuzz(fuzz_data, result) 168 | elif self.protocol == 'udp': 169 | self._execute_udp_fuzz(fuzz_data, result) 170 | else: 171 | result['status'] = 'error' 172 | result['error'] = f"Unsupported protocol: {self.protocol}" 173 | 174 | except socket.timeout: 175 | result['status'] = 'timeout' 176 | result['error'] = 'Socket timeout' 177 | except ConnectionRefusedError: 178 | result['status'] = 'refused' 179 | result['error'] = 'Connection refused' 180 | except Exception as e: 181 | result['status'] = 'error' 182 | result['error'] = str(e) 183 | 184 | finally: 185 | # Close socket 186 | if self.socket: 187 | try: 188 | self.socket.close() 189 | except: 190 | pass 191 | self.socket = None 192 | 193 | return result 194 | 195 | def _execute_tcp_fuzz(self, fuzz_data: bytes, result: Dict[str, Any]): 196 | """Execute TCP fuzzing. 197 | 198 | Args: 199 | fuzz_data: Data to use for fuzzing. 200 | result: Result dictionary to update. 201 | """ 202 | # Connect to target 203 | self.socket.connect((self.target, self.port)) 204 | 205 | # Send data 206 | self.socket.sendall(fuzz_data) 207 | 208 | # Receive response 209 | response = b'' 210 | try: 211 | while True: 212 | chunk = self.socket.recv(4096) 213 | if not chunk: 214 | break 215 | response += chunk 216 | except socket.timeout: 217 | # Timeout while receiving is not an error 218 | pass 219 | 220 | # Update result 221 | result['status'] = 'success' 222 | result['response'] = response 223 | result['response_size'] = len(response) 224 | 225 | def _execute_udp_fuzz(self, fuzz_data: bytes, result: Dict[str, Any]): 226 | """Execute UDP fuzzing. 227 | 228 | Args: 229 | fuzz_data: Data to use for fuzzing. 230 | result: Result dictionary to update. 231 | """ 232 | # Send data 233 | self.socket.sendto(fuzz_data, (self.target, self.port)) 234 | 235 | # Receive response 236 | try: 237 | response, addr = self.socket.recvfrom(4096) 238 | 239 | # Update result 240 | result['status'] = 'success' 241 | result['response'] = response 242 | result['response_size'] = len(response) 243 | result['response_addr'] = addr 244 | except socket.timeout: 245 | # Timeout is common for UDP, not necessarily an error 246 | result['status'] = 'timeout' 247 | 248 | def _get_timestamp(self): 249 | """Get current timestamp. 250 | 251 | Returns: 252 | Current timestamp as float. 253 | """ 254 | import time 255 | return time.time() -------------------------------------------------------------------------------- /examples/ml_example.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Example script demonstrating the use of ML capabilities in PhantomFuzzer. 6 | 7 | This script shows how to: 8 | 1. Initialize the ML integration 9 | 2. Train a model with sample data 10 | 3. Use the model for anomaly detection 11 | 4. Collect feedback and improve the model 12 | """ 13 | 14 | import os 15 | import sys 16 | import argparse 17 | from pathlib import Path 18 | 19 | # Add project root to path if needed 20 | sys.path.insert(0, str(Path(__file__).parent.parent)) 21 | 22 | # Import PhantomFuzzer ML components 23 | from phantomfuzzer.ml import MLIntegration 24 | 25 | 26 | def setup_argparse(): 27 | """Set up command line argument parsing.""" 28 | parser = argparse.ArgumentParser(description='PhantomFuzzer ML Example') 29 | 30 | parser.add_argument('--train', action='store_true', 31 | help='Train a new model') 32 | parser.add_argument('--benign-dir', type=str, default=None, 33 | help='Directory containing benign files for training') 34 | parser.add_argument('--malicious-dir', type=str, default=None, 35 | help='Directory containing malicious files for training') 36 | parser.add_argument('--model-name', type=str, default=None, 37 | help='Name of the model to use or train') 38 | 39 | parser.add_argument('--analyze', action='store_true', 40 | help='Analyze files for anomalies') 41 | parser.add_argument('--target-dir', type=str, default=None, 42 | help='Directory containing files to analyze') 43 | parser.add_argument('--target-file', type=str, default=None, 44 | help='Single file to analyze') 45 | 46 | parser.add_argument('--feedback', action='store_true', 47 | help='Provide feedback on a prediction') 48 | parser.add_argument('--is-correct', action='store_true', 49 | help='Whether the prediction was correct') 50 | parser.add_argument('--notes', type=str, default=None, 51 | help='Notes about the feedback') 52 | 53 | parser.add_argument('--retrain', action='store_true', 54 | help='Retrain model with feedback') 55 | 56 | parser.add_argument('--list-models', action='store_true', 57 | help='List available models') 58 | 59 | return parser 60 | 61 | 62 | def train_model(ml_integration, args): 63 | """Train a new model with sample data.""" 64 | print("Training new model...") 65 | 66 | if not args.benign_dir: 67 | print("Error: --benign-dir is required for training") 68 | return 69 | 70 | benign_dir = Path(args.benign_dir) 71 | if not benign_dir.exists() or not benign_dir.is_dir(): 72 | print(f"Error: Benign directory {benign_dir} does not exist or is not a directory") 73 | return 74 | 75 | malicious_dirs = None 76 | if args.malicious_dir: 77 | malicious_dir = Path(args.malicious_dir) 78 | if not malicious_dir.exists() or not malicious_dir.is_dir(): 79 | print(f"Error: Malicious directory {malicious_dir} does not exist or is not a directory") 80 | return 81 | malicious_dirs = [str(malicious_dir)] 82 | 83 | model_name = ml_integration.train_model( 84 | benign_dirs=[str(benign_dir)], 85 | malicious_dirs=malicious_dirs, 86 | model_name=args.model_name 87 | ) 88 | 89 | print(f"Model trained and saved as: {model_name}") 90 | 91 | # Set as default model 92 | ml_integration.set_default_model(model_name) 93 | print(f"Set {model_name} as the default model") 94 | 95 | 96 | def analyze_files(ml_integration, args): 97 | """Analyze files for anomalies.""" 98 | if args.target_file: 99 | # Analyze a single file 100 | file_path = Path(args.target_file) 101 | if not file_path.exists() or not file_path.is_file(): 102 | print(f"Error: File {file_path} does not exist or is not a file") 103 | return 104 | 105 | print(f"Analyzing file: {file_path}") 106 | result = ml_integration.detect_file_anomalies( 107 | file_path=str(file_path), 108 | model_name=args.model_name 109 | ) 110 | 111 | print("Analysis result:") 112 | print(f" File: {result.get('file')}") 113 | print(f" Is anomaly: {result.get('is_anomaly', False)}") 114 | print(f" Anomaly score: {result.get('anomaly_score', 0):.4f}") 115 | print(f" Threshold: {result.get('threshold', 0):.4f}") 116 | 117 | if 'error' in result: 118 | print(f" Error: {result['error']}") 119 | 120 | return result 121 | 122 | elif args.target_dir: 123 | # Analyze a directory of files 124 | dir_path = Path(args.target_dir) 125 | if not dir_path.exists() or not dir_path.is_dir(): 126 | print(f"Error: Directory {dir_path} does not exist or is not a directory") 127 | return 128 | 129 | print(f"Analyzing directory: {dir_path}") 130 | results = ml_integration.batch_analyze_directory( 131 | directory=str(dir_path), 132 | model_name=args.model_name, 133 | recursive=True 134 | ) 135 | 136 | print("Analysis summary:") 137 | print(f" Directory: {results.get('directory')}") 138 | print(f" Files analyzed: {results.get('files_analyzed', 0)}") 139 | print(f" Anomalies detected: {results.get('anomalies_detected', 0)}") 140 | print(f" Errors: {results.get('errors', 0)}") 141 | print(f" Average score: {results.get('average_score', 0):.4f}") 142 | print(f" Model used: {results.get('model_used')}") 143 | 144 | # Print details of anomalies 145 | anomalies = [r for r in results.get('file_results', []) if r.get('is_anomaly', False)] 146 | if anomalies: 147 | print("\nAnomalies detected:") 148 | for anomaly in anomalies: 149 | print(f" {anomaly.get('file')} (score: {anomaly.get('anomaly_score', 0):.4f})") 150 | 151 | return results 152 | else: 153 | print("Error: Either --target-file or --target-dir is required for analysis") 154 | return None 155 | 156 | 157 | def provide_feedback(ml_integration, args, prediction=None): 158 | """Provide feedback on a prediction.""" 159 | if not args.target_file: 160 | print("Error: --target-file is required for feedback") 161 | return 162 | 163 | file_path = Path(args.target_file) 164 | if not file_path.exists() or not file_path.is_file(): 165 | print(f"Error: File {file_path} does not exist or is not a file") 166 | return 167 | 168 | # If no prediction was provided, perform analysis first 169 | if prediction is None: 170 | prediction = ml_integration.detect_file_anomalies( 171 | file_path=str(file_path), 172 | model_name=args.model_name 173 | ) 174 | 175 | # Record feedback 176 | feedback = ml_integration.record_feedback( 177 | file_path=str(file_path), 178 | prediction=prediction, 179 | is_correct=args.is_correct, 180 | notes=args.notes 181 | ) 182 | 183 | print("Feedback recorded:") 184 | print(f" File: {feedback.get('file')}") 185 | print(f" Is correct: {feedback.get('is_correct')}") 186 | print(f" Feedback ID: {feedback.get('id')}") 187 | 188 | if args.notes: 189 | print(f" Notes: {feedback.get('notes')}") 190 | 191 | 192 | def retrain_with_feedback(ml_integration, args): 193 | """Retrain model with feedback.""" 194 | print("Retraining model with feedback...") 195 | 196 | new_model_name = ml_integration.retrain_with_feedback( 197 | model_name=args.model_name, 198 | include_original_data=True 199 | ) 200 | 201 | if new_model_name: 202 | print(f"Model retrained and saved as: {new_model_name}") 203 | 204 | # Set as default model 205 | ml_integration.set_default_model(new_model_name) 206 | print(f"Set {new_model_name} as the default model") 207 | else: 208 | print("Retraining failed. Check logs for details.") 209 | 210 | 211 | def list_models(ml_integration): 212 | """List available models.""" 213 | models = ml_integration.get_available_models() 214 | 215 | print("Available models:") 216 | for model in models: 217 | if model == ml_integration.default_model: 218 | print(f" {model} (default)") 219 | else: 220 | print(f" {model}") 221 | 222 | 223 | def main(): 224 | """Main function.""" 225 | parser = setup_argparse() 226 | args = parser.parse_args() 227 | 228 | # Initialize ML integration 229 | ml_integration = MLIntegration() 230 | print("ML integration initialized") 231 | 232 | # Process commands 233 | if args.list_models: 234 | list_models(ml_integration) 235 | 236 | if args.train: 237 | train_model(ml_integration, args) 238 | 239 | if args.analyze: 240 | prediction = analyze_files(ml_integration, args) 241 | 242 | # If feedback flag is set, also provide feedback 243 | if args.feedback and prediction: 244 | provide_feedback(ml_integration, args, prediction) 245 | elif args.feedback: 246 | provide_feedback(ml_integration, args) 247 | 248 | if args.retrain: 249 | retrain_with_feedback(ml_integration, args) 250 | 251 | 252 | if __name__ == "__main__": 253 | main() 254 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # PhantomFuzzer Installation Script 4 | # This script builds the Docker image and creates a wrapper script for the phantomfuzzer command 5 | 6 | # Exit on error 7 | set -e 8 | 9 | # Function to handle errors 10 | handle_error() { 11 | echo "\nERROR: Installation failed at line $1" 12 | echo "Please check the error messages above and try again." 13 | exit 1 14 | } 15 | 16 | # Set up error handling 17 | trap 'handle_error $LINENO' ERR 18 | 19 | # Parse command line arguments 20 | SKIP_DOCKER_BUILD=false 21 | for arg in "$@"; do 22 | case $arg in 23 | --skip-docker-build) 24 | SKIP_DOCKER_BUILD=true 25 | shift 26 | ;; 27 | *) 28 | # Unknown option 29 | ;; 30 | esac 31 | done 32 | 33 | echo "===== PhantomFuzzer Installation =====" 34 | echo "This script will install PhantomFuzzer and its dependencies." 35 | 36 | # Set Docker Compose availability flag 37 | DOCKER_COMPOSE_AVAILABLE=false 38 | if command -v docker-compose &> /dev/null; then 39 | DOCKER_COMPOSE_AVAILABLE=true 40 | fi 41 | 42 | # Check if docker is installed 43 | if command -v docker &> /dev/null; then 44 | echo "Docker is installed." 45 | 46 | # Check if we should skip Docker build 47 | if [ "$SKIP_DOCKER_BUILD" = true ]; then 48 | echo "Skipping Docker build as requested with --skip-docker-build option." 49 | else 50 | echo "Checking for Docker image..." 51 | 52 | # Check if the Docker image already exists 53 | if docker images -q phantomfuzzer &> /dev/null; then 54 | echo "PhantomFuzzer Docker image already exists. Skipping build." 55 | else 56 | echo "Building Docker image..." 57 | 58 | # Check if docker-compose is available 59 | if [ "$DOCKER_COMPOSE_AVAILABLE" = true ]; then 60 | echo "Using Docker Compose for build..." 61 | 62 | # Build using docker-compose 63 | docker-compose build phantomfuzzer 64 | 65 | if [ $? -ne 0 ]; then 66 | echo "Error: Docker Compose build failed. Falling back to standard Docker build..." 67 | echo "Building Docker image..." 68 | 69 | # Fallback to standard Docker build 70 | docker build -t phantomfuzzer . 71 | 72 | if [ $? -ne 0 ]; then 73 | echo "Error: Docker build failed. Please check your Docker installation and try again." 74 | exit 1 75 | fi 76 | fi 77 | else 78 | echo "Docker Compose not found. Using standard Docker build..." 79 | echo "Building Docker image..." 80 | 81 | # Build the Docker image 82 | docker build -t phantomfuzzer . 83 | 84 | if [ $? -ne 0 ]; then 85 | echo "Error: Docker build failed. Please check your Docker installation and try again." 86 | exit 1 87 | fi 88 | fi 89 | 90 | echo "Docker image built successfully." 91 | fi 92 | fi 93 | else 94 | echo "Docker is not installed. Please install Docker to use PhantomFuzzer." 95 | exit 1 96 | fi 97 | echo "Creating wrapper script..." 98 | 99 | # Create the wrapper script 100 | WRAPPER_PATH="/usr/local/bin/phantomfuzzer" 101 | 102 | # Create ASCII banner file if it doesn't exist 103 | if [ ! -f "$(pwd)/ascii.txt" ]; then 104 | echo "Creating ASCII banner file..." 105 | cat > "$(pwd)/ascii.txt" << 'EOF' 106 | ██████╗░██╗░░██╗░█████╗░███╗░░██╗████████╗░█████╗░███╗░░░███╗ 107 | ██╔══██╗██║░░██║██╔══██╗████╗░██║╚══██╔══╝██╔══██╗████╗░████║ 108 | ██████╔╝███████║███████║██╔██╗██║░░░██║░░░██║░░██║██╔████╔██║ 109 | ██╔═══╝░██╔══██║██╔══██║██║╚████║░░░██║░░░██║░░██║██║╚██╔╝██║ 110 | ██║░░░░░██║░░██║██║░░██║██║░╚███║░░░██║░░░╚█████╔╝██║░╚═╝░██║ 111 | ╚═╝░░░░░╚═╝░░╚═╝╚═╝░░╚═╝╚═╝░░╚══╝░░░╚═╝░░░░╚════╝░╚═╝░░░░░╚═╝ 112 | EOF 113 | fi 114 | 115 | # Use the existing wrapper script 116 | if [ ! -f "phantomfuzzer_wrapper.sh" ]; then 117 | echo "ERROR: phantomfuzzer_wrapper.sh not found in the current directory." 118 | echo "Please make sure you are running this script from the PhantomFuzzer directory." 119 | exit 1 120 | fi 121 | 122 | # Store the absolute path to the PhantomFuzzer directory 123 | PHANTOM_DIR="$(pwd)" 124 | 125 | # Create a temporary copy of the wrapper script with the correct PHANTOM_DIR 126 | cp phantomfuzzer_wrapper.sh wrapper_script.tmp 127 | 128 | # Check if PHANTOM_DIR is already defined in the script 129 | if grep -q "PHANTOM_DIR=" wrapper_script.tmp; then 130 | # Update the existing PHANTOM_DIR in the wrapper script 131 | sed -i "s|PHANTOM_DIR=\".*\"|PHANTOM_DIR=\"$PHANTOM_DIR\"|g" wrapper_script.tmp 132 | else 133 | # Add PHANTOM_DIR definition after the script header comments 134 | sed -i "/^# This script forwards/a\\\n# Path to PhantomFuzzer installation directory\nPHANTOM_DIR=\"$PHANTOM_DIR\"" wrapper_script.tmp 135 | fi 136 | 137 | # Read the wrapper script content 138 | WRAPPER_CONTENT=$(cat wrapper_script.tmp) 139 | 140 | # Clean up 141 | rm wrapper_script.tmp 142 | 143 | # Create the wrapper script with sudo 144 | echo "\n===== Installing PhantomFuzzer Command =====" 145 | echo "This will install the phantomfuzzer command in $WRAPPER_PATH" 146 | echo "Please enter your password when prompted:" 147 | 148 | # Explicitly ask for sudo password to ensure we have proper permissions 149 | sudo -v 150 | 151 | # Create the directory and install the wrapper script 152 | echo "Creating directory and installing wrapper script..." 153 | sudo mkdir -p /usr/local/bin 154 | 155 | # Check if the target is a dangling symlink and remove it if it is 156 | if [ -L "$WRAPPER_PATH" ] && [ ! -e "$WRAPPER_PATH" ]; then 157 | echo "Removing dangling symlink at $WRAPPER_PATH" 158 | sudo rm -f "$WRAPPER_PATH" 159 | fi 160 | 161 | # If the file exists (regular file or valid symlink), remove it to avoid conflicts 162 | if [ -e "$WRAPPER_PATH" ]; then 163 | echo "Removing existing file at $WRAPPER_PATH" 164 | sudo rm -f "$WRAPPER_PATH" 165 | fi 166 | 167 | # Write the wrapper script to a temporary file and then move it with sudo 168 | echo "$WRAPPER_CONTENT" > wrapper_script_final.tmp 169 | 170 | # Make sure the temporary file was created successfully 171 | if [ ! -f wrapper_script_final.tmp ]; then 172 | echo "ERROR: Failed to create temporary wrapper script file" 173 | exit 1 174 | fi 175 | 176 | # Copy the file to the destination with sudo 177 | sudo cp wrapper_script_final.tmp $WRAPPER_PATH 178 | 179 | # Verify the file was copied successfully 180 | if [ ! -f "$WRAPPER_PATH" ]; then 181 | echo "ERROR: Failed to copy wrapper script to $WRAPPER_PATH" 182 | rm -f wrapper_script_final.tmp 183 | exit 1 184 | fi 185 | 186 | # Set executable permissions 187 | sudo chmod +x $WRAPPER_PATH 188 | 189 | # Clean up the temporary file 190 | rm -f wrapper_script_final.tmp 191 | 192 | echo "Wrapper script installed successfully in $WRAPPER_PATH" 193 | 194 | # Set installation success flag 195 | INSTALLATION_SUCCESS=true 196 | 197 | # Install man page if available 198 | if [ -f "phantomfuzzer.1" ]; then 199 | echo "\n===== Installing Man Page =====" 200 | echo "This will install the PhantomFuzzer man page for system-wide access" 201 | 202 | # We already have sudo access from earlier, so proceed with installation 203 | echo "Creating man directory and installing man page..." 204 | sudo mkdir -p /usr/local/share/man/man1 205 | sudo cp phantomfuzzer.1 /usr/local/share/man/man1/ 206 | 207 | MAN_INSTALLED=true 208 | 209 | # Check if mandb command exists and update the man database 210 | if command -v mandb &> /dev/null; then 211 | echo "Updating man database..." 212 | sudo mandb > /dev/null 2>&1 213 | echo "Man database updated successfully." 214 | else 215 | echo "Note: 'mandb' command not found. Man page is installed but the database could not be updated." 216 | echo "You may need to manually update your man database or install the 'man-db' package." 217 | fi 218 | 219 | echo "Man page installed successfully. You can access it with:" 220 | echo " man phantomfuzzer" 221 | echo "\nAlternatively, you can view the manual with:" 222 | echo " phantomfuzzer man" 223 | fi 224 | 225 | # Check if Docker image was built successfully 226 | if ! docker image inspect phantomfuzzer:latest > /dev/null 2>&1; then 227 | echo "\n===== Installation Error =====" 228 | echo "ERROR: Docker image build failed." 229 | echo "Please check the Docker error messages above." 230 | exit 1 231 | fi 232 | 233 | # Final verification 234 | if [ ! -f "$WRAPPER_PATH" ]; then 235 | echo "\n===== Installation Error =====" 236 | echo "ERROR: Wrapper script was not installed correctly." 237 | echo "Please check the error messages above." 238 | exit 1 239 | fi 240 | 241 | # Success message 242 | echo "\n===== Installation Complete =====" 243 | echo "PhantomFuzzer has been successfully installed!" 244 | echo "" 245 | echo "You can now use PhantomFuzzer by running:" 246 | echo " phantomfuzzer [command]" 247 | echo "" 248 | echo "Examples:" 249 | echo " phantomfuzzer --help # Show help information" 250 | echo " phantomfuzzer scanner web --url example.com # Scan a website" 251 | echo " phantomfuzzer fuzzer api --spec api-spec.yaml # Fuzz an API" 252 | echo " phantomfuzzer man # View the manual" 253 | echo "" 254 | echo "Documentation:" 255 | echo " man phantomfuzzer # View the man page" 256 | echo " phantomfuzzer --help # Show command help" 257 | echo "" 258 | echo "For more information, visit: https://github.com/ghostsecurity420/PhantomFuzzer" 259 | echo "" 260 | -------------------------------------------------------------------------------- /phantomfuzzer/config.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Configuration management for PhantomFuzzer. 6 | 7 | This module handles loading, validating, and accessing configuration settings 8 | for all components of PhantomFuzzer, including scanner, fuzzer, ML, and stealth 9 | capabilities. 10 | """ 11 | 12 | import os 13 | import sys 14 | import yaml 15 | import json 16 | import logging 17 | from typing import Dict, Any, Optional, List, Union 18 | from pathlib import Path 19 | 20 | # Default configuration file path 21 | DEFAULT_CONFIG_PATH = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'config', 'default.yml') 22 | 23 | class ConfigValidationError(Exception): 24 | """Exception raised for configuration validation errors.""" 25 | pass 26 | 27 | class ConfigManager: 28 | """Manages configuration for PhantomFuzzer. 29 | 30 | This class handles loading configuration from files, validating the configuration, 31 | and providing access to configuration settings for different components. 32 | """ 33 | 34 | def __init__(self, config_path: Optional[str] = None): 35 | """Initialize the configuration manager. 36 | 37 | Args: 38 | config_path: Path to the configuration file. If None, the default 39 | configuration file will be used. 40 | """ 41 | self.config: Dict[str, Any] = {} 42 | self.config_path = config_path or DEFAULT_CONFIG_PATH 43 | self.load_config() 44 | 45 | def load_config(self) -> None: 46 | """Load configuration from the specified file. 47 | 48 | Raises: 49 | FileNotFoundError: If the configuration file does not exist. 50 | yaml.YAMLError: If the configuration file is not valid YAML. 51 | """ 52 | try: 53 | with open(self.config_path, 'r') as f: 54 | self.config = yaml.safe_load(f) 55 | self.validate_config() 56 | except FileNotFoundError: 57 | logging.error(f"Configuration file not found: {self.config_path}") 58 | raise 59 | except yaml.YAMLError as e: 60 | logging.error(f"Error parsing configuration file: {e}") 61 | raise 62 | 63 | def validate_config(self) -> None: 64 | """Validate the configuration. 65 | 66 | Ensures that all required configuration settings are present and valid. 67 | 68 | Raises: 69 | ConfigValidationError: If the configuration is invalid. 70 | """ 71 | required_sections = ['general', 'scanner', 'fuzzer', 'ml', 'stealth', 'payload', 'wordlists'] 72 | 73 | for section in required_sections: 74 | if section not in self.config: 75 | raise ConfigValidationError(f"Missing required configuration section: {section}") 76 | 77 | # Validate general section 78 | if 'log_level' not in self.config['general']: 79 | raise ConfigValidationError("Missing required configuration: general.log_level") 80 | 81 | # Validate scanner section 82 | if 'modes' not in self.config['scanner']: 83 | raise ConfigValidationError("Missing required configuration: scanner.modes") 84 | 85 | # Additional validation can be added as needed 86 | 87 | def get_config(self) -> Dict[str, Any]: 88 | """Get the complete configuration. 89 | 90 | Returns: 91 | The complete configuration dictionary. 92 | """ 93 | return self.config 94 | 95 | def get_section(self, section: str) -> Dict[str, Any]: 96 | """Get a specific section of the configuration. 97 | 98 | Args: 99 | section: The section to retrieve. 100 | 101 | Returns: 102 | The configuration section. 103 | 104 | Raises: 105 | KeyError: If the section does not exist. 106 | """ 107 | if section not in self.config: 108 | raise KeyError(f"Configuration section not found: {section}") 109 | return self.config[section] 110 | 111 | def get_value(self, path: str, default: Any = None) -> Any: 112 | """Get a specific configuration value using a dot-separated path. 113 | 114 | Args: 115 | path: The dot-separated path to the configuration value. 116 | default: The default value to return if the path does not exist. 117 | 118 | Returns: 119 | The configuration value, or the default if the path does not exist. 120 | 121 | Example: 122 | >>> config.get_value('scanner.web_scan.crawl_depth') 123 | 3 124 | """ 125 | parts = path.split('.') 126 | value = self.config 127 | 128 | try: 129 | for part in parts: 130 | value = value[part] 131 | return value 132 | except (KeyError, TypeError): 133 | return default 134 | 135 | def set_value(self, path: str, value: Any) -> None: 136 | """Set a specific configuration value using a dot-separated path. 137 | 138 | Args: 139 | path: The dot-separated path to the configuration value. 140 | value: The value to set. 141 | 142 | Example: 143 | >>> config.set_value('scanner.web_scan.crawl_depth', 5) 144 | """ 145 | parts = path.split('.') 146 | config = self.config 147 | 148 | for i, part in enumerate(parts[:-1]): 149 | if part not in config: 150 | config[part] = {} 151 | config = config[part] 152 | 153 | config[parts[-1]] = value 154 | 155 | def save_config(self, path: Optional[str] = None) -> None: 156 | """Save the current configuration to a file. 157 | 158 | Args: 159 | path: The path to save the configuration to. If None, the current 160 | configuration path will be used. 161 | 162 | Raises: 163 | IOError: If the configuration file cannot be written. 164 | """ 165 | save_path = path or self.config_path 166 | 167 | try: 168 | with open(save_path, 'w') as f: 169 | yaml.dump(self.config, f, default_flow_style=False) 170 | except IOError as e: 171 | logging.error(f"Error saving configuration file: {e}") 172 | raise 173 | 174 | def merge_config(self, config: Dict[str, Any]) -> None: 175 | """Merge another configuration dictionary into the current configuration. 176 | 177 | Args: 178 | config: The configuration dictionary to merge. 179 | """ 180 | self._merge_dicts(self.config, config) 181 | self.validate_config() 182 | 183 | def _merge_dicts(self, target: Dict[str, Any], source: Dict[str, Any]) -> None: 184 | """Recursively merge two dictionaries. 185 | 186 | Args: 187 | target: The target dictionary to merge into. 188 | source: The source dictionary to merge from. 189 | """ 190 | for key, value in source.items(): 191 | if key in target and isinstance(target[key], dict) and isinstance(value, dict): 192 | self._merge_dicts(target[key], value) 193 | else: 194 | target[key] = value 195 | 196 | # Convenience methods for accessing specific sections 197 | 198 | def get_general_config(self) -> Dict[str, Any]: 199 | """Get the general configuration section. 200 | 201 | Returns: 202 | The general configuration section. 203 | """ 204 | return self.get_section('general') 205 | 206 | def get_scanner_config(self) -> Dict[str, Any]: 207 | """Get the scanner configuration section. 208 | 209 | Returns: 210 | The scanner configuration section. 211 | """ 212 | return self.get_section('scanner') 213 | 214 | def get_fuzzer_config(self) -> Dict[str, Any]: 215 | """Get the fuzzer configuration section. 216 | 217 | Returns: 218 | The fuzzer configuration section. 219 | """ 220 | return self.get_section('fuzzer') 221 | 222 | def get_ml_config(self) -> Dict[str, Any]: 223 | """Get the ML configuration section. 224 | 225 | Returns: 226 | The ML configuration section. 227 | """ 228 | return self.get_section('ml') 229 | 230 | def get_stealth_config(self) -> Dict[str, Any]: 231 | """Get the stealth configuration section. 232 | 233 | Returns: 234 | The stealth configuration section. 235 | """ 236 | return self.get_section('stealth') 237 | 238 | def get_payload_config(self) -> Dict[str, Any]: 239 | """Get the payload configuration section. 240 | 241 | Returns: 242 | The payload configuration section. 243 | """ 244 | return self.get_section('payload') 245 | 246 | def get_wordlists_config(self) -> Dict[str, Any]: 247 | """Get the wordlists configuration section. 248 | 249 | Returns: 250 | The wordlists configuration section. 251 | """ 252 | return self.get_section('wordlists') 253 | 254 | # Global configuration instance 255 | _config_instance = None 256 | 257 | def get_config(config_path: Optional[str] = None) -> ConfigManager: 258 | """Get the global configuration instance. 259 | 260 | Args: 261 | config_path: Path to the configuration file. If None, the default 262 | configuration file will be used. This is only used if the global 263 | configuration instance has not been initialized yet. 264 | 265 | Returns: 266 | The global configuration instance. 267 | """ 268 | global _config_instance 269 | if _config_instance is None: 270 | _config_instance = ConfigManager(config_path) 271 | return _config_instance 272 | 273 | def reset_config() -> None: 274 | """Reset the global configuration instance.""" 275 | global _config_instance 276 | _config_instance = None -------------------------------------------------------------------------------- /phantomfuzzer/ml/inference.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Inference Engine for Machine Learning Models. 6 | 7 | This module provides utilities for making predictions with 8 | trained machine learning models in PhantomFuzzer. 9 | """ 10 | 11 | import os 12 | from pathlib import Path 13 | from typing import Dict, List, Tuple, Union, Optional, Any 14 | 15 | # Local imports 16 | from phantomfuzzer.utils.logging import get_logger 17 | from phantomfuzzer.ml.models.pattern_recognizer import PatternRecognizer 18 | 19 | 20 | class InferenceEngine: 21 | """Inference engine for machine learning models. 22 | 23 | This class handles loading trained models and making predictions 24 | on new data for anomaly detection and other ML tasks. 25 | """ 26 | 27 | def __init__(self, config: Optional[Dict[str, Any]] = None): 28 | """Initialize the inference engine. 29 | 30 | Args: 31 | config: Configuration parameters for inference. 32 | """ 33 | self.logger = get_logger(__name__) 34 | self.config = config or {} 35 | 36 | # Default configuration 37 | self.model_dir = self.config.get('model_dir', 'models') 38 | self.threshold = self.config.get('anomaly_threshold', 0.7) # Threshold for anomaly detection 39 | 40 | # Loaded models cache 41 | self.models: Dict[str, Any] = {} 42 | 43 | def load_pattern_recognizer(self, model_name: str) -> PatternRecognizer: 44 | """Load a pattern recognizer model. 45 | 46 | Args: 47 | model_name: Name of the model to load. 48 | 49 | Returns: 50 | The loaded PatternRecognizer model. 51 | """ 52 | # Check if model is already loaded 53 | if model_name in self.models: 54 | return self.models[model_name] 55 | 56 | # Construct model path 57 | model_path = Path(self.model_dir) / f"{model_name}.pkl" 58 | 59 | if not model_path.exists(): 60 | self.logger.error(f"Model {model_name} not found at {model_path}") 61 | raise FileNotFoundError(f"Model {model_name} not found at {model_path}") 62 | 63 | # Load model 64 | model = PatternRecognizer() 65 | success = model.load_model(model_path) 66 | 67 | if not success: 68 | self.logger.error(f"Failed to load model {model_name}") 69 | raise RuntimeError(f"Failed to load model {model_name}") 70 | 71 | # Cache model 72 | self.models[model_name] = model 73 | self.logger.info(f"Loaded model {model_name} from {model_path}") 74 | 75 | return model 76 | 77 | def detect_anomalies(self, 78 | file_paths: List[Union[str, Path]], 79 | model_name: str = 'pattern_recognizer', 80 | threshold: Optional[float] = None) -> List[Dict[str, Any]]: 81 | """Detect anomalies in a list of files. 82 | 83 | Args: 84 | file_paths: List of paths to files to analyze. 85 | model_name: Name of the model to use for detection. 86 | threshold: Anomaly score threshold (0-1). Scores above this are considered anomalies. 87 | If None, use the default threshold from config. 88 | 89 | Returns: 90 | List of dictionaries with detection results for each file. 91 | """ 92 | if threshold is None: 93 | threshold = self.threshold 94 | 95 | # Load model 96 | try: 97 | model = self.load_pattern_recognizer(model_name) 98 | except (FileNotFoundError, RuntimeError) as e: 99 | self.logger.error(f"Error loading model: {str(e)}") 100 | # Return empty results if model can't be loaded 101 | return [{'file': str(path), 'error': str(e)} for path in file_paths] 102 | 103 | # Process files 104 | results = [] 105 | for file_path in file_paths: 106 | try: 107 | # Get prediction 108 | is_anomaly, score = model.predict(file_path) 109 | 110 | # Apply custom threshold if needed 111 | if threshold != 0.5: # Default threshold for isolation forest is 0.5 112 | is_anomaly = score >= threshold 113 | 114 | # Create result 115 | result = { 116 | 'file': str(file_path), 117 | 'is_anomaly': is_anomaly, 118 | 'anomaly_score': score, 119 | 'threshold': threshold 120 | } 121 | 122 | results.append(result) 123 | 124 | except Exception as e: 125 | self.logger.error(f"Error analyzing {file_path}: {str(e)}") 126 | results.append({ 127 | 'file': str(file_path), 128 | 'error': str(e) 129 | }) 130 | 131 | return results 132 | 133 | def detect_file_anomalies(self, 134 | file_path: Union[str, Path], 135 | model_name: str = 'pattern_recognizer', 136 | threshold: Optional[float] = None) -> Dict[str, Any]: 137 | """Detect anomalies in a single file. 138 | 139 | Args: 140 | file_path: Path to the file to analyze. 141 | model_name: Name of the model to use for detection. 142 | threshold: Anomaly score threshold (0-1). Scores above this are considered anomalies. 143 | If None, use the default threshold from config. 144 | 145 | Returns: 146 | Dictionary with detection results. 147 | """ 148 | results = self.detect_anomalies([file_path], model_name, threshold) 149 | return results[0] if results else {'file': str(file_path), 'error': 'Analysis failed'} 150 | 151 | def batch_analyze(self, 152 | directory: Union[str, Path], 153 | model_name: str = 'pattern_recognizer', 154 | recursive: bool = True, 155 | file_extensions: Optional[List[str]] = None, 156 | max_files: int = 1000) -> Dict[str, Any]: 157 | """Analyze all files in a directory for anomalies. 158 | 159 | Args: 160 | directory: Path to the directory to analyze. 161 | model_name: Name of the model to use for detection. 162 | recursive: Whether to recursively search subdirectories. 163 | file_extensions: List of file extensions to include (without leading dot). 164 | If None, analyze all files. 165 | max_files: Maximum number of files to analyze. 166 | 167 | Returns: 168 | Dictionary with analysis results and summary statistics. 169 | """ 170 | directory = Path(directory) 171 | if not directory.exists() or not directory.is_dir(): 172 | self.logger.error(f"Directory {directory} does not exist or is not a directory") 173 | return {'error': f"Directory {directory} does not exist or is not a directory"} 174 | 175 | # Collect files to analyze 176 | files = [] 177 | pattern = '**/*' if recursive else '*' 178 | 179 | for file_path in directory.glob(pattern): 180 | if not file_path.is_file(): 181 | continue 182 | 183 | # Check extension if specified 184 | if file_extensions is not None: 185 | ext = file_path.suffix.lower()[1:] # Remove leading dot 186 | if ext not in file_extensions: 187 | continue 188 | 189 | files.append(str(file_path)) 190 | 191 | if len(files) >= max_files: 192 | self.logger.info(f"Reached maximum number of files ({max_files})") 193 | break 194 | 195 | # Analyze files 196 | self.logger.info(f"Analyzing {len(files)} files in {directory}") 197 | file_results = self.detect_anomalies(files, model_name) 198 | 199 | # Compile summary statistics 200 | anomalies = [r for r in file_results if r.get('is_anomaly', False)] 201 | errors = [r for r in file_results if 'error' in r] 202 | 203 | # Calculate average score 204 | scores = [r.get('anomaly_score', 0) for r in file_results if 'anomaly_score' in r] 205 | avg_score = sum(scores) / len(scores) if scores else 0 206 | 207 | # Create summary 208 | summary = { 209 | 'directory': str(directory), 210 | 'files_analyzed': len(files), 211 | 'anomalies_detected': len(anomalies), 212 | 'errors': len(errors), 213 | 'average_score': avg_score, 214 | 'model_used': model_name, 215 | 'file_results': file_results 216 | } 217 | 218 | return summary 219 | 220 | def unload_model(self, model_name: str) -> bool: 221 | """Unload a model from memory. 222 | 223 | Args: 224 | model_name: Name of the model to unload. 225 | 226 | Returns: 227 | True if the model was unloaded, False if it wasn't loaded. 228 | """ 229 | if model_name in self.models: 230 | # Clear model's cache if possible 231 | if hasattr(self.models[model_name], 'clear_cache'): 232 | self.models[model_name].clear_cache() 233 | 234 | # Remove from cache 235 | del self.models[model_name] 236 | self.logger.info(f"Unloaded model {model_name}") 237 | return True 238 | 239 | return False 240 | 241 | def unload_all_models(self) -> None: 242 | """Unload all models from memory.""" 243 | model_names = list(self.models.keys()) 244 | for model_name in model_names: 245 | self.unload_model(model_name) 246 | 247 | self.logger.info("Unloaded all models") 248 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # PhantomFuzzer 2 | 3 | ⣿⣿⣿⣿⣿⣿⣿⣿⡿⣿⣿⣿⣿⣿⡿⢿⡿⠃⠀⡐⠀⠘⡻⠿⠋⠛⢻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 4 | ⣿⣿⣿⣿⣿⣿⣿⡏⠈⣤⡝⠛⢻⣷⡆⠀⠀⠀⠀⠀⣤⣧⠀⠀⠀⠀⠚⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 5 | ⣿⣿⣿⣿⣿⣿⣿⡇⡀⠀⢴⣮⡀⠉⠁⠀⠀⠀⠀⠁⣹⠛⠋⠉⣰⢄⣠⣿⣿⣿⣿⣿⡿⡿⠿⢿⡿⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 6 | ⣿⣿⣿⣿⣿⡿⠿⢇⣗⠀⢈⠙⣷⠀⡐⢀⠀⡀⠀⢀⣴⣦⡄⢂⢀⣺⣿⣿⣿⣿⠏⠁⣠⣤⣤⣤⣭⣕⡲⣌⡋⠻⠿⠿⠿⠛⠛⣛ 7 | ⣿⣿⣿⣿⣿⣇⠀⠀⠀⠀⠾⢯⡙⢇⠀⢃⢀⣀⠢⡿⠋⢐⠶⠇⣿⣿⣿⣿⠟⠁⣺⣿⣿⣿⣿⣿⣿⣿⣷⣵⡛⣃⣀⣠⣀⣠⣾⣿ 8 | ⣿⣿⣿⣿⣿⣷⠀⠀⢸⣦⠀⠀⠉⠂⠁⢆⣌⠆⡆⢷⡍⠹⠷⠸⠿⠿⠏⠁⣤⡌⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⣿⣿⣿⣿⣿⣿ 9 | ⣿⣿⣿⣿⣿⣿⣆⠀⠀⠻⣷⣦⡀⠀⢠⠂⢾⠀⠀⠀⠀⢀⠂⠀⣤⣶⣾⣿⣿⣿⣶⣤⣤⣤⣨⡙⢿⣿⣿⣿⣿⣿⢿⣿⣿⣿⣿⣿ 10 | ⣿⣿⣿⣿⣿⠟⠁⠀⠀⠀⠚⠋⢠⣾⣿⡼⣹⣮⣤⣰⡶⠏⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⣼⣿⣻⣿⣿⣿⣿⣿⣿⣿⣿ 11 | ⣿⣿⡿⢡⣏⡇⠀⠀⠀⢀⢰⣰⢿⡛⠣⠆⢿⣿⣿⠇⠀⠀⠈⠻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 12 | ⣿⣿⡇⣸⡇⠿⠀⠀⠀⡀⠸⡀⠘⠃⠀⠀⢾⢿⠇⠀⠀⠀⢀⢰⠘⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 13 | ⣿⣿⢃⣿⡻⡀⣣⠀⠀⠀⠂⠁⠈⠈⠀⠘⠀⠄⣽⠐⠃⠀⠈⡈⢀⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 14 | ⣿⣿⠸⣿⣷⢄⠀⠱⡄⠀⠀⠀⢿⣷⣷⠀⠔⠈⠁⠀⠀⠀⣘⠁⠘⠻⠿⠿⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 15 | ⠋⠴⣬⣨⠣⣾⣷⣥⡽⠆⠀⠀⠁⠉⠀⠀⠀⠀⢀⠀⠀⣼⠁⠀⢀⣄⡦⠭⠤⠶⠤⣬⣍⣻⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 16 | ⣧⣤⣿⡟⢄⡙⠛⠉⠁⢃⠐⠀⠀⠀⠀⠀⠜⠀⠈⣀⡿⠋⠀⣸⡿⠛⠁⠀⠀⠘⠀⢉⠉⠹⢿⢟⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 17 | ⡿⣿⣿⣿⣎⠀⠀⠀⠀⠘⠀⠁⠀⠀⠀⠀⠀⠀⠀⠟⠑⠀⠀⠈⠀⠀⠀⠀⠠⢤⠤⣨⣷⡀⠀⣚⡋⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿ 18 | 19 | PhantomFuzzer is an advanced security testing toolkit that combines traditional fuzzing techniques with machine learning capabilities to detect vulnerabilities in web applications, APIs, protocols, and files. 20 | 21 | ## Features 22 | 23 | - **Comprehensive Fuzzing**: Multiple fuzzer types for API, protocol, and input fuzzing 24 | - **Advanced Scanning**: Web application, API, and file scanning capabilities 25 | - **Payload Generation**: Extensive library of attack payloads for various vulnerability types 26 | - **Machine Learning Integration**: Enhanced detection using ML algorithms (in development) 27 | - **Extensible Architecture**: Modular design for easy extension with new capabilities 28 | 29 | ## Installation 30 | 31 | ### Prerequisites 32 | 33 | - Docker (version 19.03 or higher) 34 | - Git (for cloning the repository) 35 | - Bash shell 36 | 37 | ### Setup 38 | 39 | 1. Clone the repository: 40 | ```bash 41 | git clone https://github.com/ghostsec420/PhantomFuzzer.git 42 | cd PhantomFuzzer 43 | ``` 44 | 45 | 2. Run the installation script: 46 | ```bash 47 | ./install.sh 48 | ``` 49 | 50 | This script will: 51 | - Build the Docker image with all dependencies 52 | - Create a wrapper script that allows you to use the `phantomfuzzer` command 53 | - Set appropriate permissions 54 | 55 | 3. Verify the installation: 56 | ```bash 57 | phantomfuzzer --help 58 | ``` 59 | 60 | ## Usage Guide 61 | 62 | PhantomFuzzer has three main command groups: 63 | - `scanner`: Run various types of scanners against targets 64 | - `fuzzer`: Test applications for vulnerabilities by sending unexpected inputs 65 | - `payload`: Generate attack payloads for security testing 66 | 67 | ### Global Options 68 | 69 | PhantomFuzzer provides several global options to control output verbosity and formatting: 70 | 71 | ```bash 72 | # Show minimal output (only critical messages and results) 73 | phantomfuzzer --quiet [command] 74 | 75 | # Show more detailed output 76 | phantomfuzzer --verbose [command] 77 | 78 | # Show all debug information 79 | phantomfuzzer --debug [command] 80 | 81 | # Disable colored output 82 | phantomfuzzer --no-color [command] 83 | ``` 84 | 85 | You can combine these options as needed: 86 | 87 | ```bash 88 | phantomfuzzer --verbose --no-color scanner web --url https://example.com 89 | ``` 90 | 91 | ### Scanning Operations 92 | 93 | #### Web Application Scanning 94 | 95 | PhantomFuzzer allows you to scan web applications for vulnerabilities: 96 | 97 | ##### Basic Web Scanning 98 | 99 | ```bash 100 | phantomfuzzer scanner web --url https://example.com 101 | ``` 102 | 103 | ##### Scan with Authentication 104 | 105 | ```bash 106 | phantomfuzzer scanner web --url https://example.com --auth '{"username":"user","password":"pass"}' 107 | ``` 108 | 109 | ##### Control Scan Depth 110 | 111 | ```bash 112 | phantomfuzzer scanner web --url https://example.com --depth 2 113 | ``` 114 | 115 | ##### Save Results to a File 116 | 117 | ```bash 118 | phantomfuzzer scanner web --url https://example.com --output web_results.json --format json 119 | ``` 120 | 121 | #### API Scanning 122 | 123 | Scan your APIs for potential vulnerabilities: 124 | 125 | ```bash 126 | phantomfuzzer scanner api --url https://api.example.com 127 | ``` 128 | 129 | ##### With OpenAPI/Swagger Specification 130 | 131 | ```bash 132 | phantomfuzzer scanner api --url https://api.example.com --spec openapi.json 133 | ``` 134 | 135 | ##### With Authentication 136 | 137 | ```bash 138 | phantomfuzzer scanner api --url https://api.example.com --auth '{"token":"your-api-token"}' 139 | ``` 140 | 141 | ##### Save Results to a File 142 | 143 | ```bash 144 | phantomfuzzer scanner api --url https://api.example.com --output api_results.json --format json 145 | ``` 146 | 147 | #### File Scanning 148 | 149 | Scan files and directories for vulnerabilities: 150 | 151 | ##### Scan a Single File 152 | 153 | ```bash 154 | phantomfuzzer scanner file --path ./target/file.php 155 | ``` 156 | 157 | ##### Recursive Directory Scan 158 | 159 | ```bash 160 | phantomfuzzer scanner file --path ./target --recursive 161 | ``` 162 | 163 | ##### Scan with File Pattern Matching 164 | 165 | ```bash 166 | phantomfuzzer scanner file --path ./target --recursive --pattern "*.php" 167 | ``` 168 | 169 | ##### Enable Machine Learning Enhanced Detection 170 | 171 | ```bash 172 | phantomfuzzer scanner file --path ./target --ml-enhanced 173 | ``` 174 | 175 | ##### Save Results to a File 176 | 177 | ```bash 178 | phantomfuzzer scanner file --path ./target --output file_results.json --format json 179 | ``` 180 | 181 | ### Fuzzing Operations 182 | 183 | #### API Fuzzing 184 | 185 | PhantomFuzzer provides the ability to fuzz APIs by sending crafted requests. Here's how to perform API fuzzing: 186 | 187 | ##### Basic API Fuzzing 188 | 189 | ```bash 190 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --method GET 191 | ``` 192 | 193 | ##### POST Request Fuzzing 194 | 195 | ```bash 196 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --method POST --data '{"username":"test"}' 197 | ``` 198 | 199 | ##### Fuzz with Custom Headers 200 | 201 | ```bash 202 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --headers '{"Authorization":"Bearer token"}' 203 | ``` 204 | 205 | ##### With Authentication 206 | 207 | ```bash 208 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --auth '{"username":"user","password":"pass"}' 209 | ``` 210 | 211 | ##### Control Fuzzing Intensity 212 | 213 | ```bash 214 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --iterations 200 --delay 0.2 --timeout 10 215 | ``` 216 | 217 | ##### Save Results to a File 218 | 219 | ```bash 220 | phantomfuzzer fuzzer api --target https://api.example.com/v1/users --output results.json --format json 221 | ``` 222 | 223 | #### Protocol Fuzzing 224 | 225 | You can fuzz different protocols like TCP, SSH, and FTP. Below are examples: 226 | 227 | ##### TCP Protocol Fuzzing 228 | 229 | ```bash 230 | phantomfuzzer fuzzer protocol --target example.com --port 80 --protocol tcp 231 | ``` 232 | 233 | ##### SSH Protocol Fuzzing 234 | 235 | ```bash 236 | phantomfuzzer fuzzer protocol --target example.com --port 22 --protocol ssh 237 | ``` 238 | 239 | ##### FTP Protocol Fuzzing 240 | 241 | ```bash 242 | phantomfuzzer fuzzer protocol --target example.com --port 21 --protocol ftp 243 | ``` 244 | 245 | ##### Control Protocol Fuzzing Intensity 246 | 247 | ```bash 248 | phantomfuzzer fuzzer protocol --target example.com --port 80 --protocol http --iterations 100 --delay 0.5 --timeout 15 249 | ``` 250 | 251 | #### Input Fuzzing 252 | 253 | You can fuzz various types of inputs, including files, stdin, and command-line arguments. 254 | 255 | ##### File Input Fuzzing 256 | 257 | ```bash 258 | phantomfuzzer fuzzer input --target ./target/application --input-type file 259 | ``` 260 | 261 | ##### Command-Line Argument Fuzzing 262 | 263 | ```bash 264 | phantomfuzzer fuzzer input --target ./target/application --input-type argument 265 | ``` 266 | 267 | ##### Save Results to a File 268 | 269 | ```bash 270 | phantomfuzzer fuzzer input --target ./target/application --input-type file --output input_results.json --output-format json 271 | ``` 272 | 273 | ### Payload Generation 274 | 275 | PhantomFuzzer allows you to generate different types of attack payloads for various categories. Here's how you can use it: 276 | 277 | #### List Available Payload Categories 278 | 279 | ```bash 280 | phantomfuzzer payload list 281 | ``` 282 | 283 | #### Generate Specific Payloads 284 | 285 | ##### SQL Injection (Basic) 286 | 287 | ```bash 288 | phantomfuzzer payload generate --category sql_injection --subcategory basic 289 | ``` 290 | 291 | ##### Generate Multiple XSS Payloads 292 | 293 | ```bash 294 | phantomfuzzer payload generate --category xss --count 5 --output xss_payloads.txt 295 | ``` 296 | 297 | ##### Generate Command Injection Payloads in JSON Format 298 | 299 | ```bash 300 | phantomfuzzer payload generate --category command_injection --format json 301 | ``` 302 | 303 | #### Generate Random Payloads 304 | 305 | ```bash 306 | phantomfuzzer payload random --count 3 307 | ``` 308 | 309 | ### Advanced Usage 310 | 311 | #### Combining Operations 312 | 313 | You can chain multiple operations for more comprehensive testing: 314 | 315 | ```bash 316 | # Generate payloads and use them for API fuzzing 317 | phantomfuzzer payload generate --category sql_injection --output sql_payloads.txt 318 | phantomfuzzer fuzzer api --target https://api.example.com/query --method POST --data @sql_payloads.txt 319 | 320 | # Scan and then fuzz discovered endpoints 321 | phantomfuzzer scanner api --url https://api.example.com --output discovered_apis.json 322 | phantomfuzzer fuzzer api --target https://api.example.com/query --method POST --data @discovered_apis.json 323 | ``` 324 | 325 | #### Debug Mode 326 | 327 | Enable debug logging for more detailed output: 328 | 329 | ```bash 330 | phantomfuzzer --debug scanner web --url https://example.com 331 | ``` 332 | 333 | ### Debug Mode 334 | 335 | Enable debug logging for more detailed output: 336 | 337 | ```bash 338 | phantomfuzzer --debug scanner web --url https://example.com 339 | ``` 340 | 341 | ## Contributing 342 | 343 | 1. Fork the repository 344 | 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 345 | 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 346 | 4. Push to the branch (`git push origin feature/amazing-feature`) 347 | 5. Open a Pull Request 348 | 349 | ## License 350 | 351 | This project is licensed under the MIT License - see the LICENSE file for details. 352 | -------------------------------------------------------------------------------- /phantomfuzzer/utils/helper.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Helper utilities for PhantomFuzzer. 6 | 7 | This module provides utility functions for the PhantomFuzzer toolkit, 8 | including output formatting, progress tracking, and result summarization. 9 | """ 10 | 11 | import sys 12 | import os 13 | import json 14 | from typing import Dict, List, Any, Optional, Union 15 | from enum import Enum 16 | 17 | # ANSI color codes for terminal output 18 | class Colors: 19 | RESET = "\033[0m" 20 | BOLD = "\033[1m" 21 | RED = "\033[31m" 22 | GREEN = "\033[32m" 23 | YELLOW = "\033[33m" 24 | BLUE = "\033[34m" 25 | MAGENTA = "\033[35m" 26 | CYAN = "\033[36m" 27 | WHITE = "\033[37m" 28 | BRIGHT_RED = "\033[91m" 29 | BRIGHT_GREEN = "\033[92m" 30 | BRIGHT_YELLOW = "\033[93m" 31 | BRIGHT_BLUE = "\033[94m" 32 | BRIGHT_MAGENTA = "\033[95m" 33 | BRIGHT_CYAN = "\033[96m" 34 | BRIGHT_WHITE = "\033[97m" 35 | 36 | class VerbosityLevel(Enum): 37 | """Verbosity levels for output control.""" 38 | QUIET = 0 # Only show critical errors and final results 39 | NORMAL = 1 # Show standard information and warnings 40 | VERBOSE = 2 # Show detailed information about operations 41 | DEBUG = 3 # Show all debug information 42 | 43 | # Global verbosity setting (default: NORMAL) 44 | VERBOSITY = VerbosityLevel.NORMAL 45 | USE_COLORS = True 46 | 47 | def set_verbosity(level: Union[VerbosityLevel, int, str]) -> None: 48 | """Set the global verbosity level. 49 | 50 | Args: 51 | level: The verbosity level to set. Can be a VerbosityLevel enum, 52 | an integer (0-3), or a string ('quiet', 'normal', 'verbose', 'debug'). 53 | """ 54 | global VERBOSITY 55 | 56 | if isinstance(level, VerbosityLevel): 57 | VERBOSITY = level 58 | elif isinstance(level, int): 59 | if 0 <= level <= 3: 60 | VERBOSITY = VerbosityLevel(level) 61 | else: 62 | raise ValueError(f"Invalid verbosity level: {level}. Must be between 0 and 3.") 63 | elif isinstance(level, str): 64 | level_map = { 65 | 'quiet': VerbosityLevel.QUIET, 66 | 'normal': VerbosityLevel.NORMAL, 67 | 'verbose': VerbosityLevel.VERBOSE, 68 | 'debug': VerbosityLevel.DEBUG 69 | } 70 | if level.lower() in level_map: 71 | VERBOSITY = level_map[level.lower()] 72 | else: 73 | raise ValueError(f"Invalid verbosity level: {level}. Must be one of: quiet, normal, verbose, debug.") 74 | else: 75 | raise TypeError(f"Invalid type for verbosity level: {type(level)}. Must be VerbosityLevel, int, or str.") 76 | 77 | def set_use_colors(use_colors: bool) -> None: 78 | """Set whether to use colors in terminal output. 79 | 80 | Args: 81 | use_colors: Whether to use colors in terminal output. 82 | """ 83 | global USE_COLORS 84 | USE_COLORS = use_colors 85 | 86 | def get_verbosity() -> VerbosityLevel: 87 | """Get the current verbosity level. 88 | 89 | Returns: 90 | The current verbosity level. 91 | """ 92 | return VERBOSITY 93 | 94 | def format_text(text: str, color: Optional[str] = None, bold: bool = False) -> str: 95 | """Format text with color and style. 96 | 97 | Args: 98 | text: The text to format. 99 | color: The color to use. Must be a color attribute from the Colors class. 100 | bold: Whether to make the text bold. 101 | 102 | Returns: 103 | The formatted text. 104 | """ 105 | if not USE_COLORS: 106 | return text 107 | 108 | formatted = "" 109 | if bold: 110 | formatted += Colors.BOLD 111 | if color: 112 | formatted += color 113 | 114 | formatted += text + Colors.RESET 115 | return formatted 116 | 117 | def print_quiet(message: str, color: Optional[str] = None, bold: bool = False, **kwargs) -> None: 118 | """Print a message only if verbosity is at least QUIET. 119 | 120 | Args: 121 | message: The message to print. 122 | color: Optional color to use. 123 | bold: Whether to make the text bold. 124 | **kwargs: Additional arguments to pass to print(). 125 | """ 126 | if VERBOSITY.value >= VerbosityLevel.QUIET.value: 127 | print(format_text(message, color, bold), **kwargs) 128 | 129 | def print_normal(message: str, color: Optional[str] = None, bold: bool = False, **kwargs) -> None: 130 | """Print a message only if verbosity is at least NORMAL. 131 | 132 | Args: 133 | message: The message to print. 134 | color: Optional color to use. 135 | bold: Whether to make the text bold. 136 | **kwargs: Additional arguments to pass to print(). 137 | """ 138 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 139 | print(format_text(message, color, bold), **kwargs) 140 | 141 | def print_verbose(message: str, color: Optional[str] = None, bold: bool = False, **kwargs) -> None: 142 | """Print a message only if verbosity is at least VERBOSE. 143 | 144 | Args: 145 | message: The message to print. 146 | color: Optional color to use. 147 | bold: Whether to make the text bold. 148 | **kwargs: Additional arguments to pass to print(). 149 | """ 150 | if VERBOSITY.value >= VerbosityLevel.VERBOSE.value: 151 | print(format_text(message, color, bold), **kwargs) 152 | 153 | def print_debug(message: str, color: Optional[str] = None, bold: bool = False, **kwargs) -> None: 154 | """Print a message only if verbosity is at least DEBUG. 155 | 156 | Args: 157 | message: The message to print. 158 | color: Optional color to use. 159 | bold: Whether to make the text bold. 160 | **kwargs: Additional arguments to pass to print(). 161 | """ 162 | if VERBOSITY.value >= VerbosityLevel.DEBUG.value: 163 | print(format_text(message, color, bold), **kwargs) 164 | 165 | def print_error(message: str, bold: bool = True, **kwargs) -> None: 166 | """Print an error message. 167 | 168 | Args: 169 | message: The error message to print. 170 | bold: Whether to make the text bold. 171 | **kwargs: Additional arguments to pass to print(). 172 | """ 173 | print(format_text(f"ERROR: {message}", Colors.RED, bold), file=sys.stderr, **kwargs) 174 | 175 | def print_warning(message: str, bold: bool = False, **kwargs) -> None: 176 | """Print a warning message. 177 | 178 | Args: 179 | message: The warning message to print. 180 | bold: Whether to make the text bold. 181 | **kwargs: Additional arguments to pass to print(). 182 | """ 183 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 184 | print(format_text(f"WARNING: {message}", Colors.YELLOW, bold), file=sys.stderr, **kwargs) 185 | 186 | def print_success(message: str, bold: bool = False, **kwargs) -> None: 187 | """Print a success message. 188 | 189 | Args: 190 | message: The success message to print. 191 | bold: Whether to make the text bold. 192 | **kwargs: Additional arguments to pass to print(). 193 | """ 194 | if VERBOSITY.value >= VerbosityLevel.QUIET.value: 195 | print(format_text(message, Colors.GREEN, bold), **kwargs) 196 | 197 | def print_info(message: str, bold: bool = False, **kwargs) -> None: 198 | """Print an informational message. 199 | 200 | Args: 201 | message: The informational message to print. 202 | bold: Whether to make the text bold. 203 | **kwargs: Additional arguments to pass to print(). 204 | """ 205 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 206 | print(format_text(message, Colors.BLUE, bold), **kwargs) 207 | 208 | def print_status(message: str, bold: bool = False, **kwargs) -> None: 209 | """Print a status message. 210 | 211 | Args: 212 | message: The status message to print. 213 | bold: Whether to make the text bold. 214 | **kwargs: Additional arguments to pass to print(). 215 | """ 216 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 217 | print(format_text(message, Colors.CYAN, bold), **kwargs) 218 | 219 | def print_result(message: str, bold: bool = True, **kwargs) -> None: 220 | """Print a result message. 221 | 222 | Args: 223 | message: The result message to print. 224 | bold: Whether to make the text bold. 225 | **kwargs: Additional arguments to pass to print(). 226 | """ 227 | if VERBOSITY.value >= VerbosityLevel.QUIET.value: 228 | print(format_text(message, Colors.MAGENTA, bold), **kwargs) 229 | 230 | def print_json(data: Any, pretty: bool = True, **kwargs) -> None: 231 | """Print data as JSON. 232 | 233 | Args: 234 | data: The data to print as JSON. 235 | pretty: Whether to format the JSON with indentation. 236 | **kwargs: Additional arguments to pass to print(). 237 | """ 238 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 239 | indent = 2 if pretty else None 240 | print(json.dumps(data, indent=indent), **kwargs) 241 | 242 | def print_banner(banner: str, **kwargs) -> None: 243 | """Print a banner. 244 | 245 | Args: 246 | banner: The banner to print. 247 | **kwargs: Additional arguments to pass to print(). 248 | """ 249 | if VERBOSITY.value >= VerbosityLevel.QUIET.value: 250 | print(format_text(banner, Colors.BRIGHT_CYAN), **kwargs) 251 | 252 | def print_section(title: str, **kwargs) -> None: 253 | """Print a section title. 254 | 255 | Args: 256 | title: The section title to print. 257 | **kwargs: Additional arguments to pass to print(). 258 | """ 259 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 260 | print(format_text(f"\n=== {title} ===", Colors.BRIGHT_WHITE, True), **kwargs) 261 | 262 | def print_summary(title: str, items: List[str], **kwargs) -> None: 263 | """Print a summary of items. 264 | 265 | Args: 266 | title: The summary title. 267 | items: The items to include in the summary. 268 | **kwargs: Additional arguments to pass to print(). 269 | """ 270 | if VERBOSITY.value >= VerbosityLevel.QUIET.value: 271 | print(format_text(f"\n{title}:", Colors.BRIGHT_WHITE, True), **kwargs) 272 | for i, item in enumerate(items, 1): 273 | print(format_text(f" {i}. {item}", Colors.WHITE), **kwargs) 274 | print("", **kwargs) 275 | 276 | def print_progress(current: int, total: int, prefix: str = "", suffix: str = "", bar_length: int = 50, **kwargs) -> None: 277 | """Print a progress bar. 278 | 279 | Args: 280 | current: The current progress value. 281 | total: The total progress value. 282 | prefix: Text to display before the progress bar. 283 | suffix: Text to display after the progress bar. 284 | bar_length: The length of the progress bar in characters. 285 | **kwargs: Additional arguments to pass to print(). 286 | """ 287 | if VERBOSITY.value >= VerbosityLevel.NORMAL.value: 288 | percent = float(current) / total 289 | filled_length = int(bar_length * percent) 290 | bar = "█" * filled_length + "-" * (bar_length - filled_length) 291 | progress_str = f"{prefix} |{bar}| {current}/{total} {suffix}" 292 | print(format_text(progress_str, Colors.CYAN), end="\r", **kwargs) 293 | if current >= total: 294 | print() 295 | -------------------------------------------------------------------------------- /phantomfuzzer/ml/training/data_loader.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | Data Loader for ML Training. 6 | 7 | This module provides utilities for loading and preprocessing data 8 | for training machine learning models in PhantomFuzzer. 9 | """ 10 | 11 | import os 12 | import glob 13 | import random 14 | import hashlib 15 | from pathlib import Path 16 | from typing import List, Dict, Tuple, Optional, Union, Any, Set 17 | 18 | # Local imports 19 | from phantomfuzzer.utils.logging import get_logger 20 | 21 | 22 | class DataLoader: 23 | """Data loader for machine learning model training. 24 | 25 | This class handles loading and preprocessing data for training 26 | machine learning models, particularly for anomaly detection. 27 | """ 28 | 29 | def __init__(self, config: Optional[Dict[str, Any]] = None): 30 | """Initialize the data loader. 31 | 32 | Args: 33 | config: Configuration parameters for data loading. 34 | """ 35 | self.logger = get_logger(__name__) 36 | self.config = config or {} 37 | 38 | # Default configuration 39 | self.benign_ratio = self.config.get('benign_ratio', 0.7) 40 | self.max_files = self.config.get('max_files', 10000) 41 | self.file_extensions = self.config.get('file_extensions', None) # None means all extensions 42 | self.min_file_size = self.config.get('min_file_size', 10) # bytes 43 | self.max_file_size = self.config.get('max_file_size', 10 * 1024 * 1024) # 10 MB 44 | 45 | # Cache to avoid duplicate files 46 | self.file_hashes: Set[str] = set() 47 | 48 | def load_dataset(self, 49 | benign_dirs: List[Union[str, Path]], 50 | malicious_dirs: Optional[List[Union[str, Path]]] = None) -> Tuple[List[str], Optional[List[str]]]: 51 | """Load a dataset of benign and optionally malicious files. 52 | 53 | Args: 54 | benign_dirs: List of directories containing benign files. 55 | malicious_dirs: Optional list of directories containing malicious files. 56 | 57 | Returns: 58 | A tuple of (benign_files, malicious_files) where each is a list of file paths. 59 | If malicious_dirs is None, malicious_files will be None. 60 | """ 61 | # Load benign files 62 | benign_files = self._load_files_from_dirs(benign_dirs) 63 | self.logger.info(f"Loaded {len(benign_files)} benign files") 64 | 65 | # Load malicious files if provided 66 | malicious_files = None 67 | if malicious_dirs: 68 | malicious_files = self._load_files_from_dirs(malicious_dirs) 69 | self.logger.info(f"Loaded {len(malicious_files)} malicious files") 70 | 71 | return benign_files, malicious_files 72 | 73 | def preprocess_files(self, 74 | benign_files: List[Union[str, Path]], 75 | malicious_files: Optional[List[Union[str, Path]]] = None) -> List[Dict[str, Any]]: 76 | """Preprocess files for training. 77 | 78 | Args: 79 | benign_files: List of paths to benign files. 80 | malicious_files: Optional list of paths to malicious files. 81 | 82 | Returns: 83 | A list of preprocessed data items, each containing file path and features. 84 | """ 85 | dataset = [] 86 | 87 | # Process benign files 88 | for file_path in benign_files: 89 | try: 90 | item = { 91 | 'file_path': str(file_path), 92 | 'label': 0 # 0 for benign 93 | } 94 | dataset.append(item) 95 | except Exception as e: 96 | self.logger.error(f"Error preprocessing benign file {file_path}: {str(e)}") 97 | 98 | # Process malicious files if provided 99 | if malicious_files: 100 | for file_path in malicious_files: 101 | try: 102 | item = { 103 | 'file_path': str(file_path), 104 | 'label': 1 # 1 for malicious 105 | } 106 | dataset.append(item) 107 | except Exception as e: 108 | self.logger.error(f"Error preprocessing malicious file {file_path}: {str(e)}") 109 | 110 | self.logger.info(f"Preprocessed {len(dataset)} files") 111 | return dataset 112 | 113 | def _load_files_from_dirs(self, directories: List[Union[str, Path]]) -> List[str]: 114 | """Load files from a list of directories. 115 | 116 | Args: 117 | directories: List of directories to load files from. 118 | 119 | Returns: 120 | List of file paths. 121 | """ 122 | files = [] 123 | self.file_hashes.clear() 124 | 125 | for directory in directories: 126 | directory = Path(directory) 127 | if not directory.exists() or not directory.is_dir(): 128 | self.logger.warning(f"Directory {directory} does not exist or is not a directory") 129 | continue 130 | 131 | # Get all files in the directory (recursively) 132 | pattern = '**/*' if self.file_extensions is None else f"**/*.{{{','.join(self.file_extensions)}}}" 133 | for file_path in directory.glob(pattern): 134 | if len(files) >= self.max_files: 135 | self.logger.info(f"Reached maximum number of files ({self.max_files})") 136 | break 137 | 138 | if not file_path.is_file(): 139 | continue 140 | 141 | # Check file size 142 | file_size = file_path.stat().st_size 143 | if file_size < self.min_file_size or file_size > self.max_file_size: 144 | continue 145 | 146 | # Check if we've already seen this file (by hash) 147 | if self._is_duplicate(file_path): 148 | continue 149 | 150 | files.append(str(file_path)) 151 | 152 | return files 153 | 154 | def _is_duplicate(self, file_path: Path) -> bool: 155 | """Check if a file is a duplicate based on its hash. 156 | 157 | Args: 158 | file_path: Path to the file to check. 159 | 160 | Returns: 161 | True if the file is a duplicate, False otherwise. 162 | """ 163 | try: 164 | # Calculate file hash 165 | hasher = hashlib.md5() 166 | with open(file_path, 'rb') as f: 167 | # Read in chunks to handle large files 168 | for chunk in iter(lambda: f.read(4096), b""): 169 | hasher.update(chunk) 170 | file_hash = hasher.hexdigest() 171 | 172 | # Check if we've seen this hash before 173 | if file_hash in self.file_hashes: 174 | return True 175 | 176 | # Add hash to set 177 | self.file_hashes.add(file_hash) 178 | return False 179 | 180 | except Exception as e: 181 | self.logger.error(f"Error calculating hash for {file_path}: {str(e)}") 182 | return True # Treat as duplicate to skip problematic files 183 | 184 | def split_dataset(self, 185 | files: List[str], 186 | train_ratio: float = 0.8, 187 | val_ratio: float = 0.1, 188 | test_ratio: float = 0.1) -> Tuple[List[str], List[str], List[str]]: 189 | """Split a dataset into training, validation, and test sets. 190 | 191 | Args: 192 | files: List of file paths. 193 | train_ratio: Ratio of files to use for training. 194 | val_ratio: Ratio of files to use for validation. 195 | test_ratio: Ratio of files to use for testing. 196 | 197 | Returns: 198 | A tuple of (train_files, val_files, test_files). 199 | """ 200 | # Ensure ratios sum to 1 201 | total_ratio = train_ratio + val_ratio + test_ratio 202 | if abs(total_ratio - 1.0) > 1e-6: 203 | self.logger.warning(f"Ratios do not sum to 1 ({total_ratio}), normalizing") 204 | train_ratio /= total_ratio 205 | val_ratio /= total_ratio 206 | test_ratio /= total_ratio 207 | 208 | # Shuffle files 209 | shuffled_files = files.copy() 210 | random.shuffle(shuffled_files) 211 | 212 | # Calculate split indices 213 | n_files = len(shuffled_files) 214 | train_end = int(n_files * train_ratio) 215 | val_end = train_end + int(n_files * val_ratio) 216 | 217 | # Split dataset 218 | train_files = shuffled_files[:train_end] 219 | val_files = shuffled_files[train_end:val_end] 220 | test_files = shuffled_files[val_end:] 221 | 222 | self.logger.info(f"Split dataset: {len(train_files)} train, {len(val_files)} validation, {len(test_files)} test") 223 | 224 | return train_files, val_files, test_files 225 | 226 | def balance_dataset(self, 227 | benign_files: List[str], 228 | malicious_files: List[str], 229 | benign_ratio: Optional[float] = None) -> Tuple[List[str], List[str]]: 230 | """Balance a dataset of benign and malicious files. 231 | 232 | Args: 233 | benign_files: List of benign file paths. 234 | malicious_files: List of malicious file paths. 235 | benign_ratio: Ratio of benign files in the final dataset. 236 | If None, use the default ratio from config. 237 | 238 | Returns: 239 | A tuple of (balanced_benign_files, balanced_malicious_files). 240 | """ 241 | if benign_ratio is None: 242 | benign_ratio = self.benign_ratio 243 | 244 | # Calculate target counts 245 | total_files = min(len(benign_files) + len(malicious_files), self.max_files) 246 | target_benign = int(total_files * benign_ratio) 247 | target_malicious = total_files - target_benign 248 | 249 | # Sample files 250 | balanced_benign = random.sample(benign_files, min(target_benign, len(benign_files))) 251 | balanced_malicious = random.sample(malicious_files, min(target_malicious, len(malicious_files))) 252 | 253 | self.logger.info(f"Balanced dataset: {len(balanced_benign)} benign, {len(balanced_malicious)} malicious") 254 | 255 | return balanced_benign, balanced_malicious 256 | 257 | def get_file_metadata(self, file_path: Union[str, Path]) -> Dict[str, Any]: 258 | """Get metadata for a file. 259 | 260 | Args: 261 | file_path: Path to the file. 262 | 263 | Returns: 264 | Dictionary of file metadata. 265 | """ 266 | file_path = Path(file_path) 267 | 268 | try: 269 | # Get file stats 270 | stats = file_path.stat() 271 | 272 | # Get file extension 273 | extension = file_path.suffix.lower()[1:] if file_path.suffix else '' 274 | 275 | # Get file type using magic 276 | file_type = 'unknown' 277 | try: 278 | import magic 279 | file_type = magic.from_file(str(file_path)) 280 | except ImportError: 281 | self.logger.warning("python-magic not installed, file type detection limited") 282 | 283 | # Return metadata 284 | return { 285 | 'path': str(file_path), 286 | 'size': stats.st_size, 287 | 'modified_time': stats.st_mtime, 288 | 'extension': extension, 289 | 'type': file_type 290 | } 291 | 292 | except Exception as e: 293 | self.logger.error(f"Error getting metadata for {file_path}: {str(e)}") 294 | return { 295 | 'path': str(file_path), 296 | 'error': str(e) 297 | } 298 | --------------------------------------------------------------------------------