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
autonomous/react.py ADDED
@@ -0,0 +1,339 @@
1
+ """
2
+ ReAct (Reasoning + Acting) Pattern Implementation
3
+
4
+ The ReAct loop allows the agent to:
5
+ 1. Think about the current situation (Reasoning)
6
+ 2. Decide what to do (Action)
7
+ 3. Observe the result (Observation)
8
+ 4. Repeat until goal is achieved
9
+
10
+ Based on: https://arxiv.org/abs/2210.03629
11
+ """
12
+
13
+ import asyncio
14
+ import json
15
+ import uuid
16
+ from abc import ABC, abstractmethod
17
+ from dataclasses import dataclass, field
18
+ from datetime import datetime
19
+ from enum import Enum, auto
20
+ from typing import Any, Callable, Dict, List, Optional, TypeVar, Generic
21
+
22
+
23
+ class ActionType(Enum):
24
+ """Types of actions the agent can take."""
25
+ THINK = auto() # Internal reasoning
26
+ TOOL_CALL = auto() # Execute a security tool
27
+ SEARCH_MEMORY = auto() # Recall past information
28
+ ASK_HUMAN = auto() # Request clarification
29
+ REPORT = auto() # Deliver findings
30
+ TERMINATE = auto() # End the session
31
+
32
+
33
+ @dataclass
34
+ class Thought:
35
+ """A reasoning step in the agent's thought process."""
36
+ content: str
37
+ context: Dict[str, Any] = field(default_factory=dict)
38
+ timestamp: datetime = field(default_factory=datetime.now)
39
+ step_number: int = 0
40
+
41
+ def to_dict(self) -> Dict:
42
+ return {
43
+ 'type': 'thought',
44
+ 'content': self.content,
45
+ 'context': self.context,
46
+ 'timestamp': self.timestamp.isoformat(),
47
+ 'step': self.step_number
48
+ }
49
+
50
+
51
+ @dataclass
52
+ class Action:
53
+ """An action the agent decides to take."""
54
+ type: ActionType
55
+ tool_name: Optional[str] = None
56
+ parameters: Dict[str, Any] = field(default_factory=dict)
57
+ reasoning: str = ""
58
+ timestamp: datetime = field(default_factory=datetime.now)
59
+ step_number: int = 0
60
+
61
+ def to_dict(self) -> Dict:
62
+ return {
63
+ 'type': 'action',
64
+ 'action_type': self.type.name,
65
+ 'tool': self.tool_name,
66
+ 'parameters': self.parameters,
67
+ 'reasoning': self.reasoning,
68
+ 'timestamp': self.timestamp.isoformat(),
69
+ 'step': self.step_number
70
+ }
71
+
72
+
73
+ @dataclass
74
+ class Observation:
75
+ """The result of executing an action."""
76
+ action: Action
77
+ result: Any
78
+ success: bool = True
79
+ error_message: Optional[str] = None
80
+ timestamp: datetime = field(default_factory=datetime.now)
81
+ step_number: int = 0
82
+
83
+ def to_dict(self) -> Dict:
84
+ return {
85
+ 'type': 'observation',
86
+ 'action': self.action.to_dict(),
87
+ 'result': self.result,
88
+ 'success': self.success,
89
+ 'error': self.error_message,
90
+ 'timestamp': self.timestamp.isoformat(),
91
+ 'step': self.step_number
92
+ }
93
+
94
+
95
+ class ReActLoop:
96
+ """
97
+ ReAct Reasoning Loop implementation.
98
+
99
+ Continuously cycles through:
100
+ 1. Reason about current state
101
+ 2. Decide on action
102
+ 3. Execute action
103
+ 4. Observe result
104
+ 5. Update state
105
+ """
106
+
107
+ def __init__(
108
+ self,
109
+ llm_client,
110
+ tool_executor,
111
+ memory_manager,
112
+ max_iterations: int = 50,
113
+ human_in_the_loop: bool = False
114
+ ):
115
+ self.llm = llm_client
116
+ self.tools = tool_executor
117
+ self.memory = memory_manager
118
+ self.max_iterations = max_iterations
119
+ self.human_in_the_loop = human_in_the_loop
120
+
121
+ self.history: List[Dict] = []
122
+ self.current_step: int = 0
123
+ self.goal: Optional[str] = None
124
+
125
+ async def run(self, goal: str, context: Optional[Dict] = None) -> Dict:
126
+ """
127
+ Execute the ReAct loop until goal is achieved or max iterations reached.
128
+
129
+ Args:
130
+ goal: The high-level objective
131
+ context: Additional context (target info, scope, etc.)
132
+
133
+ Returns:
134
+ Final result with findings and execution trace
135
+ """
136
+ self.goal = goal
137
+ self.current_step = 0
138
+ self.history = []
139
+
140
+ # Initialize with goal in memory
141
+ await self.memory.add_goal(goal, context)
142
+
143
+ print(f"[ReAct] Starting autonomous execution for goal: {goal}")
144
+
145
+ while self.current_step < self.max_iterations:
146
+ self.current_step += 1
147
+ print(f"\n[ReAct] Step {self.current_step}/{self.max_iterations}")
148
+
149
+ # 1. REASON: Think about current state
150
+ thought = await self._reason()
151
+ self.history.append(thought.to_dict())
152
+ print(f"[Thought] {thought.content[:100]}...")
153
+
154
+ # 2. ACT: Decide on action
155
+ action = await self._decide_action(thought)
156
+ self.history.append(action.to_dict())
157
+ print(f"[Action] {action.type.name}" + (f" ({action.tool_name})" if action.tool_name else ""))
158
+
159
+ # Check for termination
160
+ if action.type == ActionType.TERMINATE:
161
+ print("[ReAct] Goal achieved or terminated")
162
+ break
163
+
164
+ # 3. EXECUTE: Perform the action
165
+ observation = await self._execute_action(action)
166
+ self.history.append(observation.to_dict())
167
+
168
+ if observation.success:
169
+ result_str = str(observation.result)[:100] if observation.result else "None"
170
+ print(f"[Observation] Success: {result_str}...")
171
+ else:
172
+ print(f"[Observation] Failed: {observation.error_message}")
173
+
174
+ # 4. LEARN: Update memory
175
+ await self.memory.add_experience(thought, action, observation)
176
+
177
+ # Human checkpoint if enabled
178
+ if self.human_in_the_loop and action.type in [ActionType.TOOL_CALL, ActionType.REPORT]:
179
+ approved = await self._human_approval(action)
180
+ if not approved:
181
+ print("[ReAct] Human rejected action, stopping")
182
+ break
183
+
184
+ # Compile final result
185
+ return self._compile_result()
186
+
187
+ async def _reason(self) -> Thought:
188
+ """Generate a thought about the current situation."""
189
+ context = await self.memory.get_relevant_context(self.goal)
190
+
191
+ prompt = f"""You are an autonomous penetration testing agent.
192
+
193
+ Goal: {self.goal}
194
+
195
+ Current Context:
196
+ {json.dumps(context, indent=2)}
197
+
198
+ Execution History (last 5 steps):
199
+ {json.dumps(self.history[-5:], indent=2)}
200
+
201
+ Step {self.current_step}: What is your assessment of the current situation?
202
+ What have you learned? What should you do next?
203
+
204
+ Provide your reasoning:"""
205
+
206
+ response = await self.llm.generate(prompt)
207
+
208
+ return Thought(
209
+ content=response,
210
+ context={'goal': self.goal, 'step': self.current_step},
211
+ step_number=self.current_step
212
+ )
213
+
214
+ async def _decide_action(self, thought: Thought) -> Action:
215
+ """Decide on the next action based on reasoning."""
216
+ available_tools = self.tools.get_available_tools()
217
+
218
+ prompt = f"""Based on your reasoning: "{thought.content}"
219
+
220
+ Available Tools:
221
+ {json.dumps(available_tools, indent=2)}
222
+
223
+ Decide on the next action. Respond in JSON format:
224
+ {{
225
+ "action_type": "TOOL_CALL|SEARCH_MEMORY|ASK_HUMAN|REPORT|TERMINATE",
226
+ "tool_name": "name_of_tool_if_applicable",
227
+ "parameters": {{}},
228
+ "reasoning": "why this action"
229
+ }}
230
+
231
+ Rules:
232
+ - Use TOOL_CALL to execute security tools (nmap, nuclei, etc.)
233
+ - Use SEARCH_MEMORY to recall past findings
234
+ - Use REPORT when you have findings to deliver
235
+ - Use TERMINATE when goal is achieved or stuck"""
236
+
237
+ response = await self.llm.generate(prompt)
238
+
239
+ try:
240
+ # Extract JSON from response
241
+ json_start = response.find('{')
242
+ json_end = response.rfind('}') + 1
243
+ if json_start >= 0 and json_end > json_start:
244
+ decision = json.loads(response[json_start:json_end])
245
+ else:
246
+ decision = json.loads(response)
247
+
248
+ action_type = ActionType[decision.get('action_type', 'THINK')]
249
+
250
+ return Action(
251
+ type=action_type,
252
+ tool_name=decision.get('tool_name'),
253
+ parameters=decision.get('parameters', {}),
254
+ reasoning=decision.get('reasoning', ''),
255
+ step_number=self.current_step
256
+ )
257
+ except (json.JSONDecodeError, KeyError) as e:
258
+ # Fallback to thinking if parsing fails
259
+ return Action(
260
+ type=ActionType.THINK,
261
+ reasoning=f"Failed to parse action: {str(e)}",
262
+ step_number=self.current_step
263
+ )
264
+
265
+ async def _execute_action(self, action: Action) -> Observation:
266
+ """Execute the decided action."""
267
+ try:
268
+ if action.type == ActionType.TOOL_CALL and action.tool_name:
269
+ result = await self.tools.execute(
270
+ action.tool_name,
271
+ action.parameters
272
+ )
273
+ return Observation(
274
+ action=action,
275
+ result=result,
276
+ success=True,
277
+ step_number=self.current_step
278
+ )
279
+
280
+ elif action.type == ActionType.SEARCH_MEMORY:
281
+ query = action.parameters.get('query', self.goal)
282
+ results = await self.memory.search(query)
283
+ return Observation(
284
+ action=action,
285
+ result=results,
286
+ success=True,
287
+ step_number=self.current_step
288
+ )
289
+
290
+ elif action.type == ActionType.REPORT:
291
+ findings = await self.memory.get_findings()
292
+ return Observation(
293
+ action=action,
294
+ result={'findings': findings, 'ready': True},
295
+ success=True,
296
+ step_number=self.current_step
297
+ )
298
+
299
+ else:
300
+ return Observation(
301
+ action=action,
302
+ result=None,
303
+ success=True,
304
+ step_number=self.current_step
305
+ )
306
+
307
+ except Exception as e:
308
+ return Observation(
309
+ action=action,
310
+ result=None,
311
+ success=False,
312
+ error_message=str(e),
313
+ step_number=self.current_step
314
+ )
315
+
316
+ async def _human_approval(self, action: Action) -> bool:
317
+ """Request human approval for critical actions."""
318
+ print(f"\n[Human Approval Required]")
319
+ print(f"Action: {action.type.name}")
320
+ print(f"Tool: {action.tool_name}")
321
+ print(f"Parameters: {action.parameters}")
322
+ print(f"Reasoning: {action.reasoning}")
323
+
324
+ # In real implementation, this would be a UI prompt
325
+ # For now, auto-approve in autonomous mode
326
+ return True
327
+
328
+ def _compile_result(self) -> Dict:
329
+ """Compile the final execution result."""
330
+ findings = [h for h in self.history if h.get('type') == 'observation']
331
+
332
+ return {
333
+ 'goal': self.goal,
334
+ 'completed': self.current_step < self.max_iterations,
335
+ 'steps_taken': self.current_step,
336
+ 'history': self.history,
337
+ 'findings': findings,
338
+ 'execution_trace': f"Completed in {self.current_step} steps"
339
+ }