aiptx 2.0.2__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.

Potentially problematic release.


This version of aiptx might be problematic. Click here for more details.

Files changed (165) 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 +24 -0
  6. aipt_v2/agents/base.py +520 -0
  7. aipt_v2/agents/ptt.py +406 -0
  8. aipt_v2/agents/state.py +168 -0
  9. aipt_v2/app.py +960 -0
  10. aipt_v2/browser/__init__.py +31 -0
  11. aipt_v2/browser/automation.py +458 -0
  12. aipt_v2/browser/crawler.py +453 -0
  13. aipt_v2/cli.py +321 -0
  14. aipt_v2/compliance/__init__.py +71 -0
  15. aipt_v2/compliance/compliance_report.py +449 -0
  16. aipt_v2/compliance/framework_mapper.py +424 -0
  17. aipt_v2/compliance/nist_mapping.py +345 -0
  18. aipt_v2/compliance/owasp_mapping.py +330 -0
  19. aipt_v2/compliance/pci_mapping.py +297 -0
  20. aipt_v2/config.py +288 -0
  21. aipt_v2/core/__init__.py +43 -0
  22. aipt_v2/core/agent.py +630 -0
  23. aipt_v2/core/llm.py +395 -0
  24. aipt_v2/core/memory.py +305 -0
  25. aipt_v2/core/ptt.py +329 -0
  26. aipt_v2/database/__init__.py +14 -0
  27. aipt_v2/database/models.py +232 -0
  28. aipt_v2/database/repository.py +384 -0
  29. aipt_v2/docker/__init__.py +23 -0
  30. aipt_v2/docker/builder.py +260 -0
  31. aipt_v2/docker/manager.py +222 -0
  32. aipt_v2/docker/sandbox.py +371 -0
  33. aipt_v2/evasion/__init__.py +58 -0
  34. aipt_v2/evasion/request_obfuscator.py +272 -0
  35. aipt_v2/evasion/tls_fingerprint.py +285 -0
  36. aipt_v2/evasion/ua_rotator.py +301 -0
  37. aipt_v2/evasion/waf_bypass.py +439 -0
  38. aipt_v2/execution/__init__.py +23 -0
  39. aipt_v2/execution/executor.py +302 -0
  40. aipt_v2/execution/parser.py +544 -0
  41. aipt_v2/execution/terminal.py +337 -0
  42. aipt_v2/health.py +437 -0
  43. aipt_v2/intelligence/__init__.py +85 -0
  44. aipt_v2/intelligence/auth.py +520 -0
  45. aipt_v2/intelligence/chaining.py +775 -0
  46. aipt_v2/intelligence/cve_aipt.py +334 -0
  47. aipt_v2/intelligence/cve_info.py +1111 -0
  48. aipt_v2/intelligence/rag.py +239 -0
  49. aipt_v2/intelligence/scope.py +442 -0
  50. aipt_v2/intelligence/searchers/__init__.py +5 -0
  51. aipt_v2/intelligence/searchers/exploitdb_searcher.py +523 -0
  52. aipt_v2/intelligence/searchers/github_searcher.py +467 -0
  53. aipt_v2/intelligence/searchers/google_searcher.py +281 -0
  54. aipt_v2/intelligence/tools.json +443 -0
  55. aipt_v2/intelligence/triage.py +670 -0
  56. aipt_v2/interface/__init__.py +5 -0
  57. aipt_v2/interface/cli.py +230 -0
  58. aipt_v2/interface/main.py +501 -0
  59. aipt_v2/interface/tui.py +1276 -0
  60. aipt_v2/interface/utils.py +583 -0
  61. aipt_v2/llm/__init__.py +39 -0
  62. aipt_v2/llm/config.py +26 -0
  63. aipt_v2/llm/llm.py +514 -0
  64. aipt_v2/llm/memory.py +214 -0
  65. aipt_v2/llm/request_queue.py +89 -0
  66. aipt_v2/llm/utils.py +89 -0
  67. aipt_v2/models/__init__.py +15 -0
  68. aipt_v2/models/findings.py +295 -0
  69. aipt_v2/models/phase_result.py +224 -0
  70. aipt_v2/models/scan_config.py +207 -0
  71. aipt_v2/monitoring/grafana/dashboards/aipt-dashboard.json +355 -0
  72. aipt_v2/monitoring/grafana/dashboards/default.yml +17 -0
  73. aipt_v2/monitoring/grafana/datasources/prometheus.yml +17 -0
  74. aipt_v2/monitoring/prometheus.yml +60 -0
  75. aipt_v2/orchestration/__init__.py +52 -0
  76. aipt_v2/orchestration/pipeline.py +398 -0
  77. aipt_v2/orchestration/progress.py +300 -0
  78. aipt_v2/orchestration/scheduler.py +296 -0
  79. aipt_v2/orchestrator.py +2284 -0
  80. aipt_v2/payloads/__init__.py +27 -0
  81. aipt_v2/payloads/cmdi.py +150 -0
  82. aipt_v2/payloads/sqli.py +263 -0
  83. aipt_v2/payloads/ssrf.py +204 -0
  84. aipt_v2/payloads/templates.py +222 -0
  85. aipt_v2/payloads/traversal.py +166 -0
  86. aipt_v2/payloads/xss.py +204 -0
  87. aipt_v2/prompts/__init__.py +60 -0
  88. aipt_v2/proxy/__init__.py +29 -0
  89. aipt_v2/proxy/history.py +352 -0
  90. aipt_v2/proxy/interceptor.py +452 -0
  91. aipt_v2/recon/__init__.py +44 -0
  92. aipt_v2/recon/dns.py +241 -0
  93. aipt_v2/recon/osint.py +367 -0
  94. aipt_v2/recon/subdomain.py +372 -0
  95. aipt_v2/recon/tech_detect.py +311 -0
  96. aipt_v2/reports/__init__.py +17 -0
  97. aipt_v2/reports/generator.py +313 -0
  98. aipt_v2/reports/html_report.py +378 -0
  99. aipt_v2/runtime/__init__.py +44 -0
  100. aipt_v2/runtime/base.py +30 -0
  101. aipt_v2/runtime/docker.py +401 -0
  102. aipt_v2/runtime/local.py +346 -0
  103. aipt_v2/runtime/tool_server.py +205 -0
  104. aipt_v2/scanners/__init__.py +28 -0
  105. aipt_v2/scanners/base.py +273 -0
  106. aipt_v2/scanners/nikto.py +244 -0
  107. aipt_v2/scanners/nmap.py +402 -0
  108. aipt_v2/scanners/nuclei.py +273 -0
  109. aipt_v2/scanners/web.py +454 -0
  110. aipt_v2/scripts/security_audit.py +366 -0
  111. aipt_v2/telemetry/__init__.py +7 -0
  112. aipt_v2/telemetry/tracer.py +347 -0
  113. aipt_v2/terminal/__init__.py +28 -0
  114. aipt_v2/terminal/executor.py +400 -0
  115. aipt_v2/terminal/sandbox.py +350 -0
  116. aipt_v2/tools/__init__.py +44 -0
  117. aipt_v2/tools/active_directory/__init__.py +78 -0
  118. aipt_v2/tools/active_directory/ad_config.py +238 -0
  119. aipt_v2/tools/active_directory/bloodhound_wrapper.py +447 -0
  120. aipt_v2/tools/active_directory/kerberos_attacks.py +430 -0
  121. aipt_v2/tools/active_directory/ldap_enum.py +533 -0
  122. aipt_v2/tools/active_directory/smb_attacks.py +505 -0
  123. aipt_v2/tools/agents_graph/__init__.py +19 -0
  124. aipt_v2/tools/agents_graph/agents_graph_actions.py +69 -0
  125. aipt_v2/tools/api_security/__init__.py +76 -0
  126. aipt_v2/tools/api_security/api_discovery.py +608 -0
  127. aipt_v2/tools/api_security/graphql_scanner.py +622 -0
  128. aipt_v2/tools/api_security/jwt_analyzer.py +577 -0
  129. aipt_v2/tools/api_security/openapi_fuzzer.py +761 -0
  130. aipt_v2/tools/browser/__init__.py +5 -0
  131. aipt_v2/tools/browser/browser_actions.py +238 -0
  132. aipt_v2/tools/browser/browser_instance.py +535 -0
  133. aipt_v2/tools/browser/tab_manager.py +344 -0
  134. aipt_v2/tools/cloud/__init__.py +70 -0
  135. aipt_v2/tools/cloud/cloud_config.py +273 -0
  136. aipt_v2/tools/cloud/cloud_scanner.py +639 -0
  137. aipt_v2/tools/cloud/prowler_tool.py +571 -0
  138. aipt_v2/tools/cloud/scoutsuite_tool.py +359 -0
  139. aipt_v2/tools/executor.py +307 -0
  140. aipt_v2/tools/parser.py +408 -0
  141. aipt_v2/tools/proxy/__init__.py +5 -0
  142. aipt_v2/tools/proxy/proxy_actions.py +103 -0
  143. aipt_v2/tools/proxy/proxy_manager.py +789 -0
  144. aipt_v2/tools/registry.py +196 -0
  145. aipt_v2/tools/scanners/__init__.py +343 -0
  146. aipt_v2/tools/scanners/acunetix_tool.py +712 -0
  147. aipt_v2/tools/scanners/burp_tool.py +631 -0
  148. aipt_v2/tools/scanners/config.py +156 -0
  149. aipt_v2/tools/scanners/nessus_tool.py +588 -0
  150. aipt_v2/tools/scanners/zap_tool.py +612 -0
  151. aipt_v2/tools/terminal/__init__.py +5 -0
  152. aipt_v2/tools/terminal/terminal_actions.py +37 -0
  153. aipt_v2/tools/terminal/terminal_manager.py +153 -0
  154. aipt_v2/tools/terminal/terminal_session.py +449 -0
  155. aipt_v2/tools/tool_processing.py +108 -0
  156. aipt_v2/utils/__init__.py +17 -0
  157. aipt_v2/utils/logging.py +201 -0
  158. aipt_v2/utils/model_manager.py +187 -0
  159. aipt_v2/utils/searchers/__init__.py +269 -0
  160. aiptx-2.0.2.dist-info/METADATA +324 -0
  161. aiptx-2.0.2.dist-info/RECORD +165 -0
  162. aiptx-2.0.2.dist-info/WHEEL +5 -0
  163. aiptx-2.0.2.dist-info/entry_points.txt +7 -0
  164. aiptx-2.0.2.dist-info/licenses/LICENSE +21 -0
  165. aiptx-2.0.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,297 @@
1
+ """
2
+ PCI-DSS 4.0 Mapping
3
+
4
+ Payment Card Industry Data Security Standard mapping.
5
+ Maps CWEs to PCI-DSS 4.0 requirements.
6
+
7
+ Usage:
8
+ from aipt_v2.compliance import PCIMapper, get_pci_requirement
9
+
10
+ req = get_pci_requirement("CWE-89") # Returns "6.2"
11
+ """
12
+
13
+ from dataclasses import dataclass, field
14
+ from typing import List, Dict, Optional
15
+
16
+
17
+ @dataclass
18
+ class PCIRequirement:
19
+ """PCI-DSS requirement definition."""
20
+ id: str
21
+ name: str
22
+ description: str
23
+ sub_requirements: List[str]
24
+ cwes: List[str]
25
+ testing_procedures: List[str]
26
+
27
+
28
+ # PCI-DSS 4.0 Requirements (security-relevant subset)
29
+ PCI_DSS_REQUIREMENTS = {
30
+ "2.2": PCIRequirement(
31
+ id="2.2",
32
+ name="System Components are Configured and Managed Securely",
33
+ description="Configuration standards are developed, implemented, and maintained "
34
+ "for system components that are consistent with industry-accepted "
35
+ "system hardening standards.",
36
+ sub_requirements=[
37
+ "2.2.1 - Configuration standards are implemented",
38
+ "2.2.2 - Vendor default accounts are managed",
39
+ "2.2.3 - Primary functions are separated on different servers",
40
+ "2.2.4 - Only necessary services and protocols are enabled",
41
+ "2.2.5 - Insecure services and protocols are addressed",
42
+ "2.2.6 - System security parameters are configured",
43
+ "2.2.7 - Non-console administrative access is encrypted"
44
+ ],
45
+ cwes=["CWE-16", "CWE-260", "CWE-611", "CWE-756", "CWE-942"],
46
+ testing_procedures=[
47
+ "Examine configuration standards",
48
+ "Examine system configurations",
49
+ "Interview system administrators"
50
+ ]
51
+ ),
52
+
53
+ "3.4": PCIRequirement(
54
+ id="3.4",
55
+ name="PAN is Rendered Unreadable Anywhere it is Stored",
56
+ description="Primary Account Numbers (PAN) is rendered unreadable anywhere "
57
+ "it is stored using strong cryptography.",
58
+ sub_requirements=[
59
+ "3.4.1 - PAN rendered unreadable via cryptography or truncation",
60
+ "3.4.2 - Technical controls prevent PAN copy/relocation"
61
+ ],
62
+ cwes=["CWE-311", "CWE-312", "CWE-313", "CWE-316"],
63
+ testing_procedures=[
64
+ "Examine data repositories to verify PAN is unreadable",
65
+ "Examine cryptographic key management procedures"
66
+ ]
67
+ ),
68
+
69
+ "3.5": PCIRequirement(
70
+ id="3.5",
71
+ name="Cryptographic Keys are Protected",
72
+ description="Cryptographic keys used to protect stored account data "
73
+ "are secured.",
74
+ sub_requirements=[
75
+ "3.5.1 - Key access restricted to fewest custodians",
76
+ "3.5.1.1 - Service providers: key per customer",
77
+ "3.5.1.2 - Key storage in secure cryptographic device",
78
+ "3.5.1.3 - Key stored in fewest locations"
79
+ ],
80
+ cwes=["CWE-320", "CWE-321", "CWE-326", "CWE-327"],
81
+ testing_procedures=[
82
+ "Examine documented procedures",
83
+ "Interview personnel",
84
+ "Observe key management processes"
85
+ ]
86
+ ),
87
+
88
+ "4.1": PCIRequirement(
89
+ id="4.1",
90
+ name="Strong Cryptography Protects Data During Transmission",
91
+ description="Processes and mechanisms are defined to protect account data "
92
+ "with strong cryptography during transmission over open networks.",
93
+ sub_requirements=[
94
+ "4.1.1 - Security policies and procedures documented",
95
+ "4.1.2 - Roles and responsibilities assigned"
96
+ ],
97
+ cwes=["CWE-319", "CWE-326", "CWE-327", "CWE-523"],
98
+ testing_procedures=[
99
+ "Examine policies and configuration standards",
100
+ "Interview responsible personnel"
101
+ ]
102
+ ),
103
+
104
+ "6.2": PCIRequirement(
105
+ id="6.2",
106
+ name="Bespoke and Custom Software is Developed Securely",
107
+ description="Bespoke and custom software is developed securely, and "
108
+ "software development follows secure software development guidance.",
109
+ sub_requirements=[
110
+ "6.2.1 - Software developed based on industry standards",
111
+ "6.2.2 - Personnel trained in secure development",
112
+ "6.2.3 - Code reviewed for vulnerabilities",
113
+ "6.2.4 - Common software attacks addressed"
114
+ ],
115
+ cwes=["CWE-79", "CWE-89", "CWE-78", "CWE-94", "CWE-502", "CWE-918", "CWE-22",
116
+ "CWE-434", "CWE-352", "CWE-601", "CWE-20"],
117
+ testing_procedures=[
118
+ "Examine secure development procedures",
119
+ "Interview developers",
120
+ "Review code review processes"
121
+ ]
122
+ ),
123
+
124
+ "6.3": PCIRequirement(
125
+ id="6.3",
126
+ name="Security Vulnerabilities are Identified and Addressed",
127
+ description="Security vulnerabilities are identified and addressed.",
128
+ sub_requirements=[
129
+ "6.3.1 - Vulnerabilities identified via reputable sources",
130
+ "6.3.2 - Inventory of bespoke software maintained",
131
+ "6.3.3 - Vulnerabilities addressed via patching"
132
+ ],
133
+ cwes=["CWE-937", "CWE-1035", "CWE-1104"],
134
+ testing_procedures=[
135
+ "Examine processes for identifying vulnerabilities",
136
+ "Interview responsible personnel"
137
+ ]
138
+ ),
139
+
140
+ "7.1": PCIRequirement(
141
+ id="7.1",
142
+ name="Access to System Components is Defined and Assigned",
143
+ description="Processes and mechanisms for restricting access to system "
144
+ "components and cardholder data are defined and understood.",
145
+ sub_requirements=[
146
+ "7.1.1 - Security policies defined and known",
147
+ "7.1.2 - Access control model defined"
148
+ ],
149
+ cwes=["CWE-284", "CWE-285", "CWE-862", "CWE-863", "CWE-639"],
150
+ testing_procedures=[
151
+ "Examine documented policies",
152
+ "Interview personnel"
153
+ ]
154
+ ),
155
+
156
+ "8.3": PCIRequirement(
157
+ id="8.3",
158
+ name="Strong Authentication for Users and Administrators",
159
+ description="Strong authentication for users and administrators is established "
160
+ "and managed.",
161
+ sub_requirements=[
162
+ "8.3.1 - All access authenticated",
163
+ "8.3.2 - Strong cryptography for authentication",
164
+ "8.3.4 - MFA for remote network access",
165
+ "8.3.5 - MFA for all access to CDE",
166
+ "8.3.6 - MFA systems cannot be bypassed",
167
+ "8.3.9 - Passwords have minimum complexity",
168
+ "8.3.10 - Failed login attempts limited"
169
+ ],
170
+ cwes=["CWE-287", "CWE-521", "CWE-798", "CWE-307", "CWE-384", "CWE-306"],
171
+ testing_procedures=[
172
+ "Examine system configuration standards",
173
+ "Observe authentication processes"
174
+ ]
175
+ ),
176
+
177
+ "10.2": PCIRequirement(
178
+ id="10.2",
179
+ name="Audit Logs are Implemented",
180
+ description="Audit logs are implemented to support the detection of "
181
+ "anomalies and suspicious activity.",
182
+ sub_requirements=[
183
+ "10.2.1 - Audit logs enabled and active",
184
+ "10.2.1.1 - User access to CHD logged",
185
+ "10.2.1.2 - Admin actions logged",
186
+ "10.2.1.3 - Access to audit logs logged",
187
+ "10.2.1.4 - Invalid access attempts logged",
188
+ "10.2.1.5 - Changes to auth credentials logged",
189
+ "10.2.1.6 - System/log events logged",
190
+ "10.2.1.7 - Security events logged"
191
+ ],
192
+ cwes=["CWE-778", "CWE-223", "CWE-117", "CWE-532"],
193
+ testing_procedures=[
194
+ "Examine audit log configurations",
195
+ "Interview personnel",
196
+ "Review log samples"
197
+ ]
198
+ ),
199
+
200
+ "11.3": PCIRequirement(
201
+ id="11.3",
202
+ name="External and Internal Vulnerabilities Regularly Identified",
203
+ description="External and internal vulnerabilities are regularly identified, "
204
+ "prioritized, and addressed.",
205
+ sub_requirements=[
206
+ "11.3.1 - Internal vulnerability scans quarterly",
207
+ "11.3.2 - External vulnerability scans quarterly",
208
+ "11.3.3 - Vulnerability scans after significant changes",
209
+ "11.3.4 - Internal penetration testing"
210
+ ],
211
+ cwes=["CWE-937", "CWE-1104"],
212
+ testing_procedures=[
213
+ "Examine scan reports",
214
+ "Interview responsible personnel",
215
+ "Examine remediation processes"
216
+ ]
217
+ )
218
+ }
219
+
220
+
221
+ class PCIMapper:
222
+ """PCI-DSS specific mapper."""
223
+
224
+ def __init__(self):
225
+ self.requirements = PCI_DSS_REQUIREMENTS
226
+
227
+ def get_requirement(self, cwe_id: str) -> Optional[PCIRequirement]:
228
+ """Get PCI requirement for a CWE."""
229
+ cwe_id = cwe_id.upper()
230
+ if not cwe_id.startswith("CWE-"):
231
+ cwe_id = f"CWE-{cwe_id}"
232
+
233
+ for req_id, requirement in self.requirements.items():
234
+ if cwe_id in requirement.cwes:
235
+ return requirement
236
+
237
+ return None
238
+
239
+ def get_requirement_by_id(self, req_id: str) -> Optional[PCIRequirement]:
240
+ """Get PCI requirement by ID."""
241
+ return self.requirements.get(req_id)
242
+
243
+ def get_all_requirements_for_cwe(self, cwe_id: str) -> List[PCIRequirement]:
244
+ """Get all PCI requirements mapped to a CWE."""
245
+ cwe_id = cwe_id.upper()
246
+ if not cwe_id.startswith("CWE-"):
247
+ cwe_id = f"CWE-{cwe_id}"
248
+
249
+ requirements = []
250
+ for requirement in self.requirements.values():
251
+ if cwe_id in requirement.cwes:
252
+ requirements.append(requirement)
253
+
254
+ return requirements
255
+
256
+ def get_compliance_status(self, findings: List[Dict]) -> Dict[str, Dict]:
257
+ """
258
+ Calculate PCI-DSS compliance status based on findings.
259
+
260
+ Args:
261
+ findings: List of findings with CWE IDs
262
+
263
+ Returns:
264
+ Dict with compliance status per requirement
265
+ """
266
+ status = {}
267
+
268
+ for req_id, requirement in self.requirements.items():
269
+ affected_cwes = []
270
+ for finding in findings:
271
+ cwe = finding.get("cwe", finding.get("cwe_id", ""))
272
+ if cwe.upper() in requirement.cwes or f"CWE-{cwe}" in requirement.cwes:
273
+ affected_cwes.append(cwe)
274
+
275
+ status[req_id] = {
276
+ "requirement_name": requirement.name,
277
+ "compliant": len(affected_cwes) == 0,
278
+ "findings_count": len(affected_cwes),
279
+ "affected_cwes": affected_cwes
280
+ }
281
+
282
+ return status
283
+
284
+
285
+ def get_pci_requirement(cwe_id: str) -> Optional[str]:
286
+ """
287
+ Get PCI-DSS requirement ID for a CWE.
288
+
289
+ Args:
290
+ cwe_id: CWE identifier
291
+
292
+ Returns:
293
+ PCI requirement ID or None
294
+ """
295
+ mapper = PCIMapper()
296
+ requirement = mapper.get_requirement(cwe_id)
297
+ return requirement.id if requirement else None
aipt_v2/config.py ADDED
@@ -0,0 +1,288 @@
1
+ """
2
+ AIPT v2 Configuration Management
3
+ ================================
4
+
5
+ Centralized configuration with validation using Pydantic.
6
+ Loads from environment variables with sensible defaults.
7
+ """
8
+
9
+ import os
10
+ from typing import List, Optional
11
+ from functools import lru_cache
12
+ from pathlib import Path
13
+
14
+ from pydantic import BaseModel, Field, field_validator, model_validator
15
+ from pydantic_settings import BaseSettings
16
+
17
+ from .utils.logging import logger
18
+
19
+
20
+ class LLMSettings(BaseModel):
21
+ """LLM provider configuration."""
22
+
23
+ provider: str = Field(default="anthropic", description="LLM provider name")
24
+ model: str = Field(default="claude-sonnet-4-20250514", description="Model identifier")
25
+ api_key: Optional[str] = Field(default=None, description="API key")
26
+ api_base: Optional[str] = Field(default=None, description="Custom API base URL")
27
+ timeout: int = Field(default=120, ge=10, le=600, description="Request timeout in seconds")
28
+ max_tokens: int = Field(default=4096, ge=100, le=128000, description="Max response tokens")
29
+ temperature: float = Field(default=0.7, ge=0.0, le=2.0, description="Sampling temperature")
30
+ enable_caching: bool = Field(default=True, description="Enable prompt caching")
31
+
32
+ @field_validator("api_key", mode="before")
33
+ @classmethod
34
+ def get_api_key_from_env(cls, v):
35
+ if v:
36
+ return v
37
+ # Try common environment variables
38
+ for key in ["ANTHROPIC_API_KEY", "OPENAI_API_KEY", "DEEPSEEK_API_KEY", "LLM_API_KEY"]:
39
+ if os.getenv(key):
40
+ return os.getenv(key)
41
+ return None
42
+
43
+
44
+ class ScannerSettings(BaseModel):
45
+ """Enterprise scanner configuration."""
46
+
47
+ # Acunetix
48
+ acunetix_url: Optional[str] = Field(default=None, description="Acunetix API URL")
49
+ acunetix_api_key: Optional[str] = Field(default=None, description="Acunetix API key")
50
+
51
+ # Burp Suite
52
+ burp_url: Optional[str] = Field(default=None, description="Burp Suite API URL")
53
+ burp_api_key: Optional[str] = Field(default=None, description="Burp Suite API key")
54
+
55
+ # Nessus
56
+ nessus_url: Optional[str] = Field(default=None, description="Nessus API URL")
57
+ nessus_access_key: Optional[str] = Field(default=None, description="Nessus access key")
58
+ nessus_secret_key: Optional[str] = Field(default=None, description="Nessus secret key")
59
+
60
+ # OWASP ZAP
61
+ zap_url: Optional[str] = Field(default=None, description="ZAP API URL")
62
+ zap_api_key: Optional[str] = Field(default=None, description="ZAP API key")
63
+
64
+ @field_validator("acunetix_url", "burp_url", "nessus_url", "zap_url", mode="before")
65
+ @classmethod
66
+ def validate_url(cls, v):
67
+ if v and not v.startswith(("http://", "https://")):
68
+ raise ValueError(f"Invalid URL format: {v}")
69
+ return v
70
+
71
+
72
+ class VPSSettings(BaseModel):
73
+ """VPS execution configuration."""
74
+
75
+ host: Optional[str] = Field(default=None, description="VPS hostname or IP")
76
+ user: str = Field(default="ubuntu", description="SSH username")
77
+ key_path: Optional[str] = Field(default=None, description="Path to SSH private key")
78
+ port: int = Field(default=22, ge=1, le=65535, description="SSH port")
79
+ # Security: Use /var/tmp for longer-lived temp files (survives reboots)
80
+ # The directory should be created with restricted permissions (700) on the VPS
81
+ results_dir: str = Field(
82
+ default="/var/tmp/aipt_results",
83
+ description="Remote results directory (should be created with mode 700)"
84
+ )
85
+ timeout: int = Field(default=300, ge=30, le=3600, description="Command timeout in seconds")
86
+
87
+ @field_validator("key_path", mode="before")
88
+ @classmethod
89
+ def expand_key_path(cls, v):
90
+ if v:
91
+ return str(Path(v).expanduser().resolve())
92
+ return v
93
+
94
+
95
+ class APISettings(BaseModel):
96
+ """REST API configuration."""
97
+
98
+ # Security: Default to localhost to avoid accidental exposure (CWE-605)
99
+ # Use AIPT_API__HOST=0.0.0.0 for production deployments behind a reverse proxy
100
+ host: str = Field(default="127.0.0.1", description="API host (use 0.0.0.0 for network access)")
101
+ port: int = Field(default=8000, ge=1, le=65535, description="API port")
102
+ cors_origins: List[str] = Field(
103
+ default=["http://localhost:3000"],
104
+ description="Allowed CORS origins"
105
+ )
106
+ rate_limit: str = Field(default="100/minute", description="Rate limit per client")
107
+ enable_docs: bool = Field(default=True, description="Enable Swagger/OpenAPI docs")
108
+
109
+
110
+ class DatabaseSettings(BaseModel):
111
+ """Database configuration."""
112
+
113
+ url: str = Field(default="sqlite:///./aipt.db", description="Database connection URL")
114
+ echo: bool = Field(default=False, description="Echo SQL queries")
115
+ pool_size: int = Field(default=5, ge=1, le=100, description="Connection pool size")
116
+
117
+
118
+ class LoggingSettings(BaseModel):
119
+ """Logging configuration."""
120
+
121
+ level: str = Field(default="INFO", description="Log level")
122
+ format: str = Field(default="console", description="Log format (console or json)")
123
+ redact_secrets: bool = Field(default=True, description="Redact sensitive values in logs")
124
+
125
+
126
+ class AIPTConfig(BaseSettings):
127
+ """
128
+ Main AIPT v2 configuration.
129
+
130
+ Loads from environment variables with AIPT_ prefix.
131
+ """
132
+
133
+ # Sub-configurations
134
+ llm: LLMSettings = Field(default_factory=LLMSettings)
135
+ scanners: ScannerSettings = Field(default_factory=ScannerSettings)
136
+ vps: VPSSettings = Field(default_factory=VPSSettings)
137
+ api: APISettings = Field(default_factory=APISettings)
138
+ database: DatabaseSettings = Field(default_factory=DatabaseSettings)
139
+ logging: LoggingSettings = Field(default_factory=LoggingSettings)
140
+
141
+ # General settings
142
+ sandbox_mode: bool = Field(default=False, description="Run tools in sandbox")
143
+ output_dir: Path = Field(default=Path("./results"), description="Output directory")
144
+ reports_dir: Path = Field(default=Path("./reports"), description="Reports directory")
145
+
146
+ model_config = {
147
+ "env_prefix": "AIPT_",
148
+ "env_nested_delimiter": "__",
149
+ "case_sensitive": False,
150
+ }
151
+
152
+ @model_validator(mode="after")
153
+ def create_directories(self):
154
+ """Ensure output directories exist."""
155
+ self.output_dir.mkdir(parents=True, exist_ok=True)
156
+ self.reports_dir.mkdir(parents=True, exist_ok=True)
157
+ return self
158
+
159
+
160
+ @lru_cache(maxsize=1)
161
+ def get_config() -> AIPTConfig:
162
+ """
163
+ Get the global configuration instance.
164
+
165
+ Returns:
166
+ AIPTConfig instance loaded from environment
167
+ """
168
+ # Load from environment
169
+ config = AIPTConfig(
170
+ llm=LLMSettings(
171
+ provider=os.getenv("AIPT_LLM_PROVIDER", "anthropic"),
172
+ model=os.getenv("AIPT_LLM_MODEL", "claude-sonnet-4-20250514"),
173
+ api_key=os.getenv("ANTHROPIC_API_KEY") or os.getenv("OPENAI_API_KEY"),
174
+ timeout=int(os.getenv("AIPT_LLM_TIMEOUT", "120")),
175
+ ),
176
+ scanners=ScannerSettings(
177
+ acunetix_url=os.getenv("ACUNETIX_URL"),
178
+ acunetix_api_key=os.getenv("ACUNETIX_API_KEY"),
179
+ burp_url=os.getenv("BURP_URL"),
180
+ burp_api_key=os.getenv("BURP_API_KEY"),
181
+ nessus_url=os.getenv("NESSUS_URL"),
182
+ nessus_access_key=os.getenv("NESSUS_ACCESS_KEY"),
183
+ nessus_secret_key=os.getenv("NESSUS_SECRET_KEY"),
184
+ zap_url=os.getenv("ZAP_URL"),
185
+ zap_api_key=os.getenv("ZAP_API_KEY"),
186
+ ),
187
+ vps=VPSSettings(
188
+ host=os.getenv("VPS_HOST"),
189
+ user=os.getenv("VPS_USER", "ubuntu"),
190
+ key_path=os.getenv("VPS_KEY"),
191
+ ),
192
+ api=APISettings(
193
+ cors_origins=os.getenv("AIPT_CORS_ORIGINS", "http://localhost:3000").split(","),
194
+ rate_limit=os.getenv("AIPT_RATE_LIMIT", "100/minute"),
195
+ ),
196
+ database=DatabaseSettings(
197
+ url=os.getenv("DATABASE_URL", "sqlite:///./aipt.db"),
198
+ ),
199
+ logging=LoggingSettings(
200
+ level=os.getenv("AIPT_LOG_LEVEL", "INFO"),
201
+ format=os.getenv("AIPT_LOG_FORMAT", "console"),
202
+ ),
203
+ sandbox_mode=os.getenv("AIPT_SANDBOX_MODE", "false").lower() == "true",
204
+ )
205
+
206
+ # Log configuration (without secrets)
207
+ logger.info(
208
+ "Configuration loaded",
209
+ llm_provider=config.llm.provider,
210
+ llm_model=config.llm.model,
211
+ has_llm_key=bool(config.llm.api_key),
212
+ has_acunetix=bool(config.scanners.acunetix_url),
213
+ has_burp=bool(config.scanners.burp_url),
214
+ has_nessus=bool(config.scanners.nessus_url),
215
+ has_vps=bool(config.vps.host),
216
+ sandbox_mode=config.sandbox_mode,
217
+ )
218
+
219
+ return config
220
+
221
+
222
+ def validate_config_for_features(features: List[str]) -> List[str]:
223
+ """
224
+ Validate that required configuration is present for requested features.
225
+
226
+ Args:
227
+ features: List of feature names to validate
228
+
229
+ Returns:
230
+ List of error messages (empty if all valid)
231
+ """
232
+ config = get_config()
233
+ errors = []
234
+
235
+ if "llm" in features and not config.llm.api_key:
236
+ errors.append(
237
+ "LLM API key required. Set ANTHROPIC_API_KEY or OPENAI_API_KEY environment variable."
238
+ )
239
+
240
+ if "acunetix" in features:
241
+ if not config.scanners.acunetix_url:
242
+ errors.append("Acunetix URL required. Set ACUNETIX_URL environment variable.")
243
+ if not config.scanners.acunetix_api_key:
244
+ errors.append("Acunetix API key required. Set ACUNETIX_API_KEY environment variable.")
245
+
246
+ if "burp" in features:
247
+ if not config.scanners.burp_url:
248
+ errors.append("Burp Suite URL required. Set BURP_URL environment variable.")
249
+ if not config.scanners.burp_api_key:
250
+ errors.append("Burp Suite API key required. Set BURP_API_KEY environment variable.")
251
+
252
+ if "nessus" in features:
253
+ if not config.scanners.nessus_url:
254
+ errors.append("Nessus URL required. Set NESSUS_URL environment variable.")
255
+ if not config.scanners.nessus_access_key:
256
+ errors.append("Nessus access key required. Set NESSUS_ACCESS_KEY environment variable.")
257
+ if not config.scanners.nessus_secret_key:
258
+ errors.append("Nessus secret key required. Set NESSUS_SECRET_KEY environment variable.")
259
+
260
+ if "vps" in features:
261
+ if not config.vps.host:
262
+ errors.append("VPS host required. Set VPS_HOST environment variable.")
263
+ if not config.vps.key_path:
264
+ errors.append("VPS SSH key path required. Set VPS_KEY environment variable.")
265
+ elif not Path(config.vps.key_path).exists():
266
+ errors.append(f"VPS SSH key not found: {config.vps.key_path}")
267
+
268
+ return errors
269
+
270
+
271
+ # Convenience function
272
+ def require_config(*features: str) -> AIPTConfig:
273
+ """
274
+ Get config and raise if required features are not configured.
275
+
276
+ Args:
277
+ *features: Feature names to validate
278
+
279
+ Returns:
280
+ AIPTConfig instance
281
+
282
+ Raises:
283
+ ValueError: If required configuration is missing
284
+ """
285
+ errors = validate_config_for_features(list(features))
286
+ if errors:
287
+ raise ValueError("Configuration errors:\n" + "\n".join(f" - {e}" for e in errors))
288
+ return get_config()
@@ -0,0 +1,43 @@
1
+ """
2
+ AIPT Core Module
3
+
4
+ LangGraph-based autonomous pentesting agent with:
5
+ - Multi-provider LLM abstraction (OpenAI, Anthropic, Ollama)
6
+ - Memory management with automatic compression
7
+ - State machine for pentest workflow
8
+
9
+ Inspired by: Strix (LangGraph state machine, 300 iterations)
10
+ """
11
+ from __future__ import annotations
12
+
13
+ from .llm import (
14
+ LLMProvider,
15
+ LLMResponse,
16
+ OpenAIProvider,
17
+ AnthropicProvider,
18
+ OllamaProvider,
19
+ get_llm,
20
+ )
21
+ from .memory import MemoryManager, MemoryConfig
22
+ from .agent import AIPTAgent, PentestState, Phase
23
+ from .ptt import PTTTracker, PTTNode
24
+
25
+ __all__ = [
26
+ # LLM
27
+ "LLMProvider",
28
+ "LLMResponse",
29
+ "OpenAIProvider",
30
+ "AnthropicProvider",
31
+ "OllamaProvider",
32
+ "get_llm",
33
+ # Memory
34
+ "MemoryManager",
35
+ "MemoryConfig",
36
+ # Agent
37
+ "AIPTAgent",
38
+ "PentestState",
39
+ "Phase",
40
+ # PTT
41
+ "PTTTracker",
42
+ "PTTNode",
43
+ ]