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,505 @@
1
+ """
2
+ SMB Attack Module
3
+
4
+ Implements SMB-based enumeration and attacks:
5
+ - Share enumeration
6
+ - User enumeration via SMB
7
+ - Password spraying
8
+ - Pass-the-hash authentication
9
+ - SMB signing checks
10
+
11
+ Uses Impacket and CrackMapExec for SMB operations.
12
+
13
+ Usage:
14
+ from aipt_v2.tools.active_directory import SMBAttacks
15
+
16
+ smb = SMBAttacks(config)
17
+ shares = await smb.enumerate_shares()
18
+ """
19
+
20
+ import asyncio
21
+ import re
22
+ from dataclasses import dataclass, field
23
+ from datetime import datetime, timezone
24
+ from typing import List, Dict, Any, Optional
25
+
26
+ from aipt_v2.tools.active_directory.ad_config import ADConfig, get_ad_config
27
+
28
+
29
+ @dataclass
30
+ class SMBFinding:
31
+ """SMB security finding."""
32
+ category: str # share, signing, auth, misc
33
+ severity: str
34
+ title: str
35
+ description: str
36
+ target: str
37
+ evidence: str = ""
38
+ remediation: str = ""
39
+ timestamp: str = ""
40
+
41
+ def __post_init__(self):
42
+ if not self.timestamp:
43
+ self.timestamp = datetime.now(timezone.utc).isoformat()
44
+
45
+
46
+ @dataclass
47
+ class SMBShare:
48
+ """SMB share information."""
49
+ name: str
50
+ share_type: str
51
+ remark: str
52
+ readable: bool
53
+ writable: bool
54
+ permissions: List[str] = field(default_factory=list)
55
+
56
+
57
+ @dataclass
58
+ class SMBResult:
59
+ """Result of SMB enumeration."""
60
+ target: str
61
+ status: str
62
+ started_at: str
63
+ finished_at: str
64
+ duration: float
65
+ shares: List[SMBShare]
66
+ os_info: Dict[str, str]
67
+ signing_required: bool
68
+ findings: List[SMBFinding]
69
+ metadata: Dict[str, Any] = field(default_factory=dict)
70
+
71
+
72
+ class SMBAttacks:
73
+ """
74
+ SMB Attack and Enumeration Tool.
75
+
76
+ Performs SMB-based reconnaissance and attacks
77
+ against Windows systems.
78
+ """
79
+
80
+ # Sensitive share names
81
+ SENSITIVE_SHARES = [
82
+ "ADMIN$", "C$", "IPC$", "SYSVOL", "NETLOGON",
83
+ "backup", "Backup", "IT", "Admin", "HR", "Finance",
84
+ "Confidential", "Private", "Secure"
85
+ ]
86
+
87
+ def __init__(self, config: Optional[ADConfig] = None):
88
+ """
89
+ Initialize SMB attacker.
90
+
91
+ Args:
92
+ config: AD configuration
93
+ """
94
+ self.config = config or ADConfig()
95
+ self.findings: List[SMBFinding] = []
96
+ self.shares: List[SMBShare] = []
97
+ self.os_info: Dict[str, str] = {}
98
+ self.signing_required: bool = True
99
+
100
+ async def _run_command(self, cmd: List[str]) -> str:
101
+ """Run command and return output."""
102
+ try:
103
+ process = await asyncio.create_subprocess_exec(
104
+ *cmd,
105
+ stdout=asyncio.subprocess.PIPE,
106
+ stderr=asyncio.subprocess.PIPE
107
+ )
108
+
109
+ stdout, stderr = await asyncio.wait_for(
110
+ process.communicate(),
111
+ timeout=self.config.timeout
112
+ )
113
+
114
+ return stdout.decode() + stderr.decode()
115
+
116
+ except asyncio.TimeoutError:
117
+ return ""
118
+ except FileNotFoundError:
119
+ return f"[!] Command not found: {cmd[0]}"
120
+ except Exception as e:
121
+ return f"[!] Error: {e}"
122
+
123
+ async def check_smb_signing(self, target: str = None) -> bool:
124
+ """
125
+ Check if SMB signing is required.
126
+
127
+ Args:
128
+ target: Target IP (uses config.dc_ip if not provided)
129
+
130
+ Returns:
131
+ True if signing is required
132
+ """
133
+ target = target or self.config.dc_ip
134
+
135
+ # Use nmap for signing check
136
+ output = await self._run_command([
137
+ "nmap", "-p", "445",
138
+ "--script", "smb2-security-mode",
139
+ target
140
+ ])
141
+
142
+ if "Message signing enabled but not required" in output:
143
+ self.signing_required = False
144
+ self.findings.append(SMBFinding(
145
+ category="signing",
146
+ severity="high",
147
+ title="SMB Signing Not Required",
148
+ description="SMB signing is enabled but not required",
149
+ target=target,
150
+ evidence="Message signing enabled but not required",
151
+ remediation="Enable mandatory SMB signing via GPO"
152
+ ))
153
+ elif "Message signing enabled and required" in output:
154
+ self.signing_required = True
155
+ elif "not required" in output.lower():
156
+ self.signing_required = False
157
+ self.findings.append(SMBFinding(
158
+ category="signing",
159
+ severity="high",
160
+ title="SMB Signing Not Required",
161
+ description="SMB signing is not enforced",
162
+ target=target,
163
+ evidence=output[:200],
164
+ remediation="Enable mandatory SMB signing"
165
+ ))
166
+
167
+ return self.signing_required
168
+
169
+ async def enumerate_shares(self, target: str = None) -> List[SMBShare]:
170
+ """
171
+ Enumerate SMB shares.
172
+
173
+ Args:
174
+ target: Target IP
175
+
176
+ Returns:
177
+ List of discovered shares
178
+ """
179
+ target = target or self.config.dc_ip
180
+ shares = []
181
+
182
+ # Build smbclient command
183
+ cmd = ["smbclient", "-L", target, "-N"] # Null session first
184
+
185
+ if self.config.credentials.has_credentials():
186
+ user = self.config.credentials.get_auth_string()
187
+ cmd = ["smbclient", "-L", target, "-U", user]
188
+ if self.config.credentials.password:
189
+ cmd.extend(["-p", self.config.credentials.password])
190
+
191
+ output = await self._run_command(cmd)
192
+
193
+ # Parse share listing
194
+ share_pattern = r"^\s+(\S+)\s+(Disk|IPC|Printer)\s*(.*?)$"
195
+ for line in output.split("\n"):
196
+ match = re.match(share_pattern, line)
197
+ if match:
198
+ share_name = match.group(1)
199
+ share_type = match.group(2)
200
+ remark = match.group(3).strip()
201
+
202
+ share = SMBShare(
203
+ name=share_name,
204
+ share_type=share_type,
205
+ remark=remark,
206
+ readable=False,
207
+ writable=False
208
+ )
209
+ shares.append(share)
210
+
211
+ # Check for sensitive shares
212
+ if any(sens.lower() in share_name.lower() for sens in self.SENSITIVE_SHARES):
213
+ self.findings.append(SMBFinding(
214
+ category="share",
215
+ severity="medium",
216
+ title=f"Sensitive Share: {share_name}",
217
+ description=f"Potentially sensitive share discovered: {share_name}",
218
+ target=target,
219
+ evidence=f"Share: {share_name} ({share_type})",
220
+ remediation="Review share permissions and access"
221
+ ))
222
+
223
+ # Try to access each share
224
+ for share in shares:
225
+ access = await self._check_share_access(target, share.name)
226
+ share.readable = access.get("readable", False)
227
+ share.writable = access.get("writable", False)
228
+
229
+ if share.readable and share.name not in ["IPC$"]:
230
+ self.findings.append(SMBFinding(
231
+ category="share",
232
+ severity="low" if share.name in ["SYSVOL", "NETLOGON"] else "medium",
233
+ title=f"Readable Share: {share.name}",
234
+ description=f"Share {share.name} is readable",
235
+ target=target,
236
+ evidence="Share access confirmed",
237
+ remediation="Review if read access is necessary"
238
+ ))
239
+
240
+ if share.writable:
241
+ self.findings.append(SMBFinding(
242
+ category="share",
243
+ severity="high",
244
+ title=f"Writable Share: {share.name}",
245
+ description=f"Share {share.name} is writable",
246
+ target=target,
247
+ evidence="Write access confirmed",
248
+ remediation="Restrict write access to authorized users only"
249
+ ))
250
+
251
+ self.shares = shares
252
+ return shares
253
+
254
+ async def _check_share_access(self, target: str, share: str) -> Dict[str, bool]:
255
+ """Check read/write access to a share."""
256
+ access = {"readable": False, "writable": False}
257
+
258
+ # Build connection command
259
+ if self.config.credentials.has_credentials():
260
+ user = self.config.credentials.get_auth_string()
261
+ cmd = [
262
+ "smbclient",
263
+ f"//{target}/{share}",
264
+ "-U", user,
265
+ "-c", "dir"
266
+ ]
267
+ if self.config.credentials.password:
268
+ cmd.insert(4, "-p")
269
+ cmd.insert(5, self.config.credentials.password)
270
+ else:
271
+ cmd = ["smbclient", f"//{target}/{share}", "-N", "-c", "dir"]
272
+
273
+ output = await self._run_command(cmd)
274
+
275
+ # Check if we could list contents
276
+ if "NT_STATUS_ACCESS_DENIED" not in output and "Error" not in output:
277
+ if any(x in output for x in ["blocks", "bytes", "Directory"]):
278
+ access["readable"] = True
279
+
280
+ # TODO: Add write check with careful file creation/deletion
281
+
282
+ return access
283
+
284
+ async def get_os_info(self, target: str = None) -> Dict[str, str]:
285
+ """
286
+ Get OS information via SMB.
287
+
288
+ Args:
289
+ target: Target IP
290
+
291
+ Returns:
292
+ OS information dict
293
+ """
294
+ target = target or self.config.dc_ip
295
+ os_info = {}
296
+
297
+ # Use nmap for OS detection
298
+ output = await self._run_command([
299
+ "nmap", "-p", "445",
300
+ "--script", "smb-os-discovery",
301
+ target
302
+ ])
303
+
304
+ # Parse OS info
305
+ os_match = re.search(r"OS:\s*(.+?)$", output, re.MULTILINE)
306
+ if os_match:
307
+ os_info["os"] = os_match.group(1).strip()
308
+
309
+ computer_match = re.search(r"Computer name:\s*(.+?)$", output, re.MULTILINE)
310
+ if computer_match:
311
+ os_info["computer_name"] = computer_match.group(1).strip()
312
+
313
+ domain_match = re.search(r"Domain name:\s*(.+?)$", output, re.MULTILINE)
314
+ if domain_match:
315
+ os_info["domain"] = domain_match.group(1).strip()
316
+
317
+ self.os_info = os_info
318
+ return os_info
319
+
320
+ async def enumerate_users_rpc(self, target: str = None) -> List[str]:
321
+ """
322
+ Enumerate users via RPC.
323
+
324
+ Args:
325
+ target: Target IP
326
+
327
+ Returns:
328
+ List of usernames
329
+ """
330
+ target = target or self.config.dc_ip
331
+ users = []
332
+
333
+ # Use rpcclient for enumeration
334
+ cmd = ["rpcclient", "-U", "", target, "-N", "-c", "enumdomusers"]
335
+
336
+ if self.config.credentials.has_credentials():
337
+ user = self.config.credentials.get_auth_string()
338
+ password = self.config.credentials.get_password_or_hash()
339
+ cmd = [
340
+ "rpcclient", "-U", f"{user}%{password}",
341
+ target, "-c", "enumdomusers"
342
+ ]
343
+
344
+ output = await self._run_command(cmd)
345
+
346
+ # Parse users
347
+ user_pattern = r"user:\[([^\]]+)\]"
348
+ matches = re.findall(user_pattern, output)
349
+ users.extend(matches)
350
+
351
+ return users
352
+
353
+ async def password_spray(
354
+ self,
355
+ users: List[str],
356
+ password: str,
357
+ target: str = None
358
+ ) -> List[Dict]:
359
+ """
360
+ Perform password spray attack.
361
+
362
+ Args:
363
+ users: List of usernames
364
+ password: Password to try
365
+ target: Target IP
366
+
367
+ Returns:
368
+ List of valid credentials
369
+ """
370
+ target = target or self.config.dc_ip
371
+ valid_creds = []
372
+
373
+ for user in users:
374
+ # Use crackmapexec or smbclient for auth test
375
+ cmd = [
376
+ "smbclient",
377
+ f"//{target}/IPC$",
378
+ "-U", f"{self.config.domain}\\{user}%{password}",
379
+ "-c", "exit"
380
+ ]
381
+
382
+ output = await self._run_command(cmd)
383
+
384
+ if "NT_STATUS_LOGON_FAILURE" not in output and "Error" not in output:
385
+ valid_creds.append({
386
+ "username": user,
387
+ "password": password
388
+ })
389
+
390
+ self.findings.append(SMBFinding(
391
+ category="auth",
392
+ severity="critical",
393
+ title=f"Valid Credentials: {user}",
394
+ description=f"Password spray found valid credentials for {user}",
395
+ target=target,
396
+ evidence=f"User: {user}, Password: {password[:3]}***",
397
+ remediation="Enforce strong password policies"
398
+ ))
399
+
400
+ # Add delay to avoid lockout
401
+ await asyncio.sleep(0.5)
402
+
403
+ return valid_creds
404
+
405
+ async def test_null_session(self, target: str = None) -> bool:
406
+ """
407
+ Test for null session access.
408
+
409
+ Args:
410
+ target: Target IP
411
+
412
+ Returns:
413
+ True if null session works
414
+ """
415
+ target = target or self.config.dc_ip
416
+
417
+ cmd = ["smbclient", f"//{target}/IPC$", "-N", "-c", "exit"]
418
+ output = await self._run_command(cmd)
419
+
420
+ null_session = "NT_STATUS_ACCESS_DENIED" not in output
421
+
422
+ if null_session:
423
+ self.findings.append(SMBFinding(
424
+ category="auth",
425
+ severity="high",
426
+ title="Null Session Allowed",
427
+ description="Anonymous/null session authentication is allowed",
428
+ target=target,
429
+ evidence="IPC$ accessible without credentials",
430
+ remediation="Disable null session access via registry or GPO"
431
+ ))
432
+
433
+ return null_session
434
+
435
+ async def enumerate(self, target: str = None) -> SMBResult:
436
+ """
437
+ Run full SMB enumeration.
438
+
439
+ Args:
440
+ target: Target IP
441
+
442
+ Returns:
443
+ SMBResult with findings
444
+ """
445
+ target = target or self.config.dc_ip
446
+
447
+ started_at = datetime.now(timezone.utc).isoformat()
448
+ start_time = asyncio.get_event_loop().time()
449
+
450
+ # Run enumeration
451
+ await self.check_smb_signing(target)
452
+ await self.test_null_session(target)
453
+ await self.get_os_info(target)
454
+ await self.enumerate_shares(target)
455
+
456
+ finished_at = datetime.now(timezone.utc).isoformat()
457
+ duration = asyncio.get_event_loop().time() - start_time
458
+
459
+ return SMBResult(
460
+ target=target,
461
+ status="completed",
462
+ started_at=started_at,
463
+ finished_at=finished_at,
464
+ duration=duration,
465
+ shares=self.shares,
466
+ os_info=self.os_info,
467
+ signing_required=self.signing_required,
468
+ findings=self.findings,
469
+ metadata={
470
+ "share_count": len(self.shares),
471
+ "finding_count": len(self.findings)
472
+ }
473
+ )
474
+
475
+
476
+ # Convenience function
477
+ async def enumerate_smb(
478
+ target: str,
479
+ domain: str = None,
480
+ username: str = None,
481
+ password: str = None,
482
+ **kwargs
483
+ ) -> SMBResult:
484
+ """
485
+ Quick SMB enumeration.
486
+
487
+ Args:
488
+ target: Target IP or hostname
489
+ domain: AD domain
490
+ username: Username
491
+ password: Password
492
+
493
+ Returns:
494
+ SMBResult
495
+ """
496
+ config = get_ad_config(
497
+ domain=domain or "",
498
+ dc_ip=target,
499
+ username=username or "",
500
+ password=password or "",
501
+ **kwargs
502
+ )
503
+
504
+ smb = SMBAttacks(config)
505
+ return await smb.enumerate(target)
@@ -0,0 +1,19 @@
1
+ """
2
+ AIPT Agents Graph - Agent communication and tracking
3
+ """
4
+
5
+ from aipt_v2.tools.agents_graph.agents_graph_actions import (
6
+ _agent_graph,
7
+ _agent_instances,
8
+ _agent_states,
9
+ _agent_messages,
10
+ _root_agent_id,
11
+ )
12
+
13
+ __all__ = [
14
+ "_agent_graph",
15
+ "_agent_instances",
16
+ "_agent_states",
17
+ "_agent_messages",
18
+ "_root_agent_id",
19
+ ]
@@ -0,0 +1,69 @@
1
+ """
2
+ AIPT Agents Graph Actions - State management for agent graph
3
+ """
4
+
5
+ from typing import Any, Optional
6
+
7
+ # Global state for agent graph
8
+ _agent_graph: dict[str, Any] = {
9
+ "nodes": {},
10
+ "edges": [],
11
+ }
12
+
13
+ _agent_instances: dict[str, Any] = {}
14
+ _agent_states: dict[str, Any] = {}
15
+ _agent_messages: dict[str, list[dict]] = {}
16
+ _root_agent_id: Optional[str] = None
17
+
18
+
19
+ def reset_graph() -> None:
20
+ """Reset the agent graph to initial state"""
21
+ global _agent_graph, _agent_instances, _agent_states, _agent_messages, _root_agent_id
22
+ _agent_graph = {"nodes": {}, "edges": []}
23
+ _agent_instances = {}
24
+ _agent_states = {}
25
+ _agent_messages = {}
26
+ _root_agent_id = None
27
+
28
+
29
+ def send_message(
30
+ from_agent_id: str,
31
+ to_agent_id: str,
32
+ content: str,
33
+ message_type: str = "information",
34
+ priority: str = "normal",
35
+ ) -> bool:
36
+ """Send a message from one agent to another"""
37
+ from datetime import datetime
38
+
39
+ if to_agent_id not in _agent_messages:
40
+ _agent_messages[to_agent_id] = []
41
+
42
+ _agent_messages[to_agent_id].append({
43
+ "from": from_agent_id,
44
+ "content": content,
45
+ "message_type": message_type,
46
+ "priority": priority,
47
+ "timestamp": datetime.now().isoformat(),
48
+ "read": False,
49
+ })
50
+ return True
51
+
52
+
53
+ def get_agent_status(agent_id: str) -> Optional[str]:
54
+ """Get the current status of an agent"""
55
+ if agent_id in _agent_graph["nodes"]:
56
+ return _agent_graph["nodes"][agent_id].get("status")
57
+ return None
58
+
59
+
60
+ __all__ = [
61
+ "_agent_graph",
62
+ "_agent_instances",
63
+ "_agent_states",
64
+ "_agent_messages",
65
+ "_root_agent_id",
66
+ "reset_graph",
67
+ "send_message",
68
+ "get_agent_status",
69
+ ]
@@ -0,0 +1,76 @@
1
+ """
2
+ AIPT API Security Module - Comprehensive API Vulnerability Scanning
3
+
4
+ Provides security testing for modern API architectures:
5
+ - REST APIs (OpenAPI/Swagger fuzzing)
6
+ - GraphQL APIs (Introspection, DoS, Injection)
7
+ - JWT Tokens (Algorithm confusion, signature bypass)
8
+ - API Discovery (Endpoint enumeration, documentation detection)
9
+
10
+ Usage:
11
+ from aipt_v2.tools.api_security import (
12
+ GraphQLScanner,
13
+ OpenAPIFuzzer,
14
+ JWTAnalyzer,
15
+ APIDiscovery
16
+ )
17
+
18
+ # Scan GraphQL endpoint
19
+ scanner = GraphQLScanner("https://api.target.com/graphql")
20
+ findings = await scanner.scan()
21
+
22
+ # Fuzz REST API from OpenAPI spec
23
+ fuzzer = OpenAPIFuzzer("https://api.target.com", spec_path="openapi.yaml")
24
+ findings = await fuzzer.fuzz()
25
+
26
+ # Analyze JWT token
27
+ analyzer = JWTAnalyzer()
28
+ findings = analyzer.analyze(token)
29
+ """
30
+
31
+ from aipt_v2.tools.api_security.graphql_scanner import (
32
+ GraphQLScanner,
33
+ GraphQLConfig,
34
+ GraphQLFinding,
35
+ scan_graphql,
36
+ )
37
+
38
+ from aipt_v2.tools.api_security.openapi_fuzzer import (
39
+ OpenAPIFuzzer,
40
+ OpenAPIConfig,
41
+ OpenAPIFinding,
42
+ fuzz_openapi,
43
+ )
44
+
45
+ from aipt_v2.tools.api_security.jwt_analyzer import (
46
+ JWTAnalyzer,
47
+ JWTFinding,
48
+ analyze_jwt,
49
+ )
50
+
51
+ from aipt_v2.tools.api_security.api_discovery import (
52
+ APIDiscovery,
53
+ DiscoveredEndpoint,
54
+ discover_api,
55
+ )
56
+
57
+ __all__ = [
58
+ # GraphQL
59
+ "GraphQLScanner",
60
+ "GraphQLConfig",
61
+ "GraphQLFinding",
62
+ "scan_graphql",
63
+ # OpenAPI
64
+ "OpenAPIFuzzer",
65
+ "OpenAPIConfig",
66
+ "OpenAPIFinding",
67
+ "fuzz_openapi",
68
+ # JWT
69
+ "JWTAnalyzer",
70
+ "JWTFinding",
71
+ "analyze_jwt",
72
+ # Discovery
73
+ "APIDiscovery",
74
+ "DiscoveredEndpoint",
75
+ "discover_api",
76
+ ]