zen-ai-pentest 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- agents/__init__.py +28 -0
- agents/agent_base.py +239 -0
- agents/agent_orchestrator.py +346 -0
- agents/analysis_agent.py +225 -0
- agents/cli.py +258 -0
- agents/exploit_agent.py +224 -0
- agents/integration.py +211 -0
- agents/post_scan_agent.py +937 -0
- agents/react_agent.py +384 -0
- agents/react_agent_enhanced.py +616 -0
- agents/react_agent_vm.py +298 -0
- agents/research_agent.py +176 -0
- api/__init__.py +11 -0
- api/auth.py +123 -0
- api/main.py +1027 -0
- api/schemas.py +357 -0
- api/websocket.py +97 -0
- autonomous/__init__.py +122 -0
- autonomous/agent.py +253 -0
- autonomous/agent_loop.py +1370 -0
- autonomous/exploit_validator.py +1537 -0
- autonomous/memory.py +448 -0
- autonomous/react.py +339 -0
- autonomous/tool_executor.py +488 -0
- backends/__init__.py +16 -0
- backends/chatgpt_direct.py +133 -0
- backends/claude_direct.py +130 -0
- backends/duckduckgo.py +138 -0
- backends/openrouter.py +120 -0
- benchmarks/__init__.py +149 -0
- benchmarks/benchmark_engine.py +904 -0
- benchmarks/ci_benchmark.py +785 -0
- benchmarks/comparison.py +729 -0
- benchmarks/metrics.py +553 -0
- benchmarks/run_benchmarks.py +809 -0
- ci_cd/__init__.py +2 -0
- core/__init__.py +17 -0
- core/async_pool.py +282 -0
- core/asyncio_fix.py +222 -0
- core/cache.py +472 -0
- core/container.py +277 -0
- core/database.py +114 -0
- core/input_validator.py +353 -0
- core/models.py +288 -0
- core/orchestrator.py +611 -0
- core/plugin_manager.py +571 -0
- core/rate_limiter.py +405 -0
- core/secure_config.py +328 -0
- core/shield_integration.py +296 -0
- modules/__init__.py +46 -0
- modules/cve_database.py +362 -0
- modules/exploit_assist.py +330 -0
- modules/nuclei_integration.py +480 -0
- modules/osint.py +604 -0
- modules/protonvpn.py +554 -0
- modules/recon.py +165 -0
- modules/sql_injection_db.py +826 -0
- modules/tool_orchestrator.py +498 -0
- modules/vuln_scanner.py +292 -0
- modules/wordlist_generator.py +566 -0
- risk_engine/__init__.py +99 -0
- risk_engine/business_impact.py +267 -0
- risk_engine/business_impact_calculator.py +563 -0
- risk_engine/cvss.py +156 -0
- risk_engine/epss.py +190 -0
- risk_engine/example_usage.py +294 -0
- risk_engine/false_positive_engine.py +1073 -0
- risk_engine/scorer.py +304 -0
- web_ui/backend/main.py +471 -0
- zen_ai_pentest-2.0.0.dist-info/METADATA +795 -0
- zen_ai_pentest-2.0.0.dist-info/RECORD +75 -0
- zen_ai_pentest-2.0.0.dist-info/WHEEL +5 -0
- zen_ai_pentest-2.0.0.dist-info/entry_points.txt +2 -0
- zen_ai_pentest-2.0.0.dist-info/licenses/LICENSE +21 -0
- zen_ai_pentest-2.0.0.dist-info/top_level.txt +10 -0
modules/vuln_scanner.py
ADDED
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Vulnerability Scanner Module
|
|
4
|
+
AI-powered vulnerability analysis and scanning
|
|
5
|
+
Author: SHAdd0WTAka
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import asyncio
|
|
9
|
+
import logging
|
|
10
|
+
import re
|
|
11
|
+
from dataclasses import dataclass
|
|
12
|
+
from typing import Dict, List, Optional, Tuple
|
|
13
|
+
|
|
14
|
+
logger = logging.getLogger("ZenAI")
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass
|
|
18
|
+
class Vulnerability:
|
|
19
|
+
name: str
|
|
20
|
+
severity: str # Critical, High, Medium, Low, Info
|
|
21
|
+
description: str
|
|
22
|
+
evidence: str
|
|
23
|
+
remediation: str
|
|
24
|
+
cvss_score: Optional[float] = None
|
|
25
|
+
cve_ids: List[str] = None
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class VulnScannerModule:
|
|
29
|
+
"""
|
|
30
|
+
Intelligent vulnerability scanner with LLM analysis
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
SEVERITY_ORDER = {"Critical": 5, "High": 4, "Medium": 3, "Low": 2, "Info": 1}
|
|
34
|
+
|
|
35
|
+
def __init__(self, orchestrator):
|
|
36
|
+
self.orchestrator = orchestrator
|
|
37
|
+
self.vulnerabilities = []
|
|
38
|
+
|
|
39
|
+
async def analyze_nmap_output(self, nmap_output: str) -> List[Vulnerability]:
|
|
40
|
+
"""
|
|
41
|
+
Analyze nmap scan results with LLM
|
|
42
|
+
"""
|
|
43
|
+
prompt = f"""
|
|
44
|
+
Analyze this nmap scan output and identify vulnerabilities:
|
|
45
|
+
|
|
46
|
+
```
|
|
47
|
+
{nmap_output[:3000]} # Truncate for token limits
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
For each vulnerability found, provide:
|
|
51
|
+
1. Name
|
|
52
|
+
2. Severity (Critical/High/Medium/Low/Info)
|
|
53
|
+
3. Description
|
|
54
|
+
4. Evidence from scan
|
|
55
|
+
5. Remediation steps
|
|
56
|
+
6. CVE IDs if applicable
|
|
57
|
+
|
|
58
|
+
Format each finding as:
|
|
59
|
+
[VULN]
|
|
60
|
+
Name: <name>
|
|
61
|
+
Severity: <severity>
|
|
62
|
+
Description: <desc>
|
|
63
|
+
Evidence: <evidence>
|
|
64
|
+
Remediation: <fix>
|
|
65
|
+
CVE: <cve_ids>
|
|
66
|
+
[/VULN]
|
|
67
|
+
"""
|
|
68
|
+
|
|
69
|
+
response = await self.orchestrator.process(prompt)
|
|
70
|
+
vulnerabilities = self._parse_vulnerabilities(response.content)
|
|
71
|
+
|
|
72
|
+
logger.info(
|
|
73
|
+
f"[VulnScanner] Found {len(vulnerabilities)} vulnerabilities in nmap output"
|
|
74
|
+
)
|
|
75
|
+
return vulnerabilities
|
|
76
|
+
|
|
77
|
+
async def analyze_web_headers(
|
|
78
|
+
self, headers: Dict[str, str], url: str
|
|
79
|
+
) -> List[Vulnerability]:
|
|
80
|
+
"""
|
|
81
|
+
Analyze HTTP headers for security issues
|
|
82
|
+
"""
|
|
83
|
+
headers_str = "\n".join([f"{k}: {v}" for k, v in headers.items()])
|
|
84
|
+
|
|
85
|
+
prompt = f"""
|
|
86
|
+
Analyze these HTTP response headers for security vulnerabilities:
|
|
87
|
+
URL: {url}
|
|
88
|
+
|
|
89
|
+
```
|
|
90
|
+
{headers_str}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Check for:
|
|
94
|
+
- Missing security headers (HSTS, CSP, X-Frame-Options, etc.)
|
|
95
|
+
- Information disclosure (Server version, X-Powered-By)
|
|
96
|
+
- CORS misconfigurations
|
|
97
|
+
- Cookie security flags
|
|
98
|
+
|
|
99
|
+
List each finding with severity and remediation.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
response = await self.orchestrator.process(prompt)
|
|
103
|
+
return self._parse_vulnerabilities(response.content)
|
|
104
|
+
|
|
105
|
+
async def analyze_web_page(
|
|
106
|
+
self, html_content: str, url: str
|
|
107
|
+
) -> List[Vulnerability]:
|
|
108
|
+
"""
|
|
109
|
+
Analyze web page content for vulnerabilities
|
|
110
|
+
"""
|
|
111
|
+
# Extract potentially interesting parts
|
|
112
|
+
forms = re.findall(r"<form.*?</form>", html_content, re.DOTALL | re.IGNORECASE)
|
|
113
|
+
scripts = re.findall(
|
|
114
|
+
r"<script.*?</script>", html_content, re.DOTALL | re.IGNORECASE
|
|
115
|
+
)
|
|
116
|
+
comments = re.findall(r"<!--.*?-->", html_content, re.DOTALL)
|
|
117
|
+
|
|
118
|
+
analysis_input = f"""
|
|
119
|
+
Forms found: {len(forms)}
|
|
120
|
+
Scripts found: {len(scripts)}
|
|
121
|
+
HTML comments: {len(comments)}
|
|
122
|
+
|
|
123
|
+
Sample forms:
|
|
124
|
+
{chr(10).join([f[:500] for f in forms[:3]])}
|
|
125
|
+
|
|
126
|
+
Sample comments (potential info disclosure):
|
|
127
|
+
{chr(10).join([c[:300] for c in comments[:5] if len(c) > 10])}
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
prompt = f"""
|
|
131
|
+
Analyze this web page content for vulnerabilities:
|
|
132
|
+
URL: {url}
|
|
133
|
+
|
|
134
|
+
{analysis_input}
|
|
135
|
+
|
|
136
|
+
Look for:
|
|
137
|
+
- Insecure form submissions (no CSRF tokens)
|
|
138
|
+
- Hardcoded credentials or API keys in comments
|
|
139
|
+
- Sensitive information in HTML comments
|
|
140
|
+
- Inline scripts (XSS potential)
|
|
141
|
+
- File upload forms without restrictions
|
|
142
|
+
- Autocomplete enabled on sensitive fields
|
|
143
|
+
|
|
144
|
+
Provide findings with severity and remediation.
|
|
145
|
+
"""
|
|
146
|
+
|
|
147
|
+
response = await self.orchestrator.process(prompt)
|
|
148
|
+
return self._parse_vulnerabilities(response.content)
|
|
149
|
+
|
|
150
|
+
async def check_cve_database(
|
|
151
|
+
self, service: str, version: str
|
|
152
|
+
) -> List[Vulnerability]:
|
|
153
|
+
"""
|
|
154
|
+
Query LLM for known CVEs for a service/version
|
|
155
|
+
"""
|
|
156
|
+
prompt = f"""
|
|
157
|
+
List known vulnerabilities (CVEs) for:
|
|
158
|
+
Service: {service}
|
|
159
|
+
Version: {version}
|
|
160
|
+
|
|
161
|
+
For each CVE provide:
|
|
162
|
+
- CVE ID
|
|
163
|
+
- CVSS Score
|
|
164
|
+
- Severity
|
|
165
|
+
- Description
|
|
166
|
+
- Exploit availability
|
|
167
|
+
|
|
168
|
+
If version is unknown or 'latest', focus on recent high-profile CVEs.
|
|
169
|
+
"""
|
|
170
|
+
|
|
171
|
+
response = await self.orchestrator.process(prompt)
|
|
172
|
+
|
|
173
|
+
# Parse CVE information
|
|
174
|
+
vulns = []
|
|
175
|
+
cve_pattern = r"(CVE-\d{4}-\d{4,})"
|
|
176
|
+
cves = re.findall(cve_pattern, response.content)
|
|
177
|
+
|
|
178
|
+
for cve in cves[:5]: # Limit results
|
|
179
|
+
vulns.append(
|
|
180
|
+
Vulnerability(
|
|
181
|
+
name=f"{service} - {cve}",
|
|
182
|
+
severity="Unknown", # Would need actual CVSS lookup
|
|
183
|
+
description=f"Known vulnerability in {service} {version}",
|
|
184
|
+
evidence=f"CVE ID: {cve}",
|
|
185
|
+
remediation="Update to latest version or apply security patches",
|
|
186
|
+
cve_ids=[cve],
|
|
187
|
+
)
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
return vulns
|
|
191
|
+
|
|
192
|
+
async def ssl_tls_analysis(self, cert_info: str) -> List[Vulnerability]:
|
|
193
|
+
"""
|
|
194
|
+
Analyze SSL/TLS configuration
|
|
195
|
+
"""
|
|
196
|
+
prompt = f"""
|
|
197
|
+
Analyze this SSL/TLS certificate and configuration:
|
|
198
|
+
|
|
199
|
+
```
|
|
200
|
+
{cert_info[:2000]}
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
Check for:
|
|
204
|
+
- Weak cipher suites
|
|
205
|
+
- Expired or soon-expiring certificates
|
|
206
|
+
- Self-signed certificates in production
|
|
207
|
+
- Weak protocols (SSLv2, SSLv3, TLS 1.0)
|
|
208
|
+
- Certificate chain issues
|
|
209
|
+
- Wildcard certificate usage
|
|
210
|
+
|
|
211
|
+
List findings with severity and remediation.
|
|
212
|
+
"""
|
|
213
|
+
|
|
214
|
+
response = await self.orchestrator.process(prompt)
|
|
215
|
+
return self._parse_vulnerabilities(response.content)
|
|
216
|
+
|
|
217
|
+
def _parse_vulnerabilities(self, content: str) -> List[Vulnerability]:
|
|
218
|
+
"""Parse vulnerability blocks from LLM response"""
|
|
219
|
+
vulns = []
|
|
220
|
+
|
|
221
|
+
# Look for [VULN] blocks
|
|
222
|
+
vuln_blocks = re.findall(r"\[VULN\](.*?)\[/VULN\]", content, re.DOTALL)
|
|
223
|
+
|
|
224
|
+
if not vuln_blocks:
|
|
225
|
+
# Try alternate parsing (numbered lists)
|
|
226
|
+
sections = content.split("\n\n")
|
|
227
|
+
for section in sections:
|
|
228
|
+
if any(
|
|
229
|
+
s in section.lower()
|
|
230
|
+
for s in ["severity:", "vulnerability:", "risk:"]
|
|
231
|
+
):
|
|
232
|
+
vulns.append(self._create_vuln_from_text(section))
|
|
233
|
+
else:
|
|
234
|
+
for block in vuln_blocks:
|
|
235
|
+
vulns.append(self._create_vuln_from_text(block))
|
|
236
|
+
|
|
237
|
+
return vulns
|
|
238
|
+
|
|
239
|
+
def _create_vuln_from_text(self, text: str) -> Vulnerability:
|
|
240
|
+
"""Create Vulnerability object from text block"""
|
|
241
|
+
|
|
242
|
+
# Extract fields using regex
|
|
243
|
+
name_match = re.search(r"Name:\s*(.+?)(?:\n|$)", text, re.IGNORECASE)
|
|
244
|
+
severity_match = re.search(r"Severity:\s*(\w+)", text, re.IGNORECASE)
|
|
245
|
+
desc_match = re.search(
|
|
246
|
+
r"Description:\s*(.+?)(?:\n\w+:|$)", text, re.DOTALL | re.IGNORECASE
|
|
247
|
+
)
|
|
248
|
+
evidence_match = re.search(
|
|
249
|
+
r"Evidence:\s*(.+?)(?:\n\w+:|$)", text, re.DOTALL | re.IGNORECASE
|
|
250
|
+
)
|
|
251
|
+
remediation_match = re.search(
|
|
252
|
+
r"Remediation:\s*(.+?)(?:\n\w+:|$)", text, re.DOTALL | re.IGNORECASE
|
|
253
|
+
)
|
|
254
|
+
cve_match = re.findall(r"(CVE-\d{4}-\d{4,})", text)
|
|
255
|
+
|
|
256
|
+
# Validate severity
|
|
257
|
+
severity = severity_match.group(1).capitalize() if severity_match else "Info"
|
|
258
|
+
if severity not in self.SEVERITY_ORDER:
|
|
259
|
+
severity = "Info"
|
|
260
|
+
|
|
261
|
+
return Vulnerability(
|
|
262
|
+
name=name_match.group(1).strip() if name_match else "Unknown Vulnerability",
|
|
263
|
+
severity=severity,
|
|
264
|
+
description=desc_match.group(1).strip()[:500] if desc_match else text[:300],
|
|
265
|
+
evidence=evidence_match.group(1).strip()[:300] if evidence_match else "N/A",
|
|
266
|
+
remediation=(
|
|
267
|
+
remediation_match.group(1).strip()[:500]
|
|
268
|
+
if remediation_match
|
|
269
|
+
else "Review and fix"
|
|
270
|
+
),
|
|
271
|
+
cve_ids=cve_match if cve_match else [],
|
|
272
|
+
)
|
|
273
|
+
|
|
274
|
+
def get_severity_summary(
|
|
275
|
+
self, vulnerabilities: List[Vulnerability]
|
|
276
|
+
) -> Dict[str, int]:
|
|
277
|
+
"""Get summary of vulnerabilities by severity"""
|
|
278
|
+
summary = {"Critical": 0, "High": 0, "Medium": 0, "Low": 0, "Info": 0}
|
|
279
|
+
for v in vulnerabilities:
|
|
280
|
+
if v.severity in summary:
|
|
281
|
+
summary[v.severity] += 1
|
|
282
|
+
return summary
|
|
283
|
+
|
|
284
|
+
def sort_by_severity(
|
|
285
|
+
self, vulnerabilities: List[Vulnerability]
|
|
286
|
+
) -> List[Vulnerability]:
|
|
287
|
+
"""Sort vulnerabilities by severity (highest first)"""
|
|
288
|
+
return sorted(
|
|
289
|
+
vulnerabilities,
|
|
290
|
+
key=lambda x: self.SEVERITY_ORDER.get(x.severity, 0),
|
|
291
|
+
reverse=True,
|
|
292
|
+
)
|