wegho-agentes 4.0.1
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.
- package/.agents/AGENT_WORKFLOW.md +528 -0
- package/.agents/AI_COMPATIBILITY.md +332 -0
- package/.agents/CLI.md +222 -0
- package/.agents/README.md +130 -0
- package/.agents/cli.js +389 -0
- package/.agents/code-auditor-agent.ts +333 -0
- package/.agents/config.ts +145 -0
- package/.agents/context-loader.ts +300 -0
- package/.agents/core/agent-parallelizer.test.ts +94 -0
- package/.agents/core/agent-parallelizer.ts +108 -0
- package/.agents/core/architecture-agent.ts +237 -0
- package/.agents/core/base-agent.ts +311 -0
- package/.agents/core/cache-manager.test.ts +147 -0
- package/.agents/core/cache-manager.ts +184 -0
- package/.agents/core/documentation-agent.ts +183 -0
- package/.agents/core/feedback-collector.ts +207 -0
- package/.agents/core/frontend-agent.ts +210 -0
- package/.agents/core/inventory-agent.ts +582 -0
- package/.agents/core/memory-system.ts +397 -0
- package/.agents/core/quality-agent.ts +268 -0
- package/.agents/core/retry-utility.test.ts +165 -0
- package/.agents/core/retry-utility.ts +140 -0
- package/.agents/core/security-agent.ts +217 -0
- package/.agents/core/workflow-validator.test.ts +171 -0
- package/.agents/core/workflow-validator.ts +158 -0
- package/.agents/domains/README.md +53 -0
- package/.agents/domains/logistics/route-agent.ts +177 -0
- package/.agents/domains/news/cms-agent.ts +158 -0
- package/.agents/domains/news/seo-agent.ts +170 -0
- package/.agents/domains/production/production-control-agent.ts +169 -0
- package/.agents/example-learning-system.js +118 -0
- package/.agents/init.ts +164 -0
- package/.agents/memory/architecture-agent/failures.json +1 -0
- package/.agents/memory/architecture-agent/learnings.json +1 -0
- package/.agents/memory/architecture-agent/specialty.md +31 -0
- package/.agents/memory/architecture-agent/successes.json +16 -0
- package/.agents/memory/cms-agent/failures.json +1 -0
- package/.agents/memory/cms-agent/learnings.json +1 -0
- package/.agents/memory/cms-agent/specialty.md +30 -0
- package/.agents/memory/cms-agent/successes.json +16 -0
- package/.agents/memory/documentation-agent/failures.json +1 -0
- package/.agents/memory/documentation-agent/learnings.json +1 -0
- package/.agents/memory/documentation-agent/specialty.md +33 -0
- package/.agents/memory/documentation-agent/successes.json +16 -0
- package/.agents/memory/frontend-agent/failures.json +1 -0
- package/.agents/memory/frontend-agent/learnings.json +1 -0
- package/.agents/memory/frontend-agent/specialty.md +30 -0
- package/.agents/memory/frontend-agent/successes.json +16 -0
- package/.agents/memory/inventory-agent/failures.json +1 -0
- package/.agents/memory/inventory-agent/inventory/index.json +8 -0
- package/.agents/memory/inventory-agent/inventory/types.json +77716 -0
- package/.agents/memory/inventory-agent/inventory/variables.json +405 -0
- package/.agents/memory/inventory-agent/learnings.json +1 -0
- package/.agents/memory/inventory-agent/specialty.md +129 -0
- package/.agents/memory/inventory-agent/successes.json +30 -0
- package/.agents/memory/production-control-agent/failures.json +1 -0
- package/.agents/memory/production-control-agent/learnings.json +1 -0
- package/.agents/memory/production-control-agent/specialty.md +29 -0
- package/.agents/memory/production-control-agent/successes.json +16 -0
- package/.agents/memory/quality-agent/failures.json +16 -0
- package/.agents/memory/quality-agent/learnings.json +1 -0
- package/.agents/memory/quality-agent/specialty.md +31 -0
- package/.agents/memory/quality-agent/successes.json +1 -0
- package/.agents/memory/reference-repositories.json +271 -0
- package/.agents/memory/route-agent/failures.json +1 -0
- package/.agents/memory/route-agent/learnings.json +1 -0
- package/.agents/memory/route-agent/specialty.md +29 -0
- package/.agents/memory/route-agent/successes.json +16 -0
- package/.agents/memory/security-agent/failures.json +1 -0
- package/.agents/memory/security-agent/learnings.json +1 -0
- package/.agents/memory/security-agent/specialty.md +31 -0
- package/.agents/memory/security-agent/successes.json +16 -0
- package/.agents/memory/seo-agent/failures.json +1 -0
- package/.agents/memory/seo-agent/learnings.json +1 -0
- package/.agents/memory/seo-agent/specialty.md +31 -0
- package/.agents/memory/seo-agent/successes.json +16 -0
- package/.agents/orchestrator.ts +438 -0
- package/.agents/project-discovery-agent.ts +342 -0
- package/.agents/security/pentesting-agent.py +387 -0
- package/.agents/security/python-bridge.ts +193 -0
- package/.agents/security/vulnerability-db.json +201 -0
- package/.agents/task-analyzer-agent.ts +346 -0
- package/.agents/test-init-context.js +67 -0
- package/INSTALL.md +300 -0
- package/LICENSE +21 -0
- package/README.md +315 -0
- package/docs/AGENT_RULES.md +292 -0
- package/docs/BUILD_HISTORY.md +65 -0
- package/docs/DESIGN_SYSTEM.md +256 -0
- package/docs/LEARNING_SYSTEM.md +326 -0
- package/docs/SYMBOLS_TREE.md +182 -0
- package/docs/VERSION.md +6 -0
- package/docs/architecture.md +111 -0
- package/package.json +60 -0
|
@@ -0,0 +1,387 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
Pentesting Agent - Agente de Testes de Penetração
|
|
4
|
+
Responsável por executar testes de segurança automatizados
|
|
5
|
+
|
|
6
|
+
⚠️ USO ÉTICO OBRIGATÓRIO - Apenas em projetos autorizados
|
|
7
|
+
"""
|
|
8
|
+
|
|
9
|
+
import json
|
|
10
|
+
import sys
|
|
11
|
+
import argparse
|
|
12
|
+
from typing import List, Dict, Any
|
|
13
|
+
from datetime import datetime
|
|
14
|
+
import os
|
|
15
|
+
|
|
16
|
+
class PentestingAgent:
|
|
17
|
+
def __init__(self, target_url: str, memory_path: str = ".agents/memory/pentesting-agent"):
|
|
18
|
+
self.target = target_url
|
|
19
|
+
self.memory_path = memory_path
|
|
20
|
+
self.results = []
|
|
21
|
+
self.vulnerability_db = self.load_vulnerability_db()
|
|
22
|
+
self.ensure_memory_structure()
|
|
23
|
+
|
|
24
|
+
def ensure_memory_structure(self):
|
|
25
|
+
"""Garante que a estrutura de memória existe"""
|
|
26
|
+
os.makedirs(self.memory_path, exist_ok=True)
|
|
27
|
+
|
|
28
|
+
# Criar arquivos de memória se não existirem
|
|
29
|
+
for file in ['successes.json', 'failures.json', 'learnings.json']:
|
|
30
|
+
filepath = os.path.join(self.memory_path, file)
|
|
31
|
+
if not os.path.exists(filepath):
|
|
32
|
+
with open(filepath, 'w') as f:
|
|
33
|
+
json.dump([], f)
|
|
34
|
+
|
|
35
|
+
def load_vulnerability_db(self) -> Dict[str, Any]:
|
|
36
|
+
"""Carrega banco de dados de vulnerabilidades"""
|
|
37
|
+
db_path = os.path.join(os.path.dirname(__file__), 'vulnerability-db.json')
|
|
38
|
+
try:
|
|
39
|
+
with open(db_path, 'r') as f:
|
|
40
|
+
return json.load(f)
|
|
41
|
+
except FileNotFoundError:
|
|
42
|
+
return self.get_default_vulnerability_db()
|
|
43
|
+
|
|
44
|
+
def get_default_vulnerability_db(self) -> Dict[str, Any]:
|
|
45
|
+
"""Retorna banco de dados padrão de vulnerabilidades"""
|
|
46
|
+
return {
|
|
47
|
+
"sql_injection": {
|
|
48
|
+
"severity": "CRITICAL",
|
|
49
|
+
"owasp_id": "A03:2021",
|
|
50
|
+
"category": "Injection",
|
|
51
|
+
"payloads": [
|
|
52
|
+
"' OR '1'='1",
|
|
53
|
+
"'; DROP TABLE users--",
|
|
54
|
+
"' UNION SELECT NULL--",
|
|
55
|
+
"admin' --",
|
|
56
|
+
"' OR 1=1--"
|
|
57
|
+
],
|
|
58
|
+
"detection": "Error messages, data leakage, unauthorized access",
|
|
59
|
+
"remediation": "Use prepared statements, parameterized queries, ORM"
|
|
60
|
+
},
|
|
61
|
+
"xss": {
|
|
62
|
+
"severity": "HIGH",
|
|
63
|
+
"owasp_id": "A03:2021",
|
|
64
|
+
"category": "Injection",
|
|
65
|
+
"payloads": [
|
|
66
|
+
"<script>alert('XSS')</script>",
|
|
67
|
+
"<img src=x onerror=alert('XSS')>",
|
|
68
|
+
"javascript:alert('XSS')",
|
|
69
|
+
"<svg onload=alert('XSS')>",
|
|
70
|
+
"'-alert('XSS')-'"
|
|
71
|
+
],
|
|
72
|
+
"detection": "Script execution, DOM manipulation",
|
|
73
|
+
"remediation": "Sanitize inputs, use DOMPurify, Content Security Policy"
|
|
74
|
+
},
|
|
75
|
+
"csrf": {
|
|
76
|
+
"severity": "HIGH",
|
|
77
|
+
"owasp_id": "A01:2021",
|
|
78
|
+
"category": "Broken Access Control",
|
|
79
|
+
"detection": "Missing CSRF tokens, predictable tokens",
|
|
80
|
+
"remediation": "Implement CSRF tokens, SameSite cookies"
|
|
81
|
+
},
|
|
82
|
+
"weak_passwords": {
|
|
83
|
+
"severity": "CRITICAL",
|
|
84
|
+
"owasp_id": "A07:2021",
|
|
85
|
+
"category": "Identification and Authentication Failures",
|
|
86
|
+
"common_passwords": [
|
|
87
|
+
"123456", "password", "123456789", "12345678", "12345",
|
|
88
|
+
"1234567", "admin", "123123", "qwerty", "abc123"
|
|
89
|
+
],
|
|
90
|
+
"detection": "Successful login with weak password",
|
|
91
|
+
"remediation": "Enforce strong password policy, use password strength meter"
|
|
92
|
+
},
|
|
93
|
+
"session_hijacking": {
|
|
94
|
+
"severity": "CRITICAL",
|
|
95
|
+
"owasp_id": "A07:2021",
|
|
96
|
+
"category": "Identification and Authentication Failures",
|
|
97
|
+
"detection": "Session fixation, predictable session IDs",
|
|
98
|
+
"remediation": "Regenerate session ID after login, use secure cookies"
|
|
99
|
+
},
|
|
100
|
+
"insecure_headers": {
|
|
101
|
+
"severity": "MEDIUM",
|
|
102
|
+
"owasp_id": "A05:2021",
|
|
103
|
+
"category": "Security Misconfiguration",
|
|
104
|
+
"required_headers": [
|
|
105
|
+
"X-Frame-Options",
|
|
106
|
+
"X-Content-Type-Options",
|
|
107
|
+
"Strict-Transport-Security",
|
|
108
|
+
"Content-Security-Policy"
|
|
109
|
+
],
|
|
110
|
+
"remediation": "Configure security headers properly"
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
def test_sql_injection(self, endpoints: List[str]) -> Dict[str, Any]:
|
|
115
|
+
"""Testa SQL Injection em endpoints"""
|
|
116
|
+
print(f"\n🔍 Testando SQL Injection em {len(endpoints)} endpoint(s)...")
|
|
117
|
+
|
|
118
|
+
vulnerabilities = []
|
|
119
|
+
payloads = self.vulnerability_db['sql_injection']['payloads']
|
|
120
|
+
|
|
121
|
+
for endpoint in endpoints:
|
|
122
|
+
for payload in payloads:
|
|
123
|
+
# Simulação de teste (em produção usaria requests)
|
|
124
|
+
result = {
|
|
125
|
+
'endpoint': endpoint,
|
|
126
|
+
'payload': payload,
|
|
127
|
+
'vulnerable': False, # Placeholder
|
|
128
|
+
'evidence': None
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# Aqui seria feito o teste real
|
|
132
|
+
# response = requests.get(endpoint, params={'id': payload})
|
|
133
|
+
# if 'error' in response.text or 'SQL' in response.text:
|
|
134
|
+
# result['vulnerable'] = True
|
|
135
|
+
|
|
136
|
+
if result['vulnerable']:
|
|
137
|
+
vulnerabilities.append(result)
|
|
138
|
+
|
|
139
|
+
return {
|
|
140
|
+
'test': 'sql_injection',
|
|
141
|
+
'severity': self.vulnerability_db['sql_injection']['severity'],
|
|
142
|
+
'tested_endpoints': len(endpoints),
|
|
143
|
+
'vulnerabilities_found': len(vulnerabilities),
|
|
144
|
+
'details': vulnerabilities
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
def test_xss(self, inputs: List[str]) -> Dict[str, Any]:
|
|
148
|
+
"""Testa XSS em inputs"""
|
|
149
|
+
print(f"\n🔍 Testando XSS em {len(inputs)} input(s)...")
|
|
150
|
+
|
|
151
|
+
vulnerabilities = []
|
|
152
|
+
payloads = self.vulnerability_db['xss']['payloads']
|
|
153
|
+
|
|
154
|
+
for input_field in inputs:
|
|
155
|
+
for payload in payloads:
|
|
156
|
+
# Simulação de teste
|
|
157
|
+
result = {
|
|
158
|
+
'input': input_field,
|
|
159
|
+
'payload': payload,
|
|
160
|
+
'vulnerable': False,
|
|
161
|
+
'type': None # reflected, stored, dom
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# Aqui seria feito o teste real com Selenium
|
|
165
|
+
# driver.find_element_by_id(input_field).send_keys(payload)
|
|
166
|
+
# if payload in driver.page_source:
|
|
167
|
+
# result['vulnerable'] = True
|
|
168
|
+
|
|
169
|
+
if result['vulnerable']:
|
|
170
|
+
vulnerabilities.append(result)
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
'test': 'xss',
|
|
174
|
+
'severity': self.vulnerability_db['xss']['severity'],
|
|
175
|
+
'tested_inputs': len(inputs),
|
|
176
|
+
'vulnerabilities_found': len(vulnerabilities),
|
|
177
|
+
'details': vulnerabilities
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
def test_weak_passwords(self, login_endpoint: str, usernames: List[str]) -> Dict[str, Any]:
|
|
181
|
+
"""Testa senhas fracas"""
|
|
182
|
+
print(f"\n🔍 Testando senhas fracas para {len(usernames)} usuário(s)...")
|
|
183
|
+
|
|
184
|
+
weak_accounts = []
|
|
185
|
+
common_passwords = self.vulnerability_db['weak_passwords']['common_passwords']
|
|
186
|
+
|
|
187
|
+
for username in usernames:
|
|
188
|
+
for password in common_passwords:
|
|
189
|
+
# Simulação de teste
|
|
190
|
+
result = {
|
|
191
|
+
'username': username,
|
|
192
|
+
'password': password,
|
|
193
|
+
'success': False
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
# Aqui seria feito o teste real
|
|
197
|
+
# response = requests.post(login_endpoint, data={
|
|
198
|
+
# 'username': username,
|
|
199
|
+
# 'password': password
|
|
200
|
+
# })
|
|
201
|
+
# if response.status_code == 200:
|
|
202
|
+
# result['success'] = True
|
|
203
|
+
|
|
204
|
+
if result['success']:
|
|
205
|
+
weak_accounts.append(result)
|
|
206
|
+
break # Parar após encontrar senha fraca
|
|
207
|
+
|
|
208
|
+
return {
|
|
209
|
+
'test': 'weak_passwords',
|
|
210
|
+
'severity': self.vulnerability_db['weak_passwords']['severity'],
|
|
211
|
+
'tested_accounts': len(usernames),
|
|
212
|
+
'weak_accounts_found': len(weak_accounts),
|
|
213
|
+
'details': weak_accounts
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
def test_security_headers(self) -> Dict[str, Any]:
|
|
217
|
+
"""Testa headers de segurança"""
|
|
218
|
+
print(f"\n🔍 Testando headers de segurança...")
|
|
219
|
+
|
|
220
|
+
required_headers = self.vulnerability_db['insecure_headers']['required_headers']
|
|
221
|
+
missing_headers = []
|
|
222
|
+
|
|
223
|
+
# Simulação de teste
|
|
224
|
+
# response = requests.get(self.target)
|
|
225
|
+
# for header in required_headers:
|
|
226
|
+
# if header not in response.headers:
|
|
227
|
+
# missing_headers.append(header)
|
|
228
|
+
|
|
229
|
+
# Placeholder
|
|
230
|
+
missing_headers = ['X-Frame-Options', 'Content-Security-Policy']
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
'test': 'security_headers',
|
|
234
|
+
'severity': self.vulnerability_db['insecure_headers']['severity'],
|
|
235
|
+
'required_headers': len(required_headers),
|
|
236
|
+
'missing_headers': len(missing_headers),
|
|
237
|
+
'details': missing_headers
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
def run_all_tests(self, config: Dict[str, Any]) -> Dict[str, Any]:
|
|
241
|
+
"""Executa todos os testes de segurança"""
|
|
242
|
+
print(f"\n{'='*60}")
|
|
243
|
+
print(f"🔒 PENTESTING AGENT - Testes de Segurança")
|
|
244
|
+
print(f"{'='*60}")
|
|
245
|
+
print(f"Target: {self.target}")
|
|
246
|
+
print(f"Timestamp: {datetime.now().isoformat()}")
|
|
247
|
+
|
|
248
|
+
results = {
|
|
249
|
+
'target': self.target,
|
|
250
|
+
'timestamp': datetime.now().isoformat(),
|
|
251
|
+
'tests': []
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
# SQL Injection
|
|
255
|
+
if config.get('test_sql_injection', True):
|
|
256
|
+
sql_result = self.test_sql_injection(config.get('endpoints', ['/api/users']))
|
|
257
|
+
results['tests'].append(sql_result)
|
|
258
|
+
|
|
259
|
+
# XSS
|
|
260
|
+
if config.get('test_xss', True):
|
|
261
|
+
xss_result = self.test_xss(config.get('inputs', ['username', 'email', 'comment']))
|
|
262
|
+
results['tests'].append(xss_result)
|
|
263
|
+
|
|
264
|
+
# Weak Passwords
|
|
265
|
+
if config.get('test_passwords', True):
|
|
266
|
+
pwd_result = self.test_weak_passwords(
|
|
267
|
+
config.get('login_endpoint', '/api/login'),
|
|
268
|
+
config.get('usernames', ['admin', 'user', 'test'])
|
|
269
|
+
)
|
|
270
|
+
results['tests'].append(pwd_result)
|
|
271
|
+
|
|
272
|
+
# Security Headers
|
|
273
|
+
if config.get('test_headers', True):
|
|
274
|
+
headers_result = self.test_security_headers()
|
|
275
|
+
results['tests'].append(headers_result)
|
|
276
|
+
|
|
277
|
+
# Calcular resumo
|
|
278
|
+
total_vulnerabilities = sum(test.get('vulnerabilities_found', 0) for test in results['tests'])
|
|
279
|
+
critical_count = sum(1 for test in results['tests'] if test.get('severity') == 'CRITICAL' and test.get('vulnerabilities_found', 0) > 0)
|
|
280
|
+
|
|
281
|
+
results['summary'] = {
|
|
282
|
+
'total_tests': len(results['tests']),
|
|
283
|
+
'total_vulnerabilities': total_vulnerabilities,
|
|
284
|
+
'critical_vulnerabilities': critical_count,
|
|
285
|
+
'status': 'VULNERABLE' if total_vulnerabilities > 0 else 'SECURE'
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
# Salvar na memória
|
|
289
|
+
self.save_to_memory(results)
|
|
290
|
+
|
|
291
|
+
return results
|
|
292
|
+
|
|
293
|
+
def save_to_memory(self, results: Dict[str, Any]):
|
|
294
|
+
"""Salva resultados na memória"""
|
|
295
|
+
memory_entry = {
|
|
296
|
+
'id': f"{int(datetime.now().timestamp())}-{hash(self.target) % 10000}",
|
|
297
|
+
'timestamp': results['timestamp'],
|
|
298
|
+
'target': self.target,
|
|
299
|
+
'total_vulnerabilities': results['summary']['total_vulnerabilities'],
|
|
300
|
+
'status': results['summary']['status'],
|
|
301
|
+
'details': results
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
# Salvar em successes ou failures
|
|
305
|
+
if results['summary']['total_vulnerabilities'] == 0:
|
|
306
|
+
filepath = os.path.join(self.memory_path, 'successes.json')
|
|
307
|
+
else:
|
|
308
|
+
filepath = os.path.join(self.memory_path, 'failures.json')
|
|
309
|
+
|
|
310
|
+
try:
|
|
311
|
+
with open(filepath, 'r') as f:
|
|
312
|
+
memory = json.load(f)
|
|
313
|
+
except:
|
|
314
|
+
memory = []
|
|
315
|
+
|
|
316
|
+
memory.append(memory_entry)
|
|
317
|
+
|
|
318
|
+
with open(filepath, 'w') as f:
|
|
319
|
+
json.dump(memory, f, indent=2)
|
|
320
|
+
|
|
321
|
+
def generate_report(self, results: Dict[str, Any]) -> str:
|
|
322
|
+
"""Gera relatório detalhado"""
|
|
323
|
+
report = f"\n{'='*60}\n"
|
|
324
|
+
report += f"📊 RELATÓRIO DE SEGURANÇA\n"
|
|
325
|
+
report += f"{'='*60}\n\n"
|
|
326
|
+
|
|
327
|
+
report += f"🎯 Target: {results['target']}\n"
|
|
328
|
+
report += f"📅 Data: {results['timestamp']}\n"
|
|
329
|
+
report += f"🔍 Testes executados: {results['summary']['total_tests']}\n"
|
|
330
|
+
report += f"⚠️ Vulnerabilidades encontradas: {results['summary']['total_vulnerabilities']}\n"
|
|
331
|
+
report += f"💀 Vulnerabilidades críticas: {results['summary']['critical_vulnerabilities']}\n"
|
|
332
|
+
report += f"📊 Status: {results['summary']['status']}\n\n"
|
|
333
|
+
|
|
334
|
+
report += f"{'='*60}\n"
|
|
335
|
+
report += f"DETALHES DOS TESTES\n"
|
|
336
|
+
report += f"{'='*60}\n\n"
|
|
337
|
+
|
|
338
|
+
for test in results['tests']:
|
|
339
|
+
report += f"🔹 {test['test'].upper()}\n"
|
|
340
|
+
report += f" Severidade: {test.get('severity', 'N/A')}\n"
|
|
341
|
+
report += f" Vulnerabilidades: {test.get('vulnerabilities_found', 0)}\n\n"
|
|
342
|
+
|
|
343
|
+
return report
|
|
344
|
+
|
|
345
|
+
|
|
346
|
+
def main():
|
|
347
|
+
parser = argparse.ArgumentParser(description='Pentesting Agent - Testes de Segurança')
|
|
348
|
+
parser.add_argument('--target', required=True, help='URL do target')
|
|
349
|
+
parser.add_argument('--config', help='Arquivo de configuração JSON')
|
|
350
|
+
parser.add_argument('--output', help='Arquivo de saída para relatório')
|
|
351
|
+
|
|
352
|
+
args = parser.parse_args()
|
|
353
|
+
|
|
354
|
+
# Carregar configuração
|
|
355
|
+
if args.config and os.path.exists(args.config):
|
|
356
|
+
with open(args.config, 'r') as f:
|
|
357
|
+
config = json.load(f)
|
|
358
|
+
else:
|
|
359
|
+
config = {
|
|
360
|
+
'test_sql_injection': True,
|
|
361
|
+
'test_xss': True,
|
|
362
|
+
'test_passwords': True,
|
|
363
|
+
'test_headers': True
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
# Executar testes
|
|
367
|
+
agent = PentestingAgent(args.target)
|
|
368
|
+
results = agent.run_all_tests(config)
|
|
369
|
+
|
|
370
|
+
# Gerar relatório
|
|
371
|
+
report = agent.generate_report(results)
|
|
372
|
+
print(report)
|
|
373
|
+
|
|
374
|
+
# Salvar relatório
|
|
375
|
+
if args.output:
|
|
376
|
+
with open(args.output, 'w') as f:
|
|
377
|
+
f.write(report)
|
|
378
|
+
|
|
379
|
+
# Retornar JSON para integração
|
|
380
|
+
print("\n" + json.dumps(results, indent=2))
|
|
381
|
+
|
|
382
|
+
# Exit code baseado em vulnerabilidades
|
|
383
|
+
sys.exit(1 if results['summary']['total_vulnerabilities'] > 0 else 0)
|
|
384
|
+
|
|
385
|
+
|
|
386
|
+
if __name__ == '__main__':
|
|
387
|
+
main()
|
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Python Bridge - Ponte de comunicação TypeScript ↔ Python
|
|
3
|
+
*
|
|
4
|
+
* Responsável por executar o agente Python de pentesting
|
|
5
|
+
* e retornar resultados para o orquestrador TypeScript
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { spawn } from 'child_process';
|
|
9
|
+
import * as path from 'path';
|
|
10
|
+
import * as fs from 'fs';
|
|
11
|
+
|
|
12
|
+
export interface PentestConfig {
|
|
13
|
+
target: string;
|
|
14
|
+
testSqlInjection?: boolean;
|
|
15
|
+
testXss?: boolean;
|
|
16
|
+
testPasswords?: boolean;
|
|
17
|
+
testHeaders?: boolean;
|
|
18
|
+
endpoints?: string[];
|
|
19
|
+
inputs?: string[];
|
|
20
|
+
loginEndpoint?: string;
|
|
21
|
+
usernames?: string[];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface PentestResult {
|
|
25
|
+
target: string;
|
|
26
|
+
timestamp: string;
|
|
27
|
+
tests: Array<{
|
|
28
|
+
test: string;
|
|
29
|
+
severity: string;
|
|
30
|
+
vulnerabilities_found: number;
|
|
31
|
+
details: any[];
|
|
32
|
+
}>;
|
|
33
|
+
summary: {
|
|
34
|
+
total_tests: number;
|
|
35
|
+
total_vulnerabilities: number;
|
|
36
|
+
critical_vulnerabilities: number;
|
|
37
|
+
status: 'VULNERABLE' | 'SECURE';
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export class PythonBridge {
|
|
42
|
+
private pythonPath: string;
|
|
43
|
+
private agentPath: string;
|
|
44
|
+
|
|
45
|
+
constructor() {
|
|
46
|
+
this.pythonPath = 'python'; // ou 'python3' dependendo do sistema
|
|
47
|
+
this.agentPath = path.join(__dirname, 'pentesting-agent.py');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Executa testes de pentesting
|
|
52
|
+
*/
|
|
53
|
+
async executePentesting(config: PentestConfig): Promise<PentestResult> {
|
|
54
|
+
// Criar arquivo de configuração temporário
|
|
55
|
+
const configPath = path.join(__dirname, 'temp-config.json');
|
|
56
|
+
fs.writeFileSync(configPath, JSON.stringify({
|
|
57
|
+
test_sql_injection: config.testSqlInjection ?? true,
|
|
58
|
+
test_xss: config.testXss ?? true,
|
|
59
|
+
test_passwords: config.testPasswords ?? true,
|
|
60
|
+
test_headers: config.testHeaders ?? true,
|
|
61
|
+
endpoints: config.endpoints ?? ['/api/users', '/api/posts'],
|
|
62
|
+
inputs: config.inputs ?? ['username', 'email', 'comment'],
|
|
63
|
+
login_endpoint: config.loginEndpoint ?? '/api/login',
|
|
64
|
+
usernames: config.usernames ?? ['admin', 'user', 'test']
|
|
65
|
+
}));
|
|
66
|
+
|
|
67
|
+
return new Promise((resolve, reject) => {
|
|
68
|
+
const args = [
|
|
69
|
+
this.agentPath,
|
|
70
|
+
'--target', config.target,
|
|
71
|
+
'--config', configPath
|
|
72
|
+
];
|
|
73
|
+
|
|
74
|
+
console.log(`\n🐍 Executando agente Python de pentesting...`);
|
|
75
|
+
console.log(` Comando: ${this.pythonPath} ${args.join(' ')}\n`);
|
|
76
|
+
|
|
77
|
+
const python = spawn(this.pythonPath, args);
|
|
78
|
+
|
|
79
|
+
let stdout = '';
|
|
80
|
+
let stderr = '';
|
|
81
|
+
let jsonOutput = '';
|
|
82
|
+
let inJsonSection = false;
|
|
83
|
+
|
|
84
|
+
python.stdout.on('data', (data) => {
|
|
85
|
+
const output = data.toString();
|
|
86
|
+
stdout += output;
|
|
87
|
+
|
|
88
|
+
// Detectar início do JSON
|
|
89
|
+
if (output.includes('{')) {
|
|
90
|
+
inJsonSection = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (inJsonSection) {
|
|
94
|
+
jsonOutput += output;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Mostrar output em tempo real (exceto JSON)
|
|
98
|
+
if (!inJsonSection) {
|
|
99
|
+
process.stdout.write(output);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
python.stderr.on('data', (data) => {
|
|
104
|
+
stderr += data.toString();
|
|
105
|
+
process.stderr.write(data);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
python.on('close', (code) => {
|
|
109
|
+
// Limpar arquivo temporário
|
|
110
|
+
try {
|
|
111
|
+
fs.unlinkSync(configPath);
|
|
112
|
+
} catch (e) {
|
|
113
|
+
// Ignorar erro
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
if (code === null || code === 0 || code === 1) {
|
|
117
|
+
// Code 1 é esperado quando vulnerabilidades são encontradas
|
|
118
|
+
try {
|
|
119
|
+
// Extrair JSON do output
|
|
120
|
+
const jsonMatch = jsonOutput.match(/\{[\s\S]*\}/);
|
|
121
|
+
if (jsonMatch) {
|
|
122
|
+
const result = JSON.parse(jsonMatch[0]);
|
|
123
|
+
resolve(result);
|
|
124
|
+
} else {
|
|
125
|
+
reject(new Error('Não foi possível extrair JSON do output'));
|
|
126
|
+
}
|
|
127
|
+
} catch (error) {
|
|
128
|
+
reject(new Error(`Erro ao parsear JSON: ${error}`));
|
|
129
|
+
}
|
|
130
|
+
} else {
|
|
131
|
+
reject(new Error(`Python process exited with code ${code}\nStderr: ${stderr}`));
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
python.on('error', (error) => {
|
|
136
|
+
reject(new Error(`Erro ao executar Python: ${error.message}`));
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Verifica se Python está instalado
|
|
143
|
+
*/
|
|
144
|
+
async checkPythonInstalled(): Promise<boolean> {
|
|
145
|
+
return new Promise((resolve) => {
|
|
146
|
+
const python = spawn(this.pythonPath, ['--version']);
|
|
147
|
+
|
|
148
|
+
python.on('close', (code) => {
|
|
149
|
+
resolve(code === 0);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
python.on('error', () => {
|
|
153
|
+
resolve(false);
|
|
154
|
+
});
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/**
|
|
159
|
+
* Converte resultado de pentesting para formato do agente
|
|
160
|
+
*/
|
|
161
|
+
convertToAgentResult(pentestResult: PentestResult): {
|
|
162
|
+
success: boolean;
|
|
163
|
+
details: string;
|
|
164
|
+
issues?: string[];
|
|
165
|
+
warnings?: string[];
|
|
166
|
+
} {
|
|
167
|
+
const success = pentestResult.summary.status === 'SECURE';
|
|
168
|
+
|
|
169
|
+
const issues: string[] = [];
|
|
170
|
+
const warnings: string[] = [];
|
|
171
|
+
|
|
172
|
+
for (const test of pentestResult.tests) {
|
|
173
|
+
if (test.vulnerabilities_found > 0) {
|
|
174
|
+
const message = `${test.test}: ${test.vulnerabilities_found} vulnerabilidade(s) encontrada(s)`;
|
|
175
|
+
|
|
176
|
+
if (test.severity === 'CRITICAL') {
|
|
177
|
+
issues.push(message);
|
|
178
|
+
} else {
|
|
179
|
+
warnings.push(message);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const details = `Pentesting concluído: ${pentestResult.summary.total_vulnerabilities} vulnerabilidade(s) encontrada(s)`;
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
success,
|
|
188
|
+
details,
|
|
189
|
+
issues: issues.length > 0 ? issues : undefined,
|
|
190
|
+
warnings: warnings.length > 0 ? warnings : undefined
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|