-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaegis.py
More file actions
124 lines (106 loc) · 4.2 KB
/
aegis.py
File metadata and controls
124 lines (106 loc) · 4.2 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
#!/usr/bin/env python3
"""
Aegis 2025 — Main CLI entrypoint
Usage:
python main.py http://target.com
python main.py http://target.com --threads 20 --timeout 10 --ai
python main.py http://target.com --modules xss sqli headers lfi
"""
import argparse
import os
import sys
from config import DEFAULT_THREADS, DEFAULT_TIMEOUT, DEFAULT_DELAY, DEFAULT_OUTPUT_DIR
from core.http_client import normalize_url
from core.engine import ScanEngine, ALL_MODULES
from core import reporter
from utils.logging_setup import setup_logging
def parse_args():
parser = argparse.ArgumentParser(
prog="aegis",
description="Aegis 2025 — Full OWASP Web Vulnerability Scanner",
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
"url", nargs="?",
help="Target URL (e.g. http://example.com)",
)
parser.add_argument(
"--threads", type=int, default=DEFAULT_THREADS,
help=f"Worker threads (default: {DEFAULT_THREADS})",
)
parser.add_argument(
"--timeout", type=int, default=DEFAULT_TIMEOUT,
help=f"Request timeout seconds (default: {DEFAULT_TIMEOUT})",
)
parser.add_argument(
"--delay", type=float, default=DEFAULT_DELAY,
help=f"Delay between requests per thread (default: {DEFAULT_DELAY})",
)
parser.add_argument(
"--output", default=DEFAULT_OUTPUT_DIR,
help=f"Output directory for reports (default: {DEFAULT_OUTPUT_DIR})",
)
parser.add_argument(
"--modules", nargs="+", choices=list(ALL_MODULES.keys()),
help=(
"Run only specific modules. Choices:\n " +
" ".join(ALL_MODULES.keys())
),
)
parser.add_argument(
"--ai", action="store_true",
help="Enable AI-powered post-scan analysis via Claude API",
)
parser.add_argument(
"--no-pdf", action="store_true",
help="Skip PDF report generation",
)
parser.add_argument(
"--verbose", action="store_true",
help="Enable verbose logging to console",
)
return parser.parse_args()
def main():
args = parse_args()
# ── Target URL ──────────────────────────────────────
if args.url:
target = normalize_url(args.url)
else:
raw = input("Enter target URL (e.g. http://example.com): ").strip()
target = normalize_url(raw)
# ── Output dir ──────────────────────────────────────
os.makedirs(args.output, exist_ok=True)
# ── Logging ─────────────────────────────────────────
setup_logging(args.output, verbose=args.verbose)
# ── Scan ────────────────────────────────────────────
engine = ScanEngine(
target_url=target,
threads=args.threads,
delay=args.delay,
modules=args.modules,
)
try:
report = engine.run()
except KeyboardInterrupt:
print("\n[!] Interrupted — saving partial results...")
report = engine.report
# ── AI Analysis ─────────────────────────────────────
ai_text = ""
if args.ai:
from ai.analyzer import analyze
ai_text = analyze(report, target)
if ai_text:
print("\n" + "─" * 60)
print(ai_text)
print("─" * 60)
# ── Reports ─────────────────────────────────────────
reporter.generate_json(report, args.output, target)
if not args.no_pdf:
reporter.generate_pdf(report, args.output, target, ai_text)
reporter.generate_html(report, args.output, target, ai_text)
print(f"\n[✓] All reports saved to: {os.path.abspath(args.output)}/")
if __name__ == "__main__":
# Suppress InsecureRequestWarning for self-signed certs
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
main()