aiptx 2.0.7__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 (187) hide show
  1. aipt_v2/__init__.py +110 -0
  2. aipt_v2/__main__.py +24 -0
  3. aipt_v2/agents/AIPTxAgent/__init__.py +10 -0
  4. aipt_v2/agents/AIPTxAgent/aiptx_agent.py +211 -0
  5. aipt_v2/agents/__init__.py +46 -0
  6. aipt_v2/agents/base.py +520 -0
  7. aipt_v2/agents/exploit_agent.py +688 -0
  8. aipt_v2/agents/ptt.py +406 -0
  9. aipt_v2/agents/state.py +168 -0
  10. aipt_v2/app.py +957 -0
  11. aipt_v2/browser/__init__.py +31 -0
  12. aipt_v2/browser/automation.py +458 -0
  13. aipt_v2/browser/crawler.py +453 -0
  14. aipt_v2/cli.py +2933 -0
  15. aipt_v2/compliance/__init__.py +71 -0
  16. aipt_v2/compliance/compliance_report.py +449 -0
  17. aipt_v2/compliance/framework_mapper.py +424 -0
  18. aipt_v2/compliance/nist_mapping.py +345 -0
  19. aipt_v2/compliance/owasp_mapping.py +330 -0
  20. aipt_v2/compliance/pci_mapping.py +297 -0
  21. aipt_v2/config.py +341 -0
  22. aipt_v2/core/__init__.py +43 -0
  23. aipt_v2/core/agent.py +630 -0
  24. aipt_v2/core/llm.py +395 -0
  25. aipt_v2/core/memory.py +305 -0
  26. aipt_v2/core/ptt.py +329 -0
  27. aipt_v2/database/__init__.py +14 -0
  28. aipt_v2/database/models.py +232 -0
  29. aipt_v2/database/repository.py +384 -0
  30. aipt_v2/docker/__init__.py +23 -0
  31. aipt_v2/docker/builder.py +260 -0
  32. aipt_v2/docker/manager.py +222 -0
  33. aipt_v2/docker/sandbox.py +371 -0
  34. aipt_v2/evasion/__init__.py +58 -0
  35. aipt_v2/evasion/request_obfuscator.py +272 -0
  36. aipt_v2/evasion/tls_fingerprint.py +285 -0
  37. aipt_v2/evasion/ua_rotator.py +301 -0
  38. aipt_v2/evasion/waf_bypass.py +439 -0
  39. aipt_v2/execution/__init__.py +23 -0
  40. aipt_v2/execution/executor.py +302 -0
  41. aipt_v2/execution/parser.py +544 -0
  42. aipt_v2/execution/terminal.py +337 -0
  43. aipt_v2/health.py +437 -0
  44. aipt_v2/intelligence/__init__.py +194 -0
  45. aipt_v2/intelligence/adaptation.py +474 -0
  46. aipt_v2/intelligence/auth.py +520 -0
  47. aipt_v2/intelligence/chaining.py +775 -0
  48. aipt_v2/intelligence/correlation.py +536 -0
  49. aipt_v2/intelligence/cve_aipt.py +334 -0
  50. aipt_v2/intelligence/cve_info.py +1111 -0
  51. aipt_v2/intelligence/knowledge_graph.py +590 -0
  52. aipt_v2/intelligence/learning.py +626 -0
  53. aipt_v2/intelligence/llm_analyzer.py +502 -0
  54. aipt_v2/intelligence/llm_tool_selector.py +518 -0
  55. aipt_v2/intelligence/payload_generator.py +562 -0
  56. aipt_v2/intelligence/rag.py +239 -0
  57. aipt_v2/intelligence/scope.py +442 -0
  58. aipt_v2/intelligence/searchers/__init__.py +5 -0
  59. aipt_v2/intelligence/searchers/exploitdb_searcher.py +523 -0
  60. aipt_v2/intelligence/searchers/github_searcher.py +467 -0
  61. aipt_v2/intelligence/searchers/google_searcher.py +281 -0
  62. aipt_v2/intelligence/tools.json +443 -0
  63. aipt_v2/intelligence/triage.py +670 -0
  64. aipt_v2/interactive_shell.py +559 -0
  65. aipt_v2/interface/__init__.py +5 -0
  66. aipt_v2/interface/cli.py +230 -0
  67. aipt_v2/interface/main.py +501 -0
  68. aipt_v2/interface/tui.py +1276 -0
  69. aipt_v2/interface/utils.py +583 -0
  70. aipt_v2/llm/__init__.py +39 -0
  71. aipt_v2/llm/config.py +26 -0
  72. aipt_v2/llm/llm.py +514 -0
  73. aipt_v2/llm/memory.py +214 -0
  74. aipt_v2/llm/request_queue.py +89 -0
  75. aipt_v2/llm/utils.py +89 -0
  76. aipt_v2/local_tool_installer.py +1467 -0
  77. aipt_v2/models/__init__.py +15 -0
  78. aipt_v2/models/findings.py +295 -0
  79. aipt_v2/models/phase_result.py +224 -0
  80. aipt_v2/models/scan_config.py +207 -0
  81. aipt_v2/monitoring/grafana/dashboards/aipt-dashboard.json +355 -0
  82. aipt_v2/monitoring/grafana/dashboards/default.yml +17 -0
  83. aipt_v2/monitoring/grafana/datasources/prometheus.yml +17 -0
  84. aipt_v2/monitoring/prometheus.yml +60 -0
  85. aipt_v2/orchestration/__init__.py +52 -0
  86. aipt_v2/orchestration/pipeline.py +398 -0
  87. aipt_v2/orchestration/progress.py +300 -0
  88. aipt_v2/orchestration/scheduler.py +296 -0
  89. aipt_v2/orchestrator.py +2427 -0
  90. aipt_v2/payloads/__init__.py +27 -0
  91. aipt_v2/payloads/cmdi.py +150 -0
  92. aipt_v2/payloads/sqli.py +263 -0
  93. aipt_v2/payloads/ssrf.py +204 -0
  94. aipt_v2/payloads/templates.py +222 -0
  95. aipt_v2/payloads/traversal.py +166 -0
  96. aipt_v2/payloads/xss.py +204 -0
  97. aipt_v2/prompts/__init__.py +60 -0
  98. aipt_v2/proxy/__init__.py +29 -0
  99. aipt_v2/proxy/history.py +352 -0
  100. aipt_v2/proxy/interceptor.py +452 -0
  101. aipt_v2/recon/__init__.py +44 -0
  102. aipt_v2/recon/dns.py +241 -0
  103. aipt_v2/recon/osint.py +367 -0
  104. aipt_v2/recon/subdomain.py +372 -0
  105. aipt_v2/recon/tech_detect.py +311 -0
  106. aipt_v2/reports/__init__.py +17 -0
  107. aipt_v2/reports/generator.py +313 -0
  108. aipt_v2/reports/html_report.py +378 -0
  109. aipt_v2/runtime/__init__.py +53 -0
  110. aipt_v2/runtime/base.py +30 -0
  111. aipt_v2/runtime/docker.py +401 -0
  112. aipt_v2/runtime/local.py +346 -0
  113. aipt_v2/runtime/tool_server.py +205 -0
  114. aipt_v2/runtime/vps.py +830 -0
  115. aipt_v2/scanners/__init__.py +28 -0
  116. aipt_v2/scanners/base.py +273 -0
  117. aipt_v2/scanners/nikto.py +244 -0
  118. aipt_v2/scanners/nmap.py +402 -0
  119. aipt_v2/scanners/nuclei.py +273 -0
  120. aipt_v2/scanners/web.py +454 -0
  121. aipt_v2/scripts/security_audit.py +366 -0
  122. aipt_v2/setup_wizard.py +941 -0
  123. aipt_v2/skills/__init__.py +80 -0
  124. aipt_v2/skills/agents/__init__.py +14 -0
  125. aipt_v2/skills/agents/api_tester.py +706 -0
  126. aipt_v2/skills/agents/base.py +477 -0
  127. aipt_v2/skills/agents/code_review.py +459 -0
  128. aipt_v2/skills/agents/security_agent.py +336 -0
  129. aipt_v2/skills/agents/web_pentest.py +818 -0
  130. aipt_v2/skills/prompts/__init__.py +647 -0
  131. aipt_v2/system_detector.py +539 -0
  132. aipt_v2/telemetry/__init__.py +7 -0
  133. aipt_v2/telemetry/tracer.py +347 -0
  134. aipt_v2/terminal/__init__.py +28 -0
  135. aipt_v2/terminal/executor.py +400 -0
  136. aipt_v2/terminal/sandbox.py +350 -0
  137. aipt_v2/tools/__init__.py +44 -0
  138. aipt_v2/tools/active_directory/__init__.py +78 -0
  139. aipt_v2/tools/active_directory/ad_config.py +238 -0
  140. aipt_v2/tools/active_directory/bloodhound_wrapper.py +447 -0
  141. aipt_v2/tools/active_directory/kerberos_attacks.py +430 -0
  142. aipt_v2/tools/active_directory/ldap_enum.py +533 -0
  143. aipt_v2/tools/active_directory/smb_attacks.py +505 -0
  144. aipt_v2/tools/agents_graph/__init__.py +19 -0
  145. aipt_v2/tools/agents_graph/agents_graph_actions.py +69 -0
  146. aipt_v2/tools/api_security/__init__.py +76 -0
  147. aipt_v2/tools/api_security/api_discovery.py +608 -0
  148. aipt_v2/tools/api_security/graphql_scanner.py +622 -0
  149. aipt_v2/tools/api_security/jwt_analyzer.py +577 -0
  150. aipt_v2/tools/api_security/openapi_fuzzer.py +761 -0
  151. aipt_v2/tools/browser/__init__.py +5 -0
  152. aipt_v2/tools/browser/browser_actions.py +238 -0
  153. aipt_v2/tools/browser/browser_instance.py +535 -0
  154. aipt_v2/tools/browser/tab_manager.py +344 -0
  155. aipt_v2/tools/cloud/__init__.py +70 -0
  156. aipt_v2/tools/cloud/cloud_config.py +273 -0
  157. aipt_v2/tools/cloud/cloud_scanner.py +639 -0
  158. aipt_v2/tools/cloud/prowler_tool.py +571 -0
  159. aipt_v2/tools/cloud/scoutsuite_tool.py +359 -0
  160. aipt_v2/tools/executor.py +307 -0
  161. aipt_v2/tools/parser.py +408 -0
  162. aipt_v2/tools/proxy/__init__.py +5 -0
  163. aipt_v2/tools/proxy/proxy_actions.py +103 -0
  164. aipt_v2/tools/proxy/proxy_manager.py +789 -0
  165. aipt_v2/tools/registry.py +196 -0
  166. aipt_v2/tools/scanners/__init__.py +343 -0
  167. aipt_v2/tools/scanners/acunetix_tool.py +712 -0
  168. aipt_v2/tools/scanners/burp_tool.py +631 -0
  169. aipt_v2/tools/scanners/config.py +156 -0
  170. aipt_v2/tools/scanners/nessus_tool.py +588 -0
  171. aipt_v2/tools/scanners/zap_tool.py +612 -0
  172. aipt_v2/tools/terminal/__init__.py +5 -0
  173. aipt_v2/tools/terminal/terminal_actions.py +37 -0
  174. aipt_v2/tools/terminal/terminal_manager.py +153 -0
  175. aipt_v2/tools/terminal/terminal_session.py +449 -0
  176. aipt_v2/tools/tool_processing.py +108 -0
  177. aipt_v2/utils/__init__.py +17 -0
  178. aipt_v2/utils/logging.py +202 -0
  179. aipt_v2/utils/model_manager.py +187 -0
  180. aipt_v2/utils/searchers/__init__.py +269 -0
  181. aipt_v2/verify_install.py +793 -0
  182. aiptx-2.0.7.dist-info/METADATA +345 -0
  183. aiptx-2.0.7.dist-info/RECORD +187 -0
  184. aiptx-2.0.7.dist-info/WHEEL +5 -0
  185. aiptx-2.0.7.dist-info/entry_points.txt +7 -0
  186. aiptx-2.0.7.dist-info/licenses/LICENSE +21 -0
  187. aiptx-2.0.7.dist-info/top_level.txt +1 -0
@@ -0,0 +1,350 @@
1
+ """
2
+ AIPT Docker Sandbox
3
+
4
+ Isolated command execution in Docker containers for safety.
5
+ """
6
+ from __future__ import annotations
7
+
8
+ import asyncio
9
+ import logging
10
+ import os
11
+ import tempfile
12
+ from dataclasses import dataclass, field
13
+ from datetime import datetime
14
+ from typing import Optional
15
+
16
+ from .executor import CommandResult, ExecutionStatus
17
+
18
+ logger = logging.getLogger(__name__)
19
+
20
+
21
+ @dataclass
22
+ class SandboxConfig:
23
+ """Docker sandbox configuration"""
24
+ image: str = "python:3.11-slim" # Base image
25
+ network_mode: str = "bridge" # none, bridge, host
26
+ memory_limit: str = "512m"
27
+ cpu_limit: float = 1.0
28
+ timeout: float = 300.0
29
+
30
+ # Volume mounts
31
+ mount_workspace: bool = True
32
+ workspace_path: str = "/workspace"
33
+ read_only_root: bool = True
34
+
35
+ # Security
36
+ no_new_privileges: bool = True
37
+ drop_capabilities: list[str] = field(default_factory=lambda: ["ALL"])
38
+ add_capabilities: list[str] = field(default_factory=list)
39
+
40
+ # Cleanup
41
+ auto_remove: bool = True
42
+
43
+
44
+ class DockerSandbox:
45
+ """
46
+ Docker-based sandbox for isolated command execution.
47
+
48
+ Provides secure execution environment with:
49
+ - Network isolation
50
+ - Resource limits
51
+ - Filesystem isolation
52
+ - Capability dropping
53
+
54
+ Example:
55
+ sandbox = DockerSandbox()
56
+ await sandbox.start()
57
+ result = await sandbox.execute("python exploit.py")
58
+ await sandbox.stop()
59
+
60
+ # Or use context manager
61
+ async with DockerSandbox() as sandbox:
62
+ result = await sandbox.execute("nmap -sV target.com")
63
+ """
64
+
65
+ def __init__(self, config: Optional[SandboxConfig] = None):
66
+ self.config = config or SandboxConfig()
67
+ self._container_id: Optional[str] = None
68
+ self._temp_dir: Optional[str] = None
69
+ self._is_running = False
70
+
71
+ async def __aenter__(self) -> "DockerSandbox":
72
+ await self.start()
73
+ return self
74
+
75
+ async def __aexit__(self, exc_type, exc_val, exc_tb):
76
+ await self.stop()
77
+
78
+ async def start(self) -> bool:
79
+ """Start the sandbox container"""
80
+ if self._is_running:
81
+ return True
82
+
83
+ # Check Docker availability
84
+ if not await self._check_docker():
85
+ logger.error("Docker is not available")
86
+ return False
87
+
88
+ # Create temp directory for workspace
89
+ self._temp_dir = tempfile.mkdtemp(prefix="aipt_sandbox_")
90
+
91
+ # Build docker run command
92
+ cmd_parts = ["docker", "run", "-d"]
93
+
94
+ # Resource limits
95
+ cmd_parts.extend(["--memory", self.config.memory_limit])
96
+ cmd_parts.extend(["--cpus", str(self.config.cpu_limit)])
97
+
98
+ # Network
99
+ cmd_parts.extend(["--network", self.config.network_mode])
100
+
101
+ # Security
102
+ if self.config.no_new_privileges:
103
+ cmd_parts.append("--security-opt=no-new-privileges")
104
+
105
+ for cap in self.config.drop_capabilities:
106
+ cmd_parts.extend(["--cap-drop", cap])
107
+ for cap in self.config.add_capabilities:
108
+ cmd_parts.extend(["--cap-add", cap])
109
+
110
+ if self.config.read_only_root:
111
+ cmd_parts.append("--read-only")
112
+ cmd_parts.extend(["--tmpfs", "/tmp:rw,noexec,nosuid,size=100m"])
113
+
114
+ # Workspace mount
115
+ if self.config.mount_workspace:
116
+ cmd_parts.extend([
117
+ "-v", f"{self._temp_dir}:{self.config.workspace_path}:rw"
118
+ ])
119
+ cmd_parts.extend(["-w", self.config.workspace_path])
120
+
121
+ # Auto-remove
122
+ if self.config.auto_remove:
123
+ cmd_parts.append("--rm")
124
+
125
+ # Image and keep alive command
126
+ cmd_parts.extend([self.config.image, "tail", "-f", "/dev/null"])
127
+
128
+ # Start container
129
+ try:
130
+ process = await asyncio.create_subprocess_exec(
131
+ *cmd_parts,
132
+ stdout=asyncio.subprocess.PIPE,
133
+ stderr=asyncio.subprocess.PIPE,
134
+ )
135
+ stdout, stderr = await process.communicate()
136
+
137
+ if process.returncode != 0:
138
+ logger.error(f"Failed to start container: {stderr.decode()}")
139
+ return False
140
+
141
+ self._container_id = stdout.decode().strip()[:12]
142
+ self._is_running = True
143
+ logger.info(f"Sandbox started: {self._container_id}")
144
+ return True
145
+
146
+ except Exception as e:
147
+ logger.error(f"Error starting sandbox: {e}")
148
+ return False
149
+
150
+ async def stop(self) -> bool:
151
+ """Stop and cleanup the sandbox"""
152
+ if not self._is_running or not self._container_id:
153
+ return True
154
+
155
+ try:
156
+ process = await asyncio.create_subprocess_exec(
157
+ "docker", "stop", "-t", "5", self._container_id,
158
+ stdout=asyncio.subprocess.PIPE,
159
+ stderr=asyncio.subprocess.PIPE,
160
+ )
161
+ await process.communicate()
162
+
163
+ self._is_running = False
164
+ self._container_id = None
165
+
166
+ # Cleanup temp dir
167
+ if self._temp_dir and os.path.exists(self._temp_dir):
168
+ import shutil
169
+ shutil.rmtree(self._temp_dir, ignore_errors=True)
170
+ self._temp_dir = None
171
+
172
+ logger.info("Sandbox stopped")
173
+ return True
174
+
175
+ except Exception as e:
176
+ logger.error(f"Error stopping sandbox: {e}")
177
+ return False
178
+
179
+ async def execute(
180
+ self,
181
+ command: str,
182
+ timeout: Optional[float] = None,
183
+ user: str = "root",
184
+ ) -> CommandResult:
185
+ """
186
+ Execute command inside the sandbox.
187
+
188
+ Args:
189
+ command: Command to execute
190
+ timeout: Override timeout
191
+ user: User to run as
192
+
193
+ Returns:
194
+ CommandResult
195
+ """
196
+ if not self._is_running:
197
+ return CommandResult(
198
+ command=command,
199
+ status=ExecutionStatus.FAILED,
200
+ stderr="Sandbox not running",
201
+ )
202
+
203
+ timeout = timeout or self.config.timeout
204
+ result = CommandResult(
205
+ command=command,
206
+ status=ExecutionStatus.RUNNING,
207
+ start_time=datetime.utcnow(),
208
+ )
209
+
210
+ try:
211
+ # Docker exec command
212
+ exec_cmd = [
213
+ "docker", "exec",
214
+ "-u", user,
215
+ self._container_id,
216
+ "sh", "-c", command,
217
+ ]
218
+
219
+ process = await asyncio.create_subprocess_exec(
220
+ *exec_cmd,
221
+ stdout=asyncio.subprocess.PIPE,
222
+ stderr=asyncio.subprocess.PIPE,
223
+ )
224
+
225
+ try:
226
+ stdout, stderr = await asyncio.wait_for(
227
+ process.communicate(),
228
+ timeout=timeout,
229
+ )
230
+
231
+ result.exit_code = process.returncode
232
+ result.status = (
233
+ ExecutionStatus.SUCCESS
234
+ if process.returncode == 0
235
+ else ExecutionStatus.FAILED
236
+ )
237
+ result.stdout = stdout.decode("utf-8", errors="replace")
238
+ result.stderr = stderr.decode("utf-8", errors="replace")
239
+
240
+ except asyncio.TimeoutError:
241
+ process.kill()
242
+ result.status = ExecutionStatus.TIMEOUT
243
+ result.stderr = f"Command timed out after {timeout}s"
244
+
245
+ except Exception as e:
246
+ result.status = ExecutionStatus.FAILED
247
+ result.stderr = str(e)
248
+ finally:
249
+ result.end_time = datetime.utcnow()
250
+ if result.start_time:
251
+ result.duration_seconds = (result.end_time - result.start_time).total_seconds()
252
+
253
+ return result
254
+
255
+ async def copy_to(self, local_path: str, container_path: str) -> bool:
256
+ """Copy file into sandbox"""
257
+ if not self._is_running:
258
+ return False
259
+
260
+ try:
261
+ process = await asyncio.create_subprocess_exec(
262
+ "docker", "cp", local_path, f"{self._container_id}:{container_path}",
263
+ stdout=asyncio.subprocess.PIPE,
264
+ stderr=asyncio.subprocess.PIPE,
265
+ )
266
+ _, stderr = await process.communicate()
267
+ return process.returncode == 0
268
+ except Exception:
269
+ return False
270
+
271
+ async def copy_from(self, container_path: str, local_path: str) -> bool:
272
+ """Copy file from sandbox"""
273
+ if not self._is_running:
274
+ return False
275
+
276
+ try:
277
+ process = await asyncio.create_subprocess_exec(
278
+ "docker", "cp", f"{self._container_id}:{container_path}", local_path,
279
+ stdout=asyncio.subprocess.PIPE,
280
+ stderr=asyncio.subprocess.PIPE,
281
+ )
282
+ _, stderr = await process.communicate()
283
+ return process.returncode == 0
284
+ except Exception:
285
+ return False
286
+
287
+ def write_to_workspace(self, filename: str, content: str) -> Optional[str]:
288
+ """Write file to workspace directory"""
289
+ if not self._temp_dir:
290
+ return None
291
+ filepath = os.path.join(self._temp_dir, filename)
292
+ with open(filepath, "w") as f:
293
+ f.write(content)
294
+ return os.path.join(self.config.workspace_path, filename)
295
+
296
+ async def _check_docker(self) -> bool:
297
+ """Check if Docker is available"""
298
+ try:
299
+ process = await asyncio.create_subprocess_exec(
300
+ "docker", "info",
301
+ stdout=asyncio.subprocess.PIPE,
302
+ stderr=asyncio.subprocess.PIPE,
303
+ )
304
+ await process.communicate()
305
+ return process.returncode == 0
306
+ except FileNotFoundError:
307
+ return False
308
+
309
+ @property
310
+ def is_running(self) -> bool:
311
+ return self._is_running
312
+
313
+ @property
314
+ def container_id(self) -> Optional[str]:
315
+ return self._container_id
316
+
317
+
318
+ # Security-focused sandbox presets
319
+ def create_network_scanner_sandbox() -> DockerSandbox:
320
+ """Sandbox configured for network scanning tools"""
321
+ return DockerSandbox(SandboxConfig(
322
+ image="instrumentisto/nmap:latest",
323
+ network_mode="host", # Need host networking for scanning
324
+ memory_limit="1g",
325
+ timeout=600.0,
326
+ add_capabilities=["NET_RAW", "NET_ADMIN"],
327
+ ))
328
+
329
+
330
+ def create_web_scanner_sandbox() -> DockerSandbox:
331
+ """Sandbox configured for web scanning"""
332
+ return DockerSandbox(SandboxConfig(
333
+ image="python:3.11-slim",
334
+ network_mode="bridge",
335
+ memory_limit="512m",
336
+ timeout=300.0,
337
+ ))
338
+
339
+
340
+ def create_exploit_sandbox() -> DockerSandbox:
341
+ """Highly isolated sandbox for running exploits"""
342
+ return DockerSandbox(SandboxConfig(
343
+ image="python:3.11-slim",
344
+ network_mode="none", # No network access
345
+ memory_limit="256m",
346
+ cpu_limit=0.5,
347
+ timeout=60.0,
348
+ read_only_root=True,
349
+ drop_capabilities=["ALL"],
350
+ ))
@@ -0,0 +1,44 @@
1
+ """
2
+ AIPT Tools Module - Terminal, Browser, Proxy, and Output Parsing
3
+ """
4
+
5
+ from aipt_v2.tools.parser import OutputParser, Finding
6
+ from aipt_v2.tools.tool_processing import process_tool_invocations
7
+
8
+
9
+ def get_tools_prompt() -> str:
10
+ """Get the tools prompt for the agent."""
11
+ return """
12
+ You have access to the following security tools:
13
+
14
+ ## Terminal Tools
15
+ - execute_command: Run shell commands in isolated Docker sandbox
16
+ - terminal_session: Manage persistent terminal sessions
17
+
18
+ ## Browser Tools
19
+ - browser_navigate: Navigate to URLs
20
+ - browser_click: Click elements
21
+ - browser_type: Type text into inputs
22
+ - browser_screenshot: Take screenshots
23
+
24
+ ## Proxy Tools
25
+ - proxy_intercept: Intercept HTTP traffic
26
+ - proxy_modify: Modify requests/responses
27
+
28
+ ## Security Tools
29
+ - nmap: Port scanning and service detection
30
+ - gobuster: Directory brute-forcing
31
+ - nuclei: Vulnerability scanning
32
+ - hydra: Credential brute-forcing
33
+ - sqlmap: SQL injection testing
34
+
35
+ Use these tools to accomplish your penetration testing objectives.
36
+ """
37
+
38
+
39
+ __all__ = [
40
+ "OutputParser",
41
+ "Finding",
42
+ "process_tool_invocations",
43
+ "get_tools_prompt",
44
+ ]
@@ -0,0 +1,78 @@
1
+ """
2
+ AIPT Active Directory Security Module
3
+
4
+ Comprehensive Active Directory penetration testing:
5
+ - BloodHound integration for attack path mapping
6
+ - Kerberos attacks (Kerberoasting, AS-REP roasting)
7
+ - LDAP enumeration (users, groups, computers, GPOs)
8
+ - SMB attacks (relay, pass-the-hash, PsExec)
9
+ - Domain trust enumeration and abuse
10
+
11
+ Usage:
12
+ from aipt_v2.tools.active_directory import (
13
+ ADScanner,
14
+ BloodHoundWrapper,
15
+ KerberosAttacks,
16
+ LDAPEnum,
17
+ SMBAttacks
18
+ )
19
+
20
+ # Run full AD assessment
21
+ scanner = ADScanner(domain="corp.local", dc_ip="10.0.0.1")
22
+ findings = await scanner.scan(username="user", password="pass")
23
+ """
24
+
25
+ from aipt_v2.tools.active_directory.ad_config import (
26
+ ADConfig,
27
+ ADCredentials,
28
+ get_ad_config,
29
+ )
30
+
31
+ from aipt_v2.tools.active_directory.ldap_enum import (
32
+ LDAPEnum,
33
+ LDAPFinding,
34
+ enumerate_ldap,
35
+ )
36
+
37
+ from aipt_v2.tools.active_directory.kerberos_attacks import (
38
+ KerberosAttacks,
39
+ KerberosFinding,
40
+ run_kerberoast,
41
+ run_asreproast,
42
+ )
43
+
44
+ from aipt_v2.tools.active_directory.smb_attacks import (
45
+ SMBAttacks,
46
+ SMBFinding,
47
+ enumerate_smb,
48
+ )
49
+
50
+ from aipt_v2.tools.active_directory.bloodhound_wrapper import (
51
+ BloodHoundWrapper,
52
+ BloodHoundResult,
53
+ run_bloodhound,
54
+ )
55
+
56
+ __all__ = [
57
+ # Config
58
+ "ADConfig",
59
+ "ADCredentials",
60
+ "get_ad_config",
61
+ # LDAP
62
+ "LDAPEnum",
63
+ "LDAPFinding",
64
+ "enumerate_ldap",
65
+ # Kerberos
66
+ "KerberosAttacks",
67
+ "KerberosFinding",
68
+ "run_kerberoast",
69
+ "run_asreproast",
70
+ # SMB
71
+ "SMBAttacks",
72
+ "SMBFinding",
73
+ "enumerate_smb",
74
+ # BloodHound
75
+ "BloodHoundWrapper",
76
+ "BloodHoundResult",
77
+ "run_bloodhound",
78
+ ]
@@ -0,0 +1,238 @@
1
+ """
2
+ Active Directory Configuration
3
+
4
+ Handles credentials and configuration for AD penetration testing.
5
+ Supports multiple authentication methods:
6
+ - Password authentication
7
+ - NTLM hash authentication (pass-the-hash)
8
+ - Kerberos ticket authentication
9
+
10
+ Usage:
11
+ from aipt_v2.tools.active_directory import ADConfig, get_ad_config
12
+
13
+ config = get_ad_config(
14
+ domain="corp.local",
15
+ dc_ip="10.0.0.1",
16
+ username="admin",
17
+ password="secret"
18
+ )
19
+ """
20
+
21
+ import os
22
+ from dataclasses import dataclass, field
23
+ from typing import Optional, List
24
+
25
+
26
+ @dataclass
27
+ class ADCredentials:
28
+ """Active Directory credentials."""
29
+ username: str = ""
30
+ password: str = ""
31
+ domain: str = ""
32
+
33
+ # Alternative auth methods
34
+ ntlm_hash: str = "" # Format: LMHASH:NTHASH or just NTHASH
35
+ aes_key: str = "" # Kerberos AES key
36
+ ccache_file: str = "" # Kerberos ticket cache
37
+
38
+ # Kerberos options
39
+ use_kerberos: bool = False
40
+ kdcHost: str = ""
41
+
42
+ def __post_init__(self):
43
+ """Load from environment if not provided."""
44
+ if not self.username:
45
+ self.username = os.getenv("AD_USERNAME", "")
46
+ if not self.password:
47
+ self.password = os.getenv("AD_PASSWORD", "")
48
+ if not self.domain:
49
+ self.domain = os.getenv("AD_DOMAIN", "")
50
+ if not self.ntlm_hash:
51
+ self.ntlm_hash = os.getenv("AD_NTLM_HASH", "")
52
+ if not self.ccache_file:
53
+ self.ccache_file = os.getenv("KRB5CCNAME", "")
54
+
55
+ def get_auth_string(self) -> str:
56
+ """Get authentication string for tools."""
57
+ if self.domain and self.username:
58
+ return f"{self.domain}\\{self.username}"
59
+ return self.username
60
+
61
+ def has_credentials(self) -> bool:
62
+ """Check if valid credentials are available."""
63
+ return bool(
64
+ (self.username and self.password) or
65
+ (self.username and self.ntlm_hash) or
66
+ self.ccache_file
67
+ )
68
+
69
+ def is_hash_auth(self) -> bool:
70
+ """Check if using hash-based authentication."""
71
+ return bool(self.ntlm_hash and not self.password)
72
+
73
+ def get_password_or_hash(self) -> str:
74
+ """Get password or hash for authentication."""
75
+ return self.password if self.password else self.ntlm_hash
76
+
77
+
78
+ @dataclass
79
+ class ADConfig:
80
+ """Active Directory scanning configuration."""
81
+ # Domain settings
82
+ domain: str = ""
83
+ dc_ip: str = ""
84
+ dc_hostname: str = ""
85
+
86
+ # Credentials
87
+ credentials: ADCredentials = field(default_factory=ADCredentials)
88
+
89
+ # Target settings
90
+ target_users: List[str] = field(default_factory=list)
91
+ target_groups: List[str] = field(default_factory=list)
92
+ target_computers: List[str] = field(default_factory=list)
93
+
94
+ # Scanning options
95
+ enum_users: bool = True
96
+ enum_groups: bool = True
97
+ enum_computers: bool = True
98
+ enum_gpos: bool = True
99
+ enum_trusts: bool = True
100
+
101
+ # Attack options
102
+ run_kerberoast: bool = False
103
+ run_asreproast: bool = False
104
+ run_bloodhound: bool = False
105
+
106
+ # Output
107
+ output_dir: str = "./ad_results"
108
+
109
+ # LDAP settings
110
+ ldap_port: int = 389
111
+ ldaps_port: int = 636
112
+ use_ssl: bool = False
113
+ use_gc: bool = False # Global Catalog (port 3268/3269)
114
+
115
+ # Timeouts
116
+ timeout: int = 30
117
+
118
+ def __post_init__(self):
119
+ """Initialize from environment."""
120
+ if not self.domain:
121
+ self.domain = os.getenv("AD_DOMAIN", "")
122
+ if not self.dc_ip:
123
+ self.dc_ip = os.getenv("AD_DC_IP", os.getenv("DC_IP", ""))
124
+
125
+ # Ensure credentials have domain
126
+ if self.domain and not self.credentials.domain:
127
+ self.credentials.domain = self.domain
128
+
129
+ def get_ldap_uri(self) -> str:
130
+ """Get LDAP connection URI."""
131
+ protocol = "ldaps" if self.use_ssl else "ldap"
132
+ port = self.ldaps_port if self.use_ssl else self.ldap_port
133
+
134
+ if self.use_gc:
135
+ port = 3269 if self.use_ssl else 3268
136
+
137
+ host = self.dc_ip or self.dc_hostname
138
+ return f"{protocol}://{host}:{port}"
139
+
140
+ def get_base_dn(self) -> str:
141
+ """Get LDAP base DN from domain."""
142
+ if not self.domain:
143
+ return ""
144
+ parts = self.domain.split(".")
145
+ return ",".join([f"DC={part}" for part in parts])
146
+
147
+ def is_configured(self) -> bool:
148
+ """Check if AD is properly configured."""
149
+ return bool(
150
+ self.domain and
151
+ (self.dc_ip or self.dc_hostname) and
152
+ self.credentials.has_credentials()
153
+ )
154
+
155
+
156
+ def get_ad_config(
157
+ domain: Optional[str] = None,
158
+ dc_ip: Optional[str] = None,
159
+ username: Optional[str] = None,
160
+ password: Optional[str] = None,
161
+ ntlm_hash: Optional[str] = None,
162
+ **kwargs
163
+ ) -> ADConfig:
164
+ """
165
+ Create ADConfig from parameters and environment.
166
+
167
+ Args:
168
+ domain: AD domain name (e.g., "corp.local")
169
+ dc_ip: Domain Controller IP address
170
+ username: AD username
171
+ password: AD password
172
+ ntlm_hash: NTLM hash for pass-the-hash
173
+ **kwargs: Additional configuration options
174
+
175
+ Returns:
176
+ ADConfig instance
177
+ """
178
+ credentials = ADCredentials(
179
+ username=username or os.getenv("AD_USERNAME", ""),
180
+ password=password or os.getenv("AD_PASSWORD", ""),
181
+ domain=domain or os.getenv("AD_DOMAIN", ""),
182
+ ntlm_hash=ntlm_hash or os.getenv("AD_NTLM_HASH", "")
183
+ )
184
+
185
+ return ADConfig(
186
+ domain=domain or os.getenv("AD_DOMAIN", ""),
187
+ dc_ip=dc_ip or os.getenv("AD_DC_IP", ""),
188
+ credentials=credentials,
189
+ output_dir=kwargs.get("output_dir", "./ad_results"),
190
+ use_ssl=kwargs.get("use_ssl", False),
191
+ timeout=kwargs.get("timeout", 30),
192
+ run_kerberoast=kwargs.get("run_kerberoast", False),
193
+ run_asreproast=kwargs.get("run_asreproast", False),
194
+ run_bloodhound=kwargs.get("run_bloodhound", False)
195
+ )
196
+
197
+
198
+ def validate_ad_config(config: ADConfig) -> dict:
199
+ """
200
+ Validate AD configuration.
201
+
202
+ Args:
203
+ config: ADConfig to validate
204
+
205
+ Returns:
206
+ Dict with validation results
207
+ """
208
+ results = {
209
+ "valid": False,
210
+ "errors": [],
211
+ "warnings": []
212
+ }
213
+
214
+ # Check required fields
215
+ if not config.domain:
216
+ results["errors"].append("Domain not specified")
217
+
218
+ if not config.dc_ip and not config.dc_hostname:
219
+ results["errors"].append("Domain Controller not specified")
220
+
221
+ if not config.credentials.has_credentials():
222
+ results["errors"].append("No valid credentials provided")
223
+
224
+ # Check credential format
225
+ if config.credentials.ntlm_hash:
226
+ hash_parts = config.credentials.ntlm_hash.split(":")
227
+ if len(hash_parts) == 2:
228
+ if len(hash_parts[0]) != 32 or len(hash_parts[1]) != 32:
229
+ results["warnings"].append("NTLM hash format may be incorrect")
230
+ elif len(hash_parts) == 1:
231
+ if len(hash_parts[0]) != 32:
232
+ results["warnings"].append("NT hash length should be 32 characters")
233
+
234
+ # All good
235
+ if not results["errors"]:
236
+ results["valid"] = True
237
+
238
+ return results