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
api/schemas.py
ADDED
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Pydantic Schemas für API Validierung
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from pydantic import BaseModel, Field
|
|
6
|
+
from typing import Optional, List, Dict, Any
|
|
7
|
+
from datetime import datetime
|
|
8
|
+
from enum import Enum
|
|
9
|
+
|
|
10
|
+
# ============================================================================
|
|
11
|
+
# ENUMS
|
|
12
|
+
# ============================================================================
|
|
13
|
+
|
|
14
|
+
class ScanStatus(str, Enum):
|
|
15
|
+
PENDING = "pending"
|
|
16
|
+
RUNNING = "running"
|
|
17
|
+
COMPLETED = "completed"
|
|
18
|
+
FAILED = "failed"
|
|
19
|
+
CANCELLED = "cancelled"
|
|
20
|
+
|
|
21
|
+
class Severity(str, Enum):
|
|
22
|
+
CRITICAL = "critical"
|
|
23
|
+
HIGH = "high"
|
|
24
|
+
MEDIUM = "medium"
|
|
25
|
+
LOW = "low"
|
|
26
|
+
INFO = "info"
|
|
27
|
+
|
|
28
|
+
class ReportFormat(str, Enum):
|
|
29
|
+
PDF = "pdf"
|
|
30
|
+
HTML = "html"
|
|
31
|
+
JSON = "json"
|
|
32
|
+
XML = "xml"
|
|
33
|
+
|
|
34
|
+
# ============================================================================
|
|
35
|
+
# BASE SCHEMAS
|
|
36
|
+
# ============================================================================
|
|
37
|
+
|
|
38
|
+
class ScanBase(BaseModel):
|
|
39
|
+
name: str = Field(..., min_length=1, max_length=255)
|
|
40
|
+
target: str = Field(..., min_length=1, max_length=500)
|
|
41
|
+
scan_type: str = Field(..., min_length=1, max_length=100)
|
|
42
|
+
config: Optional[Dict[str, Any]] = {}
|
|
43
|
+
|
|
44
|
+
class ScanCreate(ScanBase):
|
|
45
|
+
objective: Optional[str] = "comprehensive security scan"
|
|
46
|
+
|
|
47
|
+
class ScanUpdate(BaseModel):
|
|
48
|
+
status: Optional[str] = None
|
|
49
|
+
config: Optional[Dict[str, Any]] = None
|
|
50
|
+
|
|
51
|
+
class ScanResponse(ScanBase):
|
|
52
|
+
id: int
|
|
53
|
+
status: str
|
|
54
|
+
user_id: int
|
|
55
|
+
created_at: datetime
|
|
56
|
+
started_at: Optional[datetime] = None
|
|
57
|
+
completed_at: Optional[datetime] = None
|
|
58
|
+
result_summary: Optional[str] = None
|
|
59
|
+
findings_count: Optional[int] = 0
|
|
60
|
+
|
|
61
|
+
class Config:
|
|
62
|
+
from_attributes = True
|
|
63
|
+
|
|
64
|
+
# ============================================================================
|
|
65
|
+
# FINDING SCHEMAS
|
|
66
|
+
# ============================================================================
|
|
67
|
+
|
|
68
|
+
class FindingBase(BaseModel):
|
|
69
|
+
title: str = Field(..., min_length=1, max_length=500)
|
|
70
|
+
description: Optional[str] = None
|
|
71
|
+
severity: Severity = Severity.MEDIUM
|
|
72
|
+
cvss_score: Optional[float] = Field(None, ge=0, le=10)
|
|
73
|
+
cve_id: Optional[str] = None
|
|
74
|
+
evidence: Optional[str] = None
|
|
75
|
+
remediation: Optional[str] = None
|
|
76
|
+
tool: Optional[str] = None
|
|
77
|
+
target: Optional[str] = None
|
|
78
|
+
port: Optional[int] = None
|
|
79
|
+
service: Optional[str] = None
|
|
80
|
+
|
|
81
|
+
class FindingCreate(FindingBase):
|
|
82
|
+
pass
|
|
83
|
+
|
|
84
|
+
class FindingResponse(FindingBase):
|
|
85
|
+
id: int
|
|
86
|
+
scan_id: int
|
|
87
|
+
created_at: datetime
|
|
88
|
+
verified: int = 0
|
|
89
|
+
|
|
90
|
+
class Config:
|
|
91
|
+
from_attributes = True
|
|
92
|
+
|
|
93
|
+
class FindingUpdate(BaseModel):
|
|
94
|
+
severity: Optional[Severity] = None
|
|
95
|
+
verified: Optional[int] = None
|
|
96
|
+
remediation: Optional[str] = None
|
|
97
|
+
|
|
98
|
+
# ============================================================================
|
|
99
|
+
# REPORT SCHEMAS
|
|
100
|
+
# ============================================================================
|
|
101
|
+
|
|
102
|
+
class ReportBase(BaseModel):
|
|
103
|
+
scan_id: int
|
|
104
|
+
format: ReportFormat = ReportFormat.PDF
|
|
105
|
+
template: Optional[str] = "default"
|
|
106
|
+
|
|
107
|
+
class ReportCreate(ReportBase):
|
|
108
|
+
pass
|
|
109
|
+
|
|
110
|
+
class ReportResponse(ReportBase):
|
|
111
|
+
id: int
|
|
112
|
+
user_id: int
|
|
113
|
+
status: str
|
|
114
|
+
file_path: Optional[str] = None
|
|
115
|
+
file_size: Optional[int] = None
|
|
116
|
+
created_at: datetime
|
|
117
|
+
generated_at: Optional[datetime] = None
|
|
118
|
+
|
|
119
|
+
class Config:
|
|
120
|
+
from_attributes = True
|
|
121
|
+
|
|
122
|
+
# ============================================================================
|
|
123
|
+
# TOOL EXECUTION SCHEMAS
|
|
124
|
+
# ============================================================================
|
|
125
|
+
|
|
126
|
+
class ToolExecuteRequest(BaseModel):
|
|
127
|
+
tool_name: str = Field(..., description="Name of the tool to execute")
|
|
128
|
+
target: str = Field(..., description="Target to scan")
|
|
129
|
+
parameters: Optional[Dict[str, Any]] = {}
|
|
130
|
+
timeout: Optional[int] = 300
|
|
131
|
+
|
|
132
|
+
class ToolExecuteResponse(BaseModel):
|
|
133
|
+
scan_id: int
|
|
134
|
+
status: str
|
|
135
|
+
message: str
|
|
136
|
+
estimated_duration: Optional[int] = None
|
|
137
|
+
|
|
138
|
+
class ToolInfo(BaseModel):
|
|
139
|
+
name: str
|
|
140
|
+
description: str
|
|
141
|
+
category: str
|
|
142
|
+
parameters: Optional[Dict[str, Any]] = {}
|
|
143
|
+
|
|
144
|
+
# ============================================================================
|
|
145
|
+
# AUTH SCHEMAS
|
|
146
|
+
# ============================================================================
|
|
147
|
+
|
|
148
|
+
class UserLogin(BaseModel):
|
|
149
|
+
username: str
|
|
150
|
+
password: str
|
|
151
|
+
|
|
152
|
+
class UserCreate(BaseModel):
|
|
153
|
+
username: str = Field(..., min_length=3, max_length=100)
|
|
154
|
+
email: str = Field(..., pattern=r'^[\w\.-]+@[\w\.-]+\.\w+$')
|
|
155
|
+
password: str = Field(..., min_length=8)
|
|
156
|
+
role: Optional[str] = "operator"
|
|
157
|
+
|
|
158
|
+
class UserResponse(BaseModel):
|
|
159
|
+
id: int
|
|
160
|
+
username: str
|
|
161
|
+
email: str
|
|
162
|
+
role: str
|
|
163
|
+
is_active: int
|
|
164
|
+
created_at: datetime
|
|
165
|
+
|
|
166
|
+
class Config:
|
|
167
|
+
from_attributes = True
|
|
168
|
+
|
|
169
|
+
class TokenResponse(BaseModel):
|
|
170
|
+
access_token: str
|
|
171
|
+
token_type: str = "bearer"
|
|
172
|
+
expires_in: int = 3600
|
|
173
|
+
|
|
174
|
+
# ============================================================================
|
|
175
|
+
# DASHBOARD SCHEMAS
|
|
176
|
+
# ============================================================================
|
|
177
|
+
|
|
178
|
+
class DashboardStats(BaseModel):
|
|
179
|
+
total_scans: int
|
|
180
|
+
active_scans: int
|
|
181
|
+
completed_scans: int
|
|
182
|
+
failed_scans: int
|
|
183
|
+
total_findings: int
|
|
184
|
+
critical_findings: int
|
|
185
|
+
high_findings: int
|
|
186
|
+
reports_generated: int
|
|
187
|
+
|
|
188
|
+
class RecentActivity(BaseModel):
|
|
189
|
+
id: int
|
|
190
|
+
type: str # scan, finding, report
|
|
191
|
+
description: str
|
|
192
|
+
timestamp: datetime
|
|
193
|
+
user: str
|
|
194
|
+
|
|
195
|
+
class DashboardResponse(BaseModel):
|
|
196
|
+
stats: DashboardStats
|
|
197
|
+
recent_activities: List[RecentActivity]
|
|
198
|
+
scans_by_status: Dict[str, int]
|
|
199
|
+
findings_by_severity: Dict[str, int]
|
|
200
|
+
|
|
201
|
+
# ============================================================================
|
|
202
|
+
# WEBSOCKET SCHEMAS
|
|
203
|
+
# ============================================================================
|
|
204
|
+
|
|
205
|
+
class WSMessage(BaseModel):
|
|
206
|
+
type: str # status, log, result, error
|
|
207
|
+
scan_id: Optional[int] = None
|
|
208
|
+
message: str
|
|
209
|
+
data: Optional[Dict[str, Any]] = None
|
|
210
|
+
timestamp: datetime = Field(default_factory=datetime.utcnow)
|
|
211
|
+
|
|
212
|
+
class WSCommand(BaseModel):
|
|
213
|
+
action: str # start, stop, status, ping
|
|
214
|
+
scan_id: Optional[int] = None
|
|
215
|
+
parameters: Optional[Dict[str, Any]] = None
|
|
216
|
+
|
|
217
|
+
# ============================================================================
|
|
218
|
+
# NOTIFICATION SCHEMAS
|
|
219
|
+
# ============================================================================
|
|
220
|
+
|
|
221
|
+
class NotificationBase(BaseModel):
|
|
222
|
+
type: str
|
|
223
|
+
title: str
|
|
224
|
+
message: str
|
|
225
|
+
|
|
226
|
+
class NotificationCreate(NotificationBase):
|
|
227
|
+
user_id: int
|
|
228
|
+
|
|
229
|
+
class NotificationResponse(NotificationBase):
|
|
230
|
+
id: int
|
|
231
|
+
user_id: int
|
|
232
|
+
read: int
|
|
233
|
+
created_at: datetime
|
|
234
|
+
|
|
235
|
+
class Config:
|
|
236
|
+
from_attributes = True
|
|
237
|
+
|
|
238
|
+
# ============================================================================
|
|
239
|
+
# ASSET SCHEMAS
|
|
240
|
+
# ============================================================================
|
|
241
|
+
|
|
242
|
+
class AssetBase(BaseModel):
|
|
243
|
+
name: str
|
|
244
|
+
asset_type: str
|
|
245
|
+
ip_address: Optional[str] = None
|
|
246
|
+
hostname: Optional[str] = None
|
|
247
|
+
os: Optional[str] = None
|
|
248
|
+
criticality: str = "medium"
|
|
249
|
+
|
|
250
|
+
class AssetCreate(AssetBase):
|
|
251
|
+
pass
|
|
252
|
+
|
|
253
|
+
class AssetResponse(AssetBase):
|
|
254
|
+
id: int
|
|
255
|
+
services: Optional[Dict[str, Any]] = None
|
|
256
|
+
created_at: datetime
|
|
257
|
+
last_scanned: Optional[datetime] = None
|
|
258
|
+
|
|
259
|
+
class Config:
|
|
260
|
+
from_attributes = True
|
|
261
|
+
|
|
262
|
+
# ============================================================================
|
|
263
|
+
# VULNERABILITY DB SCHEMAS
|
|
264
|
+
# ============================================================================
|
|
265
|
+
|
|
266
|
+
class VulnerabilityDBResponse(BaseModel):
|
|
267
|
+
id: int
|
|
268
|
+
cve_id: str
|
|
269
|
+
title: str
|
|
270
|
+
description: Optional[str] = None
|
|
271
|
+
severity: str
|
|
272
|
+
cvss_score: Optional[float] = None
|
|
273
|
+
epss_score: Optional[float] = None
|
|
274
|
+
affected_products: Optional[List[str]] = None
|
|
275
|
+
references: Optional[List[str]] = None
|
|
276
|
+
exploits: Optional[List[str]] = None
|
|
277
|
+
|
|
278
|
+
# ============================================================================
|
|
279
|
+
# PAGINATION SCHEMAS
|
|
280
|
+
# ============================================================================
|
|
281
|
+
|
|
282
|
+
class PaginatedResponse(BaseModel):
|
|
283
|
+
items: List[Any]
|
|
284
|
+
total: int
|
|
285
|
+
page: int
|
|
286
|
+
page_size: int
|
|
287
|
+
pages: int
|
|
288
|
+
|
|
289
|
+
class PaginationParams(BaseModel):
|
|
290
|
+
page: int = Field(1, ge=1)
|
|
291
|
+
page_size: int = Field(20, ge=1, le=100)
|
|
292
|
+
|
|
293
|
+
@property
|
|
294
|
+
def skip(self) -> int:
|
|
295
|
+
return (self.page - 1) * self.page_size
|
|
296
|
+
|
|
297
|
+
# ============================================================================
|
|
298
|
+
# SCHEDULED SCAN SCHEMAS
|
|
299
|
+
# ============================================================================
|
|
300
|
+
|
|
301
|
+
class ScheduleFrequency(str, Enum):
|
|
302
|
+
ONCE = "once"
|
|
303
|
+
DAILY = "daily"
|
|
304
|
+
WEEKLY = "weekly"
|
|
305
|
+
MONTHLY = "monthly"
|
|
306
|
+
|
|
307
|
+
class ScheduledScanCreate(BaseModel):
|
|
308
|
+
name: str = Field(..., min_length=1, max_length=200)
|
|
309
|
+
target: str = Field(..., min_length=1, max_length=500)
|
|
310
|
+
scan_type: str = "comprehensive"
|
|
311
|
+
frequency: ScheduleFrequency = ScheduleFrequency.WEEKLY
|
|
312
|
+
schedule_time: str = Field(..., pattern=r"^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$") # HH:MM format
|
|
313
|
+
schedule_day: Optional[int] = Field(None, ge=0, le=6) # 0=Monday, 6=Sunday for weekly
|
|
314
|
+
enabled: bool = True
|
|
315
|
+
notification_email: Optional[str] = None
|
|
316
|
+
notification_slack: Optional[str] = None
|
|
317
|
+
|
|
318
|
+
class ScheduledScanUpdate(BaseModel):
|
|
319
|
+
name: Optional[str] = None
|
|
320
|
+
target: Optional[str] = None
|
|
321
|
+
scan_type: Optional[str] = None
|
|
322
|
+
frequency: Optional[ScheduleFrequency] = None
|
|
323
|
+
schedule_time: Optional[str] = None
|
|
324
|
+
schedule_day: Optional[int] = None
|
|
325
|
+
enabled: Optional[bool] = None
|
|
326
|
+
notification_email: Optional[str] = None
|
|
327
|
+
notification_slack: Optional[str] = None
|
|
328
|
+
last_run_status: Optional[str] = None
|
|
329
|
+
|
|
330
|
+
class ScheduledScanResponse(BaseModel):
|
|
331
|
+
id: int
|
|
332
|
+
name: str
|
|
333
|
+
target: str
|
|
334
|
+
scan_type: str
|
|
335
|
+
frequency: str
|
|
336
|
+
schedule_time: str
|
|
337
|
+
schedule_day: Optional[int] = None
|
|
338
|
+
enabled: bool
|
|
339
|
+
notification_email: Optional[str] = None
|
|
340
|
+
notification_slack: Optional[str] = None
|
|
341
|
+
last_run_at: Optional[datetime] = None
|
|
342
|
+
last_run_status: Optional[str] = None
|
|
343
|
+
next_run_at: Optional[datetime] = None
|
|
344
|
+
created_at: datetime
|
|
345
|
+
created_by: str
|
|
346
|
+
|
|
347
|
+
class Config:
|
|
348
|
+
from_attributes = True
|
|
349
|
+
|
|
350
|
+
class ScheduleExecutionResponse(BaseModel):
|
|
351
|
+
id: int
|
|
352
|
+
scheduled_scan_id: int
|
|
353
|
+
scan_id: Optional[int] = None
|
|
354
|
+
status: str
|
|
355
|
+
started_at: Optional[datetime] = None
|
|
356
|
+
completed_at: Optional[datetime] = None
|
|
357
|
+
error_message: Optional[str] = None
|
api/websocket.py
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""
|
|
2
|
+
WebSocket Connection Manager für Real-Time Updates
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
import logging
|
|
7
|
+
from typing import Dict, List, Set
|
|
8
|
+
from fastapi import WebSocket
|
|
9
|
+
|
|
10
|
+
logger = logging.getLogger(__name__)
|
|
11
|
+
|
|
12
|
+
class ConnectionManager:
|
|
13
|
+
"""Manages WebSocket connections for real-time updates"""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
# scan_id -> Set of WebSocket connections
|
|
17
|
+
self.scan_connections: Dict[int, Set[WebSocket]] = {}
|
|
18
|
+
# Global connections (for notifications)
|
|
19
|
+
self.global_connections: Set[WebSocket] = set()
|
|
20
|
+
|
|
21
|
+
async def connect(self, websocket: WebSocket, scan_id: int = None):
|
|
22
|
+
"""Accept and register new connection"""
|
|
23
|
+
await websocket.accept()
|
|
24
|
+
|
|
25
|
+
if scan_id:
|
|
26
|
+
if scan_id not in self.scan_connections:
|
|
27
|
+
self.scan_connections[scan_id] = set()
|
|
28
|
+
self.scan_connections[scan_id].add(websocket)
|
|
29
|
+
logger.info(f"WebSocket connected for scan {scan_id}")
|
|
30
|
+
else:
|
|
31
|
+
self.global_connections.add(websocket)
|
|
32
|
+
logger.info("Global WebSocket connected")
|
|
33
|
+
|
|
34
|
+
def disconnect(self, websocket: WebSocket, scan_id: int = None):
|
|
35
|
+
"""Remove connection"""
|
|
36
|
+
if scan_id and scan_id in self.scan_connections:
|
|
37
|
+
self.scan_connections[scan_id].discard(websocket)
|
|
38
|
+
if not self.scan_connections[scan_id]:
|
|
39
|
+
del self.scan_connections[scan_id]
|
|
40
|
+
else:
|
|
41
|
+
self.global_connections.discard(websocket)
|
|
42
|
+
|
|
43
|
+
logger.info(f"WebSocket disconnected (scan: {scan_id})")
|
|
44
|
+
|
|
45
|
+
async def broadcast_to_scan(self, scan_id: int, message: dict):
|
|
46
|
+
"""Send message to all connections for a scan"""
|
|
47
|
+
if scan_id not in self.scan_connections:
|
|
48
|
+
return
|
|
49
|
+
|
|
50
|
+
disconnected = set()
|
|
51
|
+
for connection in self.scan_connections[scan_id]:
|
|
52
|
+
try:
|
|
53
|
+
await connection.send_json(message)
|
|
54
|
+
except Exception as e:
|
|
55
|
+
logger.error(f"WebSocket send error: {e}")
|
|
56
|
+
disconnected.add(connection)
|
|
57
|
+
|
|
58
|
+
# Clean up disconnected
|
|
59
|
+
for conn in disconnected:
|
|
60
|
+
self.disconnect(conn, scan_id)
|
|
61
|
+
|
|
62
|
+
async def broadcast_global(self, message: dict):
|
|
63
|
+
"""Send message to all global connections"""
|
|
64
|
+
disconnected = set()
|
|
65
|
+
for connection in self.global_connections:
|
|
66
|
+
try:
|
|
67
|
+
await connection.send_json(message)
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.error(f"WebSocket send error: {e}")
|
|
70
|
+
disconnected.add(connection)
|
|
71
|
+
|
|
72
|
+
# Clean up disconnected
|
|
73
|
+
for conn in disconnected:
|
|
74
|
+
self.disconnect(conn)
|
|
75
|
+
|
|
76
|
+
async def send_personal_message(self, websocket: WebSocket, message: dict):
|
|
77
|
+
"""Send message to specific connection"""
|
|
78
|
+
try:
|
|
79
|
+
await websocket.send_json(message)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logger.error(f"WebSocket send error: {e}")
|
|
82
|
+
|
|
83
|
+
def get_scan_connections_count(self, scan_id: int) -> int:
|
|
84
|
+
"""Get number of active connections for a scan"""
|
|
85
|
+
return len(self.scan_connections.get(scan_id, set()))
|
|
86
|
+
|
|
87
|
+
def get_global_connections_count(self) -> int:
|
|
88
|
+
"""Get number of global connections"""
|
|
89
|
+
return len(self.global_connections)
|
|
90
|
+
|
|
91
|
+
def get_stats(self) -> dict:
|
|
92
|
+
"""Get connection statistics"""
|
|
93
|
+
return {
|
|
94
|
+
"global_connections": len(self.global_connections),
|
|
95
|
+
"active_scans": len(self.scan_connections),
|
|
96
|
+
"total_scan_connections": sum(len(conns) for conns in self.scan_connections.values())
|
|
97
|
+
}
|
autonomous/__init__.py
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Autonomous Agent System for Zen AI Pentest (2026 Roadmap - Q1)
|
|
3
|
+
|
|
4
|
+
This module implements:
|
|
5
|
+
- ReAct/Plan-and-Execute reasoning loop
|
|
6
|
+
- Real tool execution framework
|
|
7
|
+
- Memory system with vector storage
|
|
8
|
+
- Self-correction capabilities
|
|
9
|
+
- Exploit validation with sandboxed execution
|
|
10
|
+
|
|
11
|
+
Usage:
|
|
12
|
+
from autonomous import AutonomousAgent
|
|
13
|
+
|
|
14
|
+
agent = AutonomousAgent(goal="Find RCE in target API")
|
|
15
|
+
result = await agent.run()
|
|
16
|
+
|
|
17
|
+
# Exploit Validation
|
|
18
|
+
from autonomous import ExploitValidator, ExploitType
|
|
19
|
+
|
|
20
|
+
validator = ExploitValidator()
|
|
21
|
+
result = await validator.validate(
|
|
22
|
+
exploit_code="...",
|
|
23
|
+
target="https://example.com",
|
|
24
|
+
exploit_type=ExploitType.WEB_SQLI
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Autonomous Agent Loop
|
|
28
|
+
from autonomous import AutonomousAgentLoop, AgentState, AgentMemory
|
|
29
|
+
|
|
30
|
+
agent_loop = AutonomousAgentLoop(max_iterations=50)
|
|
31
|
+
result = await agent_loop.run(
|
|
32
|
+
goal="Find vulnerabilities",
|
|
33
|
+
target="example.com",
|
|
34
|
+
scope={"depth": "comprehensive"}
|
|
35
|
+
)
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
# Core autonomous components
|
|
39
|
+
from .agent import AutonomousAgent
|
|
40
|
+
from .react import ReActLoop, Thought, Action, Observation
|
|
41
|
+
from .tool_executor import ToolExecutor, ToolRegistry
|
|
42
|
+
from .memory import MemoryManager, WorkingMemory, LongTermMemory
|
|
43
|
+
|
|
44
|
+
# Exploit Validator components
|
|
45
|
+
from .exploit_validator import (
|
|
46
|
+
ExploitValidator,
|
|
47
|
+
ExploitValidatorPool,
|
|
48
|
+
ExploitResult,
|
|
49
|
+
ExploitType,
|
|
50
|
+
ExploitStatus,
|
|
51
|
+
SafetyLevel,
|
|
52
|
+
Evidence,
|
|
53
|
+
ScopeConfig,
|
|
54
|
+
SandboxConfig,
|
|
55
|
+
validate_sql_injection,
|
|
56
|
+
validate_xss,
|
|
57
|
+
validate_command_injection,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
# Autonomous Agent Loop components
|
|
61
|
+
from .agent_loop import (
|
|
62
|
+
AutonomousAgentLoop,
|
|
63
|
+
AgentState,
|
|
64
|
+
AgentMemory,
|
|
65
|
+
ToolResult,
|
|
66
|
+
PlanStep,
|
|
67
|
+
ToolType,
|
|
68
|
+
BaseTool,
|
|
69
|
+
NmapScanner,
|
|
70
|
+
NucleiScanner,
|
|
71
|
+
ExploitValidator as ExploitValidatorTool,
|
|
72
|
+
ReportGenerator,
|
|
73
|
+
SubdomainEnumerator,
|
|
74
|
+
ToolRegistry as AgentToolRegistry,
|
|
75
|
+
create_agent_loop
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
__all__ = [
|
|
79
|
+
# Core autonomous components
|
|
80
|
+
'AutonomousAgent',
|
|
81
|
+
'ReActLoop',
|
|
82
|
+
'Thought',
|
|
83
|
+
'Action',
|
|
84
|
+
'Observation',
|
|
85
|
+
'ToolExecutor',
|
|
86
|
+
'ToolRegistry',
|
|
87
|
+
'MemoryManager',
|
|
88
|
+
'WorkingMemory',
|
|
89
|
+
'LongTermMemory',
|
|
90
|
+
|
|
91
|
+
# Exploit Validator components
|
|
92
|
+
'ExploitValidator',
|
|
93
|
+
'ExploitValidatorPool',
|
|
94
|
+
'ExploitResult',
|
|
95
|
+
'ExploitType',
|
|
96
|
+
'ExploitStatus',
|
|
97
|
+
'SafetyLevel',
|
|
98
|
+
'Evidence',
|
|
99
|
+
'ScopeConfig',
|
|
100
|
+
'SandboxConfig',
|
|
101
|
+
'validate_sql_injection',
|
|
102
|
+
'validate_xss',
|
|
103
|
+
'validate_command_injection',
|
|
104
|
+
|
|
105
|
+
# Autonomous Agent Loop components
|
|
106
|
+
'AutonomousAgentLoop',
|
|
107
|
+
'AgentState',
|
|
108
|
+
'AgentMemory',
|
|
109
|
+
'ToolResult',
|
|
110
|
+
'PlanStep',
|
|
111
|
+
'ToolType',
|
|
112
|
+
'BaseTool',
|
|
113
|
+
'NmapScanner',
|
|
114
|
+
'NucleiScanner',
|
|
115
|
+
'ExploitValidatorTool',
|
|
116
|
+
'ReportGenerator',
|
|
117
|
+
'SubdomainEnumerator',
|
|
118
|
+
'AgentToolRegistry',
|
|
119
|
+
'create_agent_loop',
|
|
120
|
+
]
|
|
121
|
+
|
|
122
|
+
__version__ = '2.0.0'
|