-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
242 lines (206 loc) Β· 9.5 KB
/
main.py
File metadata and controls
242 lines (206 loc) Β· 9.5 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
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
#!/usr/bin/env python3
"""
Enhanced Web Application Security Testing Tool with Authentication Support
"""
import argparse
import sys
import json
import logging
from modules.xss_scanner import XSSScanner
from modules.csrf_scanner import CSRFScanner
from modules.crawler import WebCrawler
from modules.reporter import Reporter
from modules.auth_handler import AuthHandler
from modules.authenticated_scanner import AuthenticatedScanner
def setup_logging(verbose=False):
"""Setup logging configuration"""
level = logging.DEBUG if verbose else logging.INFO
logging.basicConfig(
level=level,
format='%(asctime)s - %(levelname)s - %(message)s',
handlers=[
logging.StreamHandler(sys.stdout)
]
)
def parse_auth_config(auth_string):
"""Parse authentication configuration string"""
if not auth_string:
return None
try:
# Try to parse as JSON first
return json.loads(auth_string)
except json.JSONDecodeError:
# Parse as simple key=value format
config = {}
for pair in auth_string.split(','):
if '=' in pair:
key, value = pair.strip().split('=', 1)
config[key.strip()] = value.strip()
return config
def main():
parser = argparse.ArgumentParser(
description='Web Application Security Testing Tool with Authentication Support',
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
Authentication Examples:
Form-based login:
--auth '{"type":"form","login_url":"http://example.com/login","username":"admin","password":"password"}'
Basic authentication:
--auth '{"type":"basic","url":"http://example.com","username":"admin","password":"password"}'
Cookie-based:
--auth '{"type":"cookies","cookies":"PHPSESSID=abc123;user_token=xyz789"}'
Header-based:
--auth '{"type":"headers","headers":"Authorization:Bearer token123,X-API-Key:key456"}'
Simple format:
--auth 'type=form,login_url=http://example.com/login,username=admin,password=password'
"""
)
parser.add_argument('target', help='Target URL to test')
parser.add_argument('--xss', action='store_true', help='Test for XSS vulnerabilities')
parser.add_argument('--csrf', action='store_true', help='Test for CSRF vulnerabilities')
parser.add_argument('--all', action='store_true', help='Run all available tests')
parser.add_argument('--session', action='store_true', help='Test session management (requires auth)')
parser.add_argument('--privilege', action='store_true', help='Test privilege escalation (requires auth)')
# Authentication options
parser.add_argument('--auth', help='Authentication configuration (JSON or key=value format)')
parser.add_argument('--login-url', help='Login page URL for form-based authentication')
parser.add_argument('--username', help='Username for authentication')
parser.add_argument('--password', help='Password for authentication')
parser.add_argument('--cookies', help='Authentication cookies (name1=value1;name2=value2)')
parser.add_argument('--headers', help='Authentication headers (Header1:Value1,Header2:Value2)')
# Output options
parser.add_argument('--output', '-o', help='Output file for report')
parser.add_argument('--format', choices=['markdown', 'json', 'html', 'csv'],
default='markdown', help='Report format')
parser.add_argument('--verbose', '-v', action='store_true', help='Verbose output')
# Scanning options
parser.add_argument('--depth', type=int, default=2, help='Crawling depth (default: 2)')
parser.add_argument('--delay', type=float, default=0.1, help='Delay between requests (default: 0.1)')
parser.add_argument('--timeout', type=int, default=10, help='Request timeout (default: 10)')
args = parser.parse_args()
# Setup logging
setup_logging(args.verbose)
# Validate arguments
if not any([args.xss, args.csrf, args.all, args.session, args.privilege]):
parser.error("At least one test type must be specified")
# Parse authentication configuration
auth_config = None
if args.auth:
auth_config = parse_auth_config(args.auth)
elif args.login_url and args.username and args.password:
auth_config = {
'type': 'form',
'login_url': args.login_url,
'username': args.username,
'password': args.password
}
elif args.cookies:
auth_config = {
'type': 'cookies',
'cookies': args.cookies
}
elif args.headers:
auth_config = {
'type': 'headers',
'headers': args.headers
}
# Check if authentication is required for certain tests
if (args.session or args.privilege) and not auth_config:
parser.error("Session and privilege escalation tests require authentication")
print(f"π Starting security scan of {args.target}")
# Initialize components
auth_handler = AuthHandler()
authenticated_scanner = AuthenticatedScanner(auth_handler)
results = {}
# Setup authentication if provided
if auth_config:
print("π Setting up authentication...")
if authenticated_scanner.setup_authentication(auth_config):
print("β
Authentication successful")
auth_info = auth_handler.get_auth_info()
print(f" - Login URL: {auth_info.get('login_url', 'N/A')}")
print(f" - Cookies: {len(auth_info.get('cookies', []))}")
print(f" - Headers: {len(auth_info.get('headers', []))}")
else:
print("β Authentication failed")
if args.session or args.privilege:
print("Cannot proceed with session/privilege tests without authentication")
sys.exit(1)
# Initialize crawler with authenticated session if available
session = auth_handler.get_authenticated_session()
crawler = WebCrawler(session=session)
# Discover endpoints
print("π·οΈ Crawling application...")
endpoints = crawler.crawl(args.target, max_depth=args.depth)
print(f" Found {len(endpoints)} endpoints")
# If authenticated, also scan protected endpoints
if auth_handler.logged_in:
print("π Scanning authenticated endpoints...")
auth_endpoints = authenticated_scanner.scan_authenticated_endpoints(args.target, args.depth)
endpoints.extend(auth_endpoints)
print(f" Found {len(auth_endpoints)} additional authenticated endpoints")
# Run XSS tests
if args.xss or args.all:
print("π¨ Testing for XSS vulnerabilities...")
xss_scanner = XSSScanner(session=session)
xss_results = xss_scanner.scan_endpoints(endpoints)
results['xss'] = xss_results
print(f" Found {len(xss_results)} XSS vulnerabilities")
# Run CSRF tests
if args.csrf or args.all:
print("π‘οΈ Testing for CSRF vulnerabilities...")
csrf_scanner = CSRFScanner(session=session)
csrf_results = csrf_scanner.scan_endpoints(endpoints)
results['csrf'] = csrf_results
print(f" Found {len(csrf_results)} CSRF vulnerabilities")
# Run session management tests
if args.session and auth_handler.logged_in:
print("π Testing session management...")
session_results = authenticated_scanner.test_session_management(args.target)
results['session'] = session_results
print(f" Found {len(session_results)} session management issues")
# Run privilege escalation tests
if args.privilege and auth_handler.logged_in:
print("β¬οΈ Testing for privilege escalation...")
privilege_results = authenticated_scanner.test_privilege_escalation(endpoints)
results['privilege_escalation'] = privilege_results
print(f" Found {len(privilege_results)} privilege escalation issues")
# Generate report
print("π Generating report...")
reporter = Reporter()
if args.format == 'json':
report_content = reporter.generate_json_report(results, args.target)
elif args.format == 'html':
report_content = reporter.generate_html_report(results, args.target)
elif args.format == 'csv':
report_content = reporter.generate_csv_report(results, args.target)
else: # markdown
report_content = reporter.generate_report(results, args.target)
# Output report
if args.output:
output_path = args.output
if not output_path.startswith("output/"):
output_path = f"output/{output_path}"
try:
filename = reporter.save_report(report_content, output_path)
print(f"π Report saved to: {filename}")
except Exception as e:
print(f"β Failed to save report: {e}")
sys.exit(1)
else:
print("\n" + "="*80)
print(report_content)
# Summary
total_vulns = sum(len(vulns) for vulns in results.values())
high_vulns = sum(1 for vulns in results.values() for vuln in vulns if vuln.get('severity') == 'High')
print(f"\nπ― Scan completed!")
print(f" Total vulnerabilities: {total_vulns}")
print(f" High severity: {high_vulns}")
if auth_handler.logged_in:
print(f" Authenticated scan: β
")
session_info = authenticated_scanner.get_session_info()
print(f" Active cookies: {len(session_info['cookies'])}")
# Exit with appropriate code
sys.exit(1 if high_vulns > 0 else 0)
if __name__ == "__main__":
main()