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,222 @@
1
+ """
2
+ AIPT Container Manager - Manages multiple sandbox configurations
3
+
4
+ Provides pre-configured sandboxes for different use cases:
5
+ - Recon tools (nmap, masscan)
6
+ - Web tools (nuclei, httpx)
7
+ - Exploitation (metasploit)
8
+ - Post-exploitation (linpeas)
9
+ """
10
+ from __future__ import annotations
11
+
12
+ from typing import Optional, Dict, List
13
+ from dataclasses import dataclass, field
14
+ from enum import Enum
15
+
16
+ from .sandbox import DockerSandbox, SandboxConfig, SandboxResult
17
+
18
+
19
+ class SecurityImage(str, Enum):
20
+ """Pre-defined security tool images"""
21
+ KALI = "kalilinux/kali-rolling"
22
+ NMAP = "instrumentisto/nmap"
23
+ NUCLEI = "projectdiscovery/nuclei"
24
+ HTTPX = "projectdiscovery/httpx"
25
+ SUBFINDER = "projectdiscovery/subfinder"
26
+ MASSCAN = "adarnimrod/masscan"
27
+ METASPLOIT = "metasploitframework/metasploit-framework"
28
+ SQLMAP = "paoloo/sqlmap"
29
+ NIKTO = "sullo/nikto"
30
+
31
+
32
+ @dataclass
33
+ class PhaseConfig:
34
+ """Configuration for a pentest phase"""
35
+ memory_limit: str = "1g"
36
+ cpu_limit: float = 2.0
37
+ timeout: int = 600
38
+ network_mode: str = "bridge"
39
+ capabilities: List[str] = field(default_factory=list)
40
+
41
+
42
+ class ContainerManager:
43
+ """
44
+ Manages multiple sandbox configurations for different use cases.
45
+
46
+ Provides pre-configured sandboxes for:
47
+ - Recon tools (nmap, masscan)
48
+ - Web tools (nuclei, httpx)
49
+ - Exploitation (metasploit)
50
+ - Post-exploitation (linpeas)
51
+ """
52
+
53
+ # Tool to image mapping
54
+ TOOL_IMAGES: Dict[str, SecurityImage] = {
55
+ "nmap": SecurityImage.NMAP,
56
+ "masscan": SecurityImage.MASSCAN,
57
+ "nuclei": SecurityImage.NUCLEI,
58
+ "httpx": SecurityImage.HTTPX,
59
+ "subfinder": SecurityImage.SUBFINDER,
60
+ "metasploit": SecurityImage.METASPLOIT,
61
+ "msfconsole": SecurityImage.METASPLOIT,
62
+ "sqlmap": SecurityImage.SQLMAP,
63
+ "nikto": SecurityImage.NIKTO,
64
+ }
65
+
66
+ # Phase configurations
67
+ PHASE_CONFIGS: Dict[str, PhaseConfig] = {
68
+ "recon": PhaseConfig(
69
+ memory_limit="1g",
70
+ cpu_limit=2.0,
71
+ timeout=600,
72
+ network_mode="bridge",
73
+ capabilities=["NET_RAW"],
74
+ ),
75
+ "enum": PhaseConfig(
76
+ memory_limit="2g",
77
+ cpu_limit=2.0,
78
+ timeout=900,
79
+ network_mode="bridge",
80
+ ),
81
+ "exploit": PhaseConfig(
82
+ memory_limit="4g",
83
+ cpu_limit=4.0,
84
+ timeout=1800,
85
+ network_mode="host", # May need host network for reverse shells
86
+ ),
87
+ "post": PhaseConfig(
88
+ memory_limit="2g",
89
+ cpu_limit=2.0,
90
+ timeout=600,
91
+ network_mode="none", # Isolated for safety
92
+ ),
93
+ }
94
+
95
+ def __init__(self, default_image: str = SecurityImage.KALI.value):
96
+ self.default_image = default_image
97
+ self.sandboxes: Dict[str, DockerSandbox] = {}
98
+ self._active_containers: List[str] = []
99
+
100
+ def get_sandbox(self, phase: str = "recon") -> DockerSandbox:
101
+ """Get or create sandbox for phase"""
102
+ if phase not in self.sandboxes:
103
+ phase_config = self.PHASE_CONFIGS.get(phase, PhaseConfig())
104
+
105
+ config = SandboxConfig(
106
+ image=self.default_image,
107
+ memory_limit=phase_config.memory_limit,
108
+ cpu_limit=phase_config.cpu_limit,
109
+ timeout=phase_config.timeout,
110
+ network_mode=phase_config.network_mode,
111
+ capabilities=phase_config.capabilities,
112
+ )
113
+
114
+ self.sandboxes[phase] = DockerSandbox(config)
115
+
116
+ return self.sandboxes[phase]
117
+
118
+ def get_image_for_tool(self, tool_name: str) -> str:
119
+ """Get appropriate Docker image for tool"""
120
+ tool_lower = tool_name.lower()
121
+
122
+ # Check direct mapping
123
+ if tool_lower in self.TOOL_IMAGES:
124
+ return self.TOOL_IMAGES[tool_lower].value
125
+
126
+ # Check partial match
127
+ for key, image in self.TOOL_IMAGES.items():
128
+ if key in tool_lower:
129
+ return image.value
130
+
131
+ # Default to Kali for unknown tools
132
+ return self.default_image
133
+
134
+ def execute_tool(
135
+ self,
136
+ tool_name: str,
137
+ command: str,
138
+ phase: str = "recon",
139
+ **kwargs,
140
+ ) -> SandboxResult:
141
+ """
142
+ Execute a security tool in appropriate sandbox.
143
+
144
+ Args:
145
+ tool_name: Name of the tool
146
+ command: Full command to execute
147
+ phase: Pentest phase (recon, enum, exploit, post)
148
+ **kwargs: Additional sandbox options
149
+
150
+ Returns:
151
+ SandboxResult
152
+ """
153
+ sandbox = self.get_sandbox(phase)
154
+ image = self.get_image_for_tool(tool_name)
155
+ return sandbox.execute(command, image=image, **kwargs)
156
+
157
+ def execute_with_callback(
158
+ self,
159
+ tool_name: str,
160
+ command: str,
161
+ callback,
162
+ phase: str = "recon",
163
+ ) -> SandboxResult:
164
+ """Execute tool with streaming output callback"""
165
+ sandbox = self.get_sandbox(phase)
166
+ image = self.get_image_for_tool(tool_name)
167
+ return sandbox.execute_streaming(command, callback, image=image)
168
+
169
+ def is_available(self) -> bool:
170
+ """Check if Docker is available"""
171
+ sandbox = self.get_sandbox("recon")
172
+ return sandbox.is_available()
173
+
174
+ def pull_security_images(self, images: Optional[List[SecurityImage]] = None) -> Dict[str, bool]:
175
+ """
176
+ Pull security tool images.
177
+
178
+ Args:
179
+ images: List of images to pull (pulls all if None)
180
+
181
+ Returns:
182
+ Dict mapping image name to success status
183
+ """
184
+ images_to_pull = images or list(SecurityImage)
185
+ results = {}
186
+
187
+ sandbox = DockerSandbox()
188
+
189
+ for image in images_to_pull:
190
+ image_name = image.value if isinstance(image, SecurityImage) else image
191
+ results[image_name] = sandbox.pull_image(image_name)
192
+
193
+ return results
194
+
195
+ def list_pulled_images(self) -> List[str]:
196
+ """List pulled security images"""
197
+ sandbox = DockerSandbox()
198
+ pulled = []
199
+
200
+ for image in SecurityImage:
201
+ if sandbox.image_exists(image.value):
202
+ pulled.append(image.value)
203
+
204
+ return pulled
205
+
206
+ def cleanup(self) -> None:
207
+ """Cleanup all sandboxes and containers"""
208
+ for sandbox in self.sandboxes.values():
209
+ sandbox.cleanup_containers()
210
+ self.sandboxes.clear()
211
+
212
+
213
+ # Singleton instance
214
+ _container_manager: Optional[ContainerManager] = None
215
+
216
+
217
+ def get_container_manager() -> ContainerManager:
218
+ """Get singleton container manager"""
219
+ global _container_manager
220
+ if _container_manager is None:
221
+ _container_manager = ContainerManager()
222
+ return _container_manager
@@ -0,0 +1,371 @@
1
+ """
2
+ AIPT Docker Sandbox - Secure command execution in containers
3
+
4
+ Provides isolated execution environment for security tools:
5
+ - Network-isolated containers
6
+ - Resource limits (CPU, memory)
7
+ - Timeout enforcement
8
+ - Output capture and streaming
9
+ """
10
+ from __future__ import annotations
11
+
12
+ import subprocess
13
+ import json
14
+ import os
15
+ import time
16
+ import asyncio
17
+ from dataclasses import dataclass, field
18
+ from typing import Optional, List, Dict, Any, Callable
19
+ from pathlib import Path
20
+
21
+
22
+ @dataclass
23
+ class SandboxResult:
24
+ """Result from sandbox execution"""
25
+ output: str
26
+ return_code: int
27
+ duration: float
28
+ container_id: Optional[str] = None
29
+ error: Optional[str] = None
30
+ truncated: bool = False
31
+
32
+
33
+ @dataclass
34
+ class SandboxConfig:
35
+ """Docker sandbox configuration"""
36
+ image: str = "kalilinux/kali-rolling"
37
+ memory_limit: str = "512m"
38
+ cpu_limit: float = 1.0
39
+ network_mode: str = "bridge" # bridge, host, none
40
+ timeout: int = 300
41
+ working_dir: str = "/workspace"
42
+ environment: Dict[str, str] = field(default_factory=dict)
43
+ volumes: Dict[str, str] = field(default_factory=dict)
44
+ capabilities: List[str] = field(default_factory=list) # NET_RAW, etc.
45
+ privileged: bool = False
46
+ remove_after: bool = True
47
+
48
+
49
+ class DockerSandbox:
50
+ """
51
+ Docker-based sandbox for secure command execution.
52
+
53
+ Provides isolated execution environment with:
54
+ - Resource limits (memory, CPU)
55
+ - Network isolation options
56
+ - Timeout enforcement
57
+ - Output streaming
58
+ """
59
+
60
+ def __init__(
61
+ self,
62
+ config: Optional[SandboxConfig] = None,
63
+ auto_pull: bool = True,
64
+ ):
65
+ self.config = config or SandboxConfig()
66
+ self.auto_pull = auto_pull
67
+ self._docker_available: Optional[bool] = None
68
+
69
+ def is_available(self) -> bool:
70
+ """Check if Docker is available"""
71
+ if self._docker_available is not None:
72
+ return self._docker_available
73
+
74
+ try:
75
+ result = subprocess.run(
76
+ ["docker", "info"],
77
+ capture_output=True,
78
+ timeout=10,
79
+ )
80
+ self._docker_available = result.returncode == 0
81
+ except (FileNotFoundError, subprocess.TimeoutExpired, PermissionError, OSError):
82
+ self._docker_available = False
83
+
84
+ return self._docker_available
85
+
86
+ def image_exists(self, image: str) -> bool:
87
+ """Check if Docker image exists locally"""
88
+ try:
89
+ result = subprocess.run(
90
+ ["docker", "images", "-q", image],
91
+ capture_output=True,
92
+ text=True,
93
+ timeout=10,
94
+ )
95
+ return bool(result.stdout.strip())
96
+ except Exception:
97
+ return False
98
+
99
+ def pull_image(self, image: Optional[str] = None) -> bool:
100
+ """Pull Docker image"""
101
+ image = image or self.config.image
102
+ try:
103
+ result = subprocess.run(
104
+ ["docker", "pull", image],
105
+ capture_output=True,
106
+ text=True,
107
+ timeout=600,
108
+ )
109
+ return result.returncode == 0
110
+ except Exception:
111
+ return False
112
+
113
+ def execute(
114
+ self,
115
+ command: str,
116
+ timeout: Optional[int] = None,
117
+ image: Optional[str] = None,
118
+ network: Optional[str] = None,
119
+ env: Optional[Dict[str, str]] = None,
120
+ volumes: Optional[Dict[str, str]] = None,
121
+ ) -> SandboxResult:
122
+ """
123
+ Execute command in Docker container.
124
+
125
+ Args:
126
+ command: Command to execute
127
+ timeout: Execution timeout in seconds
128
+ image: Docker image (overrides config)
129
+ network: Network mode (overrides config)
130
+ env: Additional environment variables
131
+ volumes: Additional volume mounts
132
+
133
+ Returns:
134
+ SandboxResult with output and status
135
+ """
136
+ start_time = time.time()
137
+
138
+ if not self.is_available():
139
+ return SandboxResult(
140
+ output="",
141
+ return_code=-1,
142
+ duration=0,
143
+ error="Docker is not available",
144
+ )
145
+
146
+ image = image or self.config.image
147
+
148
+ if self.auto_pull and not self.image_exists(image):
149
+ if not self.pull_image(image):
150
+ return SandboxResult(
151
+ output="",
152
+ return_code=-1,
153
+ duration=0,
154
+ error=f"Failed to pull image: {image}",
155
+ )
156
+
157
+ docker_cmd = self._build_docker_command(
158
+ command=command,
159
+ image=image,
160
+ network=network,
161
+ env=env,
162
+ volumes=volumes,
163
+ )
164
+
165
+ timeout = timeout or self.config.timeout
166
+
167
+ try:
168
+ result = subprocess.run(
169
+ docker_cmd,
170
+ capture_output=True,
171
+ text=True,
172
+ timeout=timeout,
173
+ )
174
+
175
+ duration = time.time() - start_time
176
+ output = result.stdout
177
+
178
+ if result.stderr:
179
+ output = f"{output}\n[STDERR]\n{result.stderr}"
180
+
181
+ truncated = False
182
+ if len(output) > 100000:
183
+ output = output[:100000] + "\n... [OUTPUT TRUNCATED]"
184
+ truncated = True
185
+
186
+ return SandboxResult(
187
+ output=output,
188
+ return_code=result.returncode,
189
+ duration=duration,
190
+ truncated=truncated,
191
+ )
192
+
193
+ except subprocess.TimeoutExpired:
194
+ return SandboxResult(
195
+ output="",
196
+ return_code=-1,
197
+ duration=timeout,
198
+ error=f"Command timed out after {timeout}s",
199
+ )
200
+ except Exception as e:
201
+ return SandboxResult(
202
+ output="",
203
+ return_code=-1,
204
+ duration=time.time() - start_time,
205
+ error=str(e),
206
+ )
207
+
208
+ async def execute_async(
209
+ self,
210
+ command: str,
211
+ timeout: Optional[int] = None,
212
+ image: Optional[str] = None,
213
+ **kwargs
214
+ ) -> SandboxResult:
215
+ """Async version of execute"""
216
+ loop = asyncio.get_event_loop()
217
+ return await loop.run_in_executor(
218
+ None,
219
+ lambda: self.execute(command, timeout, image, **kwargs)
220
+ )
221
+
222
+ def execute_streaming(
223
+ self,
224
+ command: str,
225
+ callback: Callable[[str], None],
226
+ timeout: Optional[int] = None,
227
+ image: Optional[str] = None,
228
+ ) -> SandboxResult:
229
+ """
230
+ Execute command with streaming output.
231
+
232
+ Args:
233
+ command: Command to execute
234
+ callback: Function to call with each output line
235
+ timeout: Execution timeout
236
+ image: Docker image
237
+
238
+ Returns:
239
+ SandboxResult
240
+ """
241
+ start_time = time.time()
242
+ image = image or self.config.image
243
+ timeout = timeout or self.config.timeout
244
+
245
+ if not self.is_available():
246
+ return SandboxResult(
247
+ output="",
248
+ return_code=-1,
249
+ duration=0,
250
+ error="Docker is not available",
251
+ )
252
+
253
+ docker_cmd = self._build_docker_command(command, image)
254
+
255
+ try:
256
+ process = subprocess.Popen(
257
+ docker_cmd,
258
+ stdout=subprocess.PIPE,
259
+ stderr=subprocess.STDOUT,
260
+ text=True,
261
+ )
262
+
263
+ output_lines = []
264
+
265
+ while True:
266
+ if time.time() - start_time > timeout:
267
+ process.kill()
268
+ return SandboxResult(
269
+ output="\n".join(output_lines),
270
+ return_code=-1,
271
+ duration=timeout,
272
+ error=f"Command timed out after {timeout}s",
273
+ )
274
+
275
+ line = process.stdout.readline()
276
+ if not line and process.poll() is not None:
277
+ break
278
+
279
+ if line:
280
+ line = line.rstrip()
281
+ output_lines.append(line)
282
+ callback(line)
283
+
284
+ return SandboxResult(
285
+ output="\n".join(output_lines),
286
+ return_code=process.returncode,
287
+ duration=time.time() - start_time,
288
+ )
289
+
290
+ except Exception as e:
291
+ return SandboxResult(
292
+ output="",
293
+ return_code=-1,
294
+ duration=time.time() - start_time,
295
+ error=str(e),
296
+ )
297
+
298
+ def _build_docker_command(
299
+ self,
300
+ command: str,
301
+ image: str,
302
+ network: Optional[str] = None,
303
+ env: Optional[Dict[str, str]] = None,
304
+ volumes: Optional[Dict[str, str]] = None,
305
+ ) -> List[str]:
306
+ """Build docker run command"""
307
+ docker_cmd = [
308
+ "docker", "run",
309
+ "--memory", self.config.memory_limit,
310
+ "--cpus", str(self.config.cpu_limit),
311
+ "--network", network or self.config.network_mode,
312
+ "-w", self.config.working_dir,
313
+ ]
314
+
315
+ if self.config.remove_after:
316
+ docker_cmd.append("--rm")
317
+
318
+ if self.config.privileged:
319
+ docker_cmd.append("--privileged")
320
+
321
+ for cap in self.config.capabilities:
322
+ docker_cmd.extend(["--cap-add", cap])
323
+
324
+ all_env = {**self.config.environment, **(env or {})}
325
+ for key, value in all_env.items():
326
+ docker_cmd.extend(["-e", f"{key}={value}"])
327
+
328
+ all_volumes = {**self.config.volumes, **(volumes or {})}
329
+ for host_path, container_path in all_volumes.items():
330
+ docker_cmd.extend(["-v", f"{host_path}:{container_path}"])
331
+
332
+ docker_cmd.extend([image, "sh", "-c", command])
333
+
334
+ return docker_cmd
335
+
336
+ def list_containers(self, all_containers: bool = False) -> List[Dict[str, str]]:
337
+ """List running containers"""
338
+ cmd = ["docker", "ps", "--format", "{{json .}}"]
339
+ if all_containers:
340
+ cmd.append("-a")
341
+
342
+ try:
343
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=10)
344
+ containers = []
345
+ for line in result.stdout.strip().split("\n"):
346
+ if line:
347
+ containers.append(json.loads(line))
348
+ return containers
349
+ except Exception:
350
+ return []
351
+
352
+ def stop_container(self, container_id: str, force: bool = False) -> bool:
353
+ """Stop a running container"""
354
+ cmd = ["docker", "kill" if force else "stop", container_id]
355
+ try:
356
+ result = subprocess.run(cmd, capture_output=True, timeout=30)
357
+ return result.returncode == 0
358
+ except Exception:
359
+ return False
360
+
361
+ def cleanup_containers(self, image_filter: Optional[str] = None) -> int:
362
+ """Remove stopped containers"""
363
+ cmd = ["docker", "container", "prune", "-f"]
364
+ if image_filter:
365
+ cmd.extend(["--filter", f"ancestor={image_filter}"])
366
+
367
+ try:
368
+ result = subprocess.run(cmd, capture_output=True, text=True, timeout=30)
369
+ return result.returncode
370
+ except Exception:
371
+ return -1
@@ -0,0 +1,58 @@
1
+ """
2
+ AIPT Evasion Module - WAF Bypass and Request Obfuscation
3
+
4
+ Provides evasion techniques for authorized penetration testing:
5
+ - WAF bypass payload generation
6
+ - Request obfuscation and encoding
7
+ - User-Agent rotation
8
+ - TLS fingerprint randomization
9
+
10
+ WARNING: Use only for authorized security testing!
11
+
12
+ Usage:
13
+ from aipt_v2.evasion import WAFBypass, RequestObfuscator, UARotator
14
+
15
+ bypass = WAFBypass()
16
+ payloads = bypass.generate_sqli_bypasses("' OR '1'='1")
17
+ """
18
+
19
+ from aipt_v2.evasion.waf_bypass import (
20
+ WAFBypass,
21
+ BypassPayload,
22
+ generate_bypass_payloads,
23
+ )
24
+
25
+ from aipt_v2.evasion.request_obfuscator import (
26
+ RequestObfuscator,
27
+ ObfuscationConfig,
28
+ obfuscate_request,
29
+ )
30
+
31
+ from aipt_v2.evasion.ua_rotator import (
32
+ UARotator,
33
+ UserAgent,
34
+ get_random_ua,
35
+ )
36
+
37
+ from aipt_v2.evasion.tls_fingerprint import (
38
+ TLSFingerprint,
39
+ randomize_tls,
40
+ )
41
+
42
+ __all__ = [
43
+ # WAF Bypass
44
+ "WAFBypass",
45
+ "BypassPayload",
46
+ "generate_bypass_payloads",
47
+ # Obfuscation
48
+ "RequestObfuscator",
49
+ "ObfuscationConfig",
50
+ "obfuscate_request",
51
+ # User-Agent
52
+ "UARotator",
53
+ "UserAgent",
54
+ "get_random_ua",
55
+ # TLS
56
+ "TLSFingerprint",
57
+ "randomize_tls",
58
+ ]