-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
162 lines (136 loc) · 6.65 KB
/
main.py
File metadata and controls
162 lines (136 loc) · 6.65 KB
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
import argparse
import os
import json
import sys
from urllib.parse import urlparse
from mirror import WebsiteMirror
from analysis import AnalysisEngine, save_report
def load_config(config_file):
"""Load authentication config from a JSON file."""
if not os.path.exists(config_file):
print(f"Warning: Config file {config_file} not found")
return {}
try:
with open(config_file, 'r', encoding='utf-8') as f:
config = json.load(f)
return config
except json.JSONDecodeError as e:
print(f"Error: Invalid JSON in config file {config_file}: {e}")
sys.exit(1)
except Exception as e:
print(f"Error loading config file {config_file}: {e}")
sys.exit(1)
def validate_url(url):
"""Validate that the URL is properly formatted."""
try:
result = urlparse(url)
if not all([result.scheme, result.netloc]):
return False
if result.scheme not in ['http', 'https']:
return False
return True
except Exception:
return False
def main():
parser = argparse.ArgumentParser(description="Web Vulnerability Scanner (Offline Mode)")
parser.add_argument("--url", help="URL of the website to mirror and scan (e.g., http://example.com)")
parser.add_argument("--dir", help="Directory of an already mirrored website to scan")
parser.add_argument("--output", default="vuln_report.json", help="Output report file (default: vuln_report.json)")
parser.add_argument("--username", help="Username for form-based authentication")
parser.add_argument("--password", help="Password for form-based authentication")
parser.add_argument("--login-url", help="Login URL for form-based authentication (e.g., http://example.com/login)")
parser.add_argument("--token", help="Access token for token-based authentication (e.g., Bearer token)")
parser.add_argument("--config", help="JSON config file with authentication details")
parser.add_argument("--no-verification", action="store_true", help="Disable verification pipeline (Phase 1)")
parser.add_argument("--active-testing", action="store_true", help="Enable active vulnerability testing (Phase 1)")
parser.add_argument("--intelligence", action="store_true", help="Enable intelligent analysis with taint tracking and data flow (Phase 2)")
parser.add_argument("--osint", action="store_true", help="Enable OSINT data extraction (emails, phones, API keys, etc.)")
args = parser.parse_args()
# Validate arguments
if not args.url and not args.dir:
parser.error("Either --url or --dir must be provided")
if args.url and args.dir:
parser.error("Cannot use both --url and --dir")
# Validate URL format if provided
if args.url and not validate_url(args.url):
parser.error(f"Invalid URL format: {args.url}. Must be http:// or https://")
# Validate directory exists if provided
if args.dir and not os.path.exists(args.dir):
parser.error(f"Directory does not exist: {args.dir}")
if args.dir and not os.path.isdir(args.dir):
parser.error(f"Path is not a directory: {args.dir}")
if (args.username or args.password) and not args.login_url:
parser.error("--login-url is required when using --username or --password")
if args.login_url and not validate_url(args.login_url):
parser.error(f"Invalid login URL format: {args.login_url}. Must be http:// or https://")
if args.token and (args.username or args.password or args.login_url):
parser.error("Cannot use --token with --username, --password, or --login-url")
# Load config file if provided
config = load_config(args.config) if args.config else {}
# Prioritize command-line arguments over config file
auth_params = {
'username': args.username or config.get('username'),
'password': args.password or config.get('password'),
'login_url': args.login_url or config.get('login_url'),
'token': args.token or config.get('token')
}
# Initialize mirroring module
output_dir = args.dir if args.dir else "cloned_site"
mirror = WebsiteMirror(output_dir, **auth_params)
# Mirror website if URL is provided
files = []
if args.url:
print(f"Mirroring {args.url}...")
if not mirror.clone(args.url):
print("Error: Mirroring failed. Please check the URL and try again.")
sys.exit(1)
files = mirror.get_cloned_files()
else:
print(f"Scanning existing directory {args.dir}...")
files = mirror.get_cloned_files()
if not files:
print("No files found for analysis. Ensure the directory contains supported file types.")
sys.exit(1)
print(f"Found {len(files)} file(s) to analyze...")
# Initialize analysis engine and load plugins
enable_verification = not args.no_verification
enable_active = args.active_testing
enable_intelligence = args.intelligence
enable_osint = args.osint
if enable_active:
print("⚠ WARNING: Active testing enabled - payloads will be sent to target")
print(" Ensure you have permission to test the target application")
if enable_intelligence:
print("ℹ️ Phase 2 Intelligence enabled: Taint analysis and data flow tracking active")
if enable_osint:
print("🔍 OSINT Extraction enabled: Collecting emails, phones, API keys, and other intelligence")
print(" ⚠️ Use responsibly - only scan targets you have permission to test")
engine = AnalysisEngine(
enable_verification=enable_verification,
enable_active_testing=enable_active,
enable_intelligence=enable_intelligence
)
plugin_dir = os.path.join(os.path.dirname(__file__), "detections")
engine.load_plugins(plugin_dir)
# Filter plugins based on flags
if not enable_osint:
# Remove OSINT plugin if not enabled
engine.plugins = [p for p in engine.plugins if not p.__class__.__name__ == 'OSINTIntelligencePlugin']
if not engine.plugins:
print("Warning: No analysis plugins loaded. Check the detections directory.")
# Analyze files
print("Running analysis...")
findings = engine.analyze_files(files)
# Save and display results
save_report(findings, args.output)
print(f"\n{'='*60}")
print(f"Scan Complete! Found {len(findings)} potential issue(s)")
print(f"{'='*60}")
if findings:
for finding in findings:
print(f"- {finding['type']} in {finding['file']} (Line {finding['line']}): {finding['details']} [Severity: {finding['severity']}]")
else:
print("No vulnerabilities detected.")
print(f"\nFull report saved to: {args.output}")
if __name__ == "__main__":
main()