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.
Files changed (75) hide show
  1. agents/__init__.py +28 -0
  2. agents/agent_base.py +239 -0
  3. agents/agent_orchestrator.py +346 -0
  4. agents/analysis_agent.py +225 -0
  5. agents/cli.py +258 -0
  6. agents/exploit_agent.py +224 -0
  7. agents/integration.py +211 -0
  8. agents/post_scan_agent.py +937 -0
  9. agents/react_agent.py +384 -0
  10. agents/react_agent_enhanced.py +616 -0
  11. agents/react_agent_vm.py +298 -0
  12. agents/research_agent.py +176 -0
  13. api/__init__.py +11 -0
  14. api/auth.py +123 -0
  15. api/main.py +1027 -0
  16. api/schemas.py +357 -0
  17. api/websocket.py +97 -0
  18. autonomous/__init__.py +122 -0
  19. autonomous/agent.py +253 -0
  20. autonomous/agent_loop.py +1370 -0
  21. autonomous/exploit_validator.py +1537 -0
  22. autonomous/memory.py +448 -0
  23. autonomous/react.py +339 -0
  24. autonomous/tool_executor.py +488 -0
  25. backends/__init__.py +16 -0
  26. backends/chatgpt_direct.py +133 -0
  27. backends/claude_direct.py +130 -0
  28. backends/duckduckgo.py +138 -0
  29. backends/openrouter.py +120 -0
  30. benchmarks/__init__.py +149 -0
  31. benchmarks/benchmark_engine.py +904 -0
  32. benchmarks/ci_benchmark.py +785 -0
  33. benchmarks/comparison.py +729 -0
  34. benchmarks/metrics.py +553 -0
  35. benchmarks/run_benchmarks.py +809 -0
  36. ci_cd/__init__.py +2 -0
  37. core/__init__.py +17 -0
  38. core/async_pool.py +282 -0
  39. core/asyncio_fix.py +222 -0
  40. core/cache.py +472 -0
  41. core/container.py +277 -0
  42. core/database.py +114 -0
  43. core/input_validator.py +353 -0
  44. core/models.py +288 -0
  45. core/orchestrator.py +611 -0
  46. core/plugin_manager.py +571 -0
  47. core/rate_limiter.py +405 -0
  48. core/secure_config.py +328 -0
  49. core/shield_integration.py +296 -0
  50. modules/__init__.py +46 -0
  51. modules/cve_database.py +362 -0
  52. modules/exploit_assist.py +330 -0
  53. modules/nuclei_integration.py +480 -0
  54. modules/osint.py +604 -0
  55. modules/protonvpn.py +554 -0
  56. modules/recon.py +165 -0
  57. modules/sql_injection_db.py +826 -0
  58. modules/tool_orchestrator.py +498 -0
  59. modules/vuln_scanner.py +292 -0
  60. modules/wordlist_generator.py +566 -0
  61. risk_engine/__init__.py +99 -0
  62. risk_engine/business_impact.py +267 -0
  63. risk_engine/business_impact_calculator.py +563 -0
  64. risk_engine/cvss.py +156 -0
  65. risk_engine/epss.py +190 -0
  66. risk_engine/example_usage.py +294 -0
  67. risk_engine/false_positive_engine.py +1073 -0
  68. risk_engine/scorer.py +304 -0
  69. web_ui/backend/main.py +471 -0
  70. zen_ai_pentest-2.0.0.dist-info/METADATA +795 -0
  71. zen_ai_pentest-2.0.0.dist-info/RECORD +75 -0
  72. zen_ai_pentest-2.0.0.dist-info/WHEEL +5 -0
  73. zen_ai_pentest-2.0.0.dist-info/entry_points.txt +2 -0
  74. zen_ai_pentest-2.0.0.dist-info/licenses/LICENSE +21 -0
  75. zen_ai_pentest-2.0.0.dist-info/top_level.txt +10 -0
@@ -0,0 +1,480 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Nuclei Integration Module
4
+ Template management and vulnerability scanning with Nuclei
5
+ Author: SHAdd0WTAka
6
+ """
7
+
8
+ import asyncio
9
+ import json
10
+ import logging
11
+ import os
12
+ import re
13
+ import subprocess
14
+ from dataclasses import asdict, dataclass
15
+ from datetime import datetime
16
+ from typing import Any, Dict, List, Optional
17
+
18
+ logger = logging.getLogger("ZenAI")
19
+
20
+
21
+ @dataclass
22
+ class NucleiTemplate:
23
+ """Represents a Nuclei template"""
24
+
25
+ id: str
26
+ name: str
27
+ severity: str
28
+ description: str
29
+ tags: List[str]
30
+ author: str
31
+ reference: List[str]
32
+ classification: Dict
33
+ template_path: str
34
+ protocol: str
35
+ cvss_score: Optional[float] = None
36
+ cwe: List[str] = None
37
+ cve: List[str] = None
38
+
39
+
40
+ @dataclass
41
+ class NucleiFinding:
42
+ """Represents a Nuclei scan finding"""
43
+
44
+ template_id: str
45
+ template_name: str
46
+ severity: str
47
+ host: str
48
+ matched_at: str
49
+ extract_results: List[str]
50
+ timestamp: str
51
+ curl_command: Optional[str] = None
52
+ request: Optional[str] = None
53
+ response: Optional[str] = None
54
+
55
+
56
+ class NucleiIntegration:
57
+ """
58
+ Integration with ProjectDiscovery Nuclei scanner
59
+ Manages templates and executes scans
60
+ """
61
+
62
+ SEVERITY_ORDER = {"critical": 5, "high": 4, "medium": 3, "low": 2, "info": 1}
63
+
64
+ def __init__(self, orchestrator=None, nuclei_path: str = "nuclei"):
65
+ self.orchestrator = orchestrator
66
+ self.nuclei_path = nuclei_path
67
+ self.templates_dir = "data/nuclei_templates"
68
+ self.custom_templates = []
69
+ self.scan_results = []
70
+
71
+ # Ensure directories exist
72
+ os.makedirs(self.templates_dir, exist_ok=True)
73
+
74
+ async def check_nuclei_installed(self) -> bool:
75
+ """Check if Nuclei is installed"""
76
+ try:
77
+ result = subprocess.run(
78
+ [self.nuclei_path, "-version"],
79
+ capture_output=True,
80
+ text=True,
81
+ timeout=10,
82
+ )
83
+ return result.returncode == 0
84
+ except:
85
+ return False
86
+
87
+ async def update_templates(self) -> bool:
88
+ """Update Nuclei templates from official repository"""
89
+ try:
90
+ logger.info("[Nuclei] Updating templates...")
91
+ result = subprocess.run(
92
+ [self.nuclei_path, "-update-templates"],
93
+ capture_output=True,
94
+ text=True,
95
+ timeout=300,
96
+ )
97
+ success = result.returncode == 0
98
+ if success:
99
+ logger.info("[Nuclei] Templates updated successfully")
100
+ else:
101
+ logger.error(f"[Nuclei] Update failed: {result.stderr}")
102
+ return success
103
+ except Exception as e:
104
+ logger.error(f"[Nuclei] Update error: {e}")
105
+ return False
106
+
107
+ def get_template_categories(self) -> Dict[str, List[str]]:
108
+ """Get available template categories"""
109
+ categories = {
110
+ "cves": [],
111
+ "vulnerabilities": [],
112
+ "misconfiguration": [],
113
+ "exposures": [],
114
+ "technologies": [],
115
+ "token-spray": [],
116
+ "default-logins": [],
117
+ "dns": [],
118
+ "fuzzing": [],
119
+ "helpers": [],
120
+ "headless": [],
121
+ }
122
+
123
+ # Get from nuclei if available
124
+ try:
125
+ result = subprocess.run(
126
+ [self.nuclei_path, "-tl"], capture_output=True, text=True, timeout=30
127
+ )
128
+ if result.returncode == 0:
129
+ for line in result.stdout.split("\n"):
130
+ for category in categories.keys():
131
+ if f"{category}/" in line.lower():
132
+ categories[category].append(line.strip())
133
+ except:
134
+ pass
135
+
136
+ return categories
137
+
138
+ async def scan_target(
139
+ self,
140
+ target: str,
141
+ severity: List[str] = None,
142
+ tags: List[str] = None,
143
+ templates: List[str] = None,
144
+ rate_limit: int = 150,
145
+ ) -> List[NucleiFinding]:
146
+ """
147
+ Run Nuclei scan against target
148
+ """
149
+ if not await self.check_nuclei_installed():
150
+ logger.error(
151
+ "[Nuclei] Nuclei not installed. Install from: https://nuclei.projectdiscovery.io/"
152
+ )
153
+ return []
154
+
155
+ cmd = [
156
+ self.nuclei_path,
157
+ "-u",
158
+ target,
159
+ "-json",
160
+ "-rate-limit",
161
+ str(rate_limit),
162
+ "-timeout",
163
+ "10",
164
+ "-retries",
165
+ "2",
166
+ ]
167
+
168
+ # Add severity filter
169
+ if severity:
170
+ cmd.extend(["-severity", ",".join(severity)])
171
+
172
+ # Add tags filter
173
+ if tags:
174
+ cmd.extend(["-tags", ",".join(tags)])
175
+
176
+ # Add specific templates
177
+ if templates:
178
+ for tmpl in templates:
179
+ cmd.extend(["-t", tmpl])
180
+
181
+ logger.info(f"[Nuclei] Starting scan: {' '.join(cmd)}")
182
+
183
+ findings = []
184
+ try:
185
+ process = await asyncio.create_subprocess_exec(
186
+ *cmd, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE
187
+ )
188
+
189
+ while True:
190
+ line = await process.stdout.readline()
191
+ if not line:
192
+ break
193
+
194
+ try:
195
+ data = json.loads(line.decode().strip())
196
+ finding = self._parse_nuclei_output(data)
197
+ if finding:
198
+ findings.append(finding)
199
+ logger.info(
200
+ f"[Nuclei] Found: {finding.template_name} ({finding.severity})"
201
+ )
202
+ except json.JSONDecodeError:
203
+ continue
204
+
205
+ await process.wait()
206
+
207
+ except Exception as e:
208
+ logger.error(f"[Nuclei] Scan error: {e}")
209
+
210
+ self.scan_results.extend(findings)
211
+ return findings
212
+
213
+ def _parse_nuclei_output(self, data: Dict) -> Optional[NucleiFinding]:
214
+ """Parse Nuclei JSON output"""
215
+ try:
216
+ info = data.get("info", {})
217
+
218
+ return NucleiFinding(
219
+ template_id=info.get("id", "unknown"),
220
+ template_name=info.get("name", "Unknown"),
221
+ severity=info.get("severity", "info"),
222
+ host=data.get("host", ""),
223
+ matched_at=data.get("matched-at", ""),
224
+ extract_results=data.get("extracted-results", []),
225
+ timestamp=datetime.now().isoformat(),
226
+ curl_command=data.get("curl-command"),
227
+ request=data.get("request"),
228
+ response=data.get("response"),
229
+ )
230
+ except Exception as e:
231
+ logger.error(f"[Nuclei] Parse error: {e}")
232
+ return None
233
+
234
+ async def scan_with_ai_analysis(self, target: str) -> Dict:
235
+ """
236
+ Run Nuclei scan and analyze results with LLM
237
+ """
238
+ # Run the scan
239
+ findings = await self.scan_target(
240
+ target, severity=["critical", "high", "medium"]
241
+ )
242
+
243
+ if not findings:
244
+ return {"findings": [], "analysis": "No vulnerabilities found"}
245
+
246
+ # Prepare data for LLM analysis
247
+ findings_summary = "\n".join(
248
+ [
249
+ f"- [{f.severity.upper()}] {f.template_name} at {f.matched_at}"
250
+ for f in findings[:20] # Limit for token efficiency
251
+ ]
252
+ )
253
+
254
+ if self.orchestrator:
255
+ prompt = f"""
256
+ Analyze these Nuclei scan findings for {target}:
257
+
258
+ {findings_summary}
259
+
260
+ Provide:
261
+ 1. Risk assessment summary
262
+ 2. Prioritized remediation steps
263
+ 3. Potential attack chains (how vulnerabilities might be combined)
264
+ 4. Immediate actions required
265
+ """
266
+ analysis = await self.orchestrator.process(prompt)
267
+ analysis_text = analysis.content
268
+ else:
269
+ analysis_text = "LLM analysis not available (no orchestrator)"
270
+
271
+ return {
272
+ "findings": findings,
273
+ "analysis": analysis_text,
274
+ "severity_summary": self._get_severity_summary(findings),
275
+ "timestamp": datetime.now().isoformat(),
276
+ }
277
+
278
+ def _get_severity_summary(self, findings: List[NucleiFinding]) -> Dict[str, int]:
279
+ """Get severity summary of findings"""
280
+ summary = {"critical": 0, "high": 0, "medium": 0, "low": 0, "info": 0}
281
+ for f in findings:
282
+ sev = f.severity.lower()
283
+ if sev in summary:
284
+ summary[sev] += 1
285
+ return summary
286
+
287
+ def export_results(
288
+ self, findings: List[NucleiFinding], filename: str = None
289
+ ) -> str:
290
+ """Export findings to JSON"""
291
+ if not filename:
292
+ filename = (
293
+ f"logs/nuclei_scan_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
294
+ )
295
+
296
+ data = {
297
+ "scan_date": datetime.now().isoformat(),
298
+ "total_findings": len(findings),
299
+ "severity_summary": self._get_severity_summary(findings),
300
+ "findings": [asdict(f) for f in findings],
301
+ }
302
+
303
+ with open(filename, "w") as f:
304
+ json.dump(data, f, indent=2)
305
+
306
+ logger.info(f"[Nuclei] Results exported: {filename}")
307
+ return filename
308
+
309
+ def get_critical_cves(self) -> List[Dict]:
310
+ """Get list of critical CVE templates"""
311
+ critical_cves = [
312
+ {
313
+ "id": "CVE-2024-XXXX",
314
+ "name": "Placeholder for latest critical CVEs",
315
+ "severity": "critical",
316
+ },
317
+ {
318
+ "id": "CVE-2023-44487",
319
+ "name": "HTTP/2 Rapid Reset",
320
+ "severity": "critical",
321
+ },
322
+ {
323
+ "id": "CVE-2023-38545",
324
+ "name": "cURL SOCKS5 heap buffer overflow",
325
+ "severity": "high",
326
+ },
327
+ {
328
+ "id": "CVE-2023-29357",
329
+ "name": "Microsoft SharePoint Privilege Escalation",
330
+ "severity": "critical",
331
+ },
332
+ {
333
+ "id": "CVE-2023-21716",
334
+ "name": "Microsoft Word Remote Code Execution",
335
+ "severity": "critical",
336
+ },
337
+ {
338
+ "id": "CVE-2022-44877",
339
+ "name": "CentOS Web Panel RCE",
340
+ "severity": "critical",
341
+ },
342
+ {
343
+ "id": "CVE-2022-42889",
344
+ "name": "Apache Commons Text RCE (Text4Shell)",
345
+ "severity": "critical",
346
+ },
347
+ {
348
+ "id": "CVE-2022-41741",
349
+ "name": "VMware Workspace ONE Access RCE",
350
+ "severity": "critical",
351
+ },
352
+ {
353
+ "id": "CVE-2022-26134",
354
+ "name": "Atlassian Confluence OGNL Injection",
355
+ "severity": "critical",
356
+ },
357
+ {
358
+ "id": "CVE-2022-22965",
359
+ "name": "Spring Framework RCE (Spring4Shell)",
360
+ "severity": "critical",
361
+ },
362
+ {
363
+ "id": "CVE-2022-22947",
364
+ "name": "Spring Cloud Gateway RCE",
365
+ "severity": "critical",
366
+ },
367
+ {
368
+ "id": "CVE-2021-44228",
369
+ "name": "Log4j RCE (Log4Shell)",
370
+ "severity": "critical",
371
+ },
372
+ {
373
+ "id": "CVE-2021-45046",
374
+ "name": "Log4j Denial of Service",
375
+ "severity": "critical",
376
+ },
377
+ {
378
+ "id": "CVE-2021-41773",
379
+ "name": "Apache Path Traversal",
380
+ "severity": "critical",
381
+ },
382
+ {
383
+ "id": "CVE-2021-3129",
384
+ "name": "Laravel Ignition RCE",
385
+ "severity": "critical",
386
+ },
387
+ {"id": "CVE-2020-1472", "name": "Zerologon", "severity": "critical"},
388
+ {
389
+ "id": "CVE-2020-14882",
390
+ "name": "Oracle WebLogic RCE",
391
+ "severity": "critical",
392
+ },
393
+ {
394
+ "id": "CVE-2019-19781",
395
+ "name": "Citrix ADC RCE (Shitrix)",
396
+ "severity": "critical",
397
+ },
398
+ {
399
+ "id": "CVE-2019-11510",
400
+ "name": "Pulse Secure VPN Arbitrary File Reading",
401
+ "severity": "critical",
402
+ },
403
+ {
404
+ "id": "CVE-2018-13379",
405
+ "name": "Fortinet VPN Path Traversal",
406
+ "severity": "critical",
407
+ },
408
+ {
409
+ "id": "CVE-2017-0144",
410
+ "name": "EternalBlue (MS17-010)",
411
+ "severity": "critical",
412
+ },
413
+ {
414
+ "id": "CVE-2017-5638",
415
+ "name": "Apache Struts RCE",
416
+ "severity": "critical",
417
+ },
418
+ ]
419
+ return critical_cves
420
+
421
+
422
+ class NucleiTemplateManager:
423
+ """Manages custom Nuclei templates"""
424
+
425
+ def __init__(self, templates_dir: str = "data/nuclei_templates"):
426
+ self.templates_dir = templates_dir
427
+ os.makedirs(templates_dir, exist_ok=True)
428
+
429
+ def create_template(
430
+ self,
431
+ template_id: str,
432
+ name: str,
433
+ severity: str,
434
+ request: Dict,
435
+ matchers: List[Dict],
436
+ description: str = "",
437
+ ) -> str:
438
+ """Create a new Nuclei template"""
439
+
440
+ template = {
441
+ "id": template_id,
442
+ "info": {
443
+ "name": name,
444
+ "author": "zen-ai-pentest",
445
+ "severity": severity,
446
+ "description": description,
447
+ "tags": ["custom", "autogenerated"],
448
+ "metadata": {
449
+ "generated_at": datetime.now().isoformat(),
450
+ "tool": "zen-ai-pentest",
451
+ },
452
+ },
453
+ "http": [
454
+ {
455
+ "method": request.get("method", "GET"),
456
+ "path": request.get("path", ["/"]),
457
+ "headers": request.get("headers", {}),
458
+ "body": request.get("body", ""),
459
+ "matchers": matchers,
460
+ "extractors": request.get("extractors", []),
461
+ }
462
+ ],
463
+ }
464
+
465
+ filepath = os.path.join(self.templates_dir, f"{template_id}.yaml")
466
+
467
+ import yaml
468
+
469
+ with open(filepath, "w") as f:
470
+ yaml.dump(template, f, default_flow_style=False, sort_keys=False)
471
+
472
+ return filepath
473
+
474
+ def list_templates(self) -> List[str]:
475
+ """List all custom templates"""
476
+ templates = []
477
+ for f in os.listdir(self.templates_dir):
478
+ if f.endswith(".yaml") or f.endswith(".yml"):
479
+ templates.append(os.path.join(self.templates_dir, f))
480
+ return templates