erosolar-cli 2.1.243 → 2.1.244
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/dist/capabilities/index.d.ts +1 -0
- package/dist/capabilities/index.d.ts.map +1 -1
- package/dist/capabilities/index.js +1 -0
- package/dist/capabilities/index.js.map +1 -1
- package/dist/capabilities/unifiedInvestigationCapability.d.ts +22 -0
- package/dist/capabilities/unifiedInvestigationCapability.d.ts.map +1 -0
- package/dist/capabilities/unifiedInvestigationCapability.js +41 -0
- package/dist/capabilities/unifiedInvestigationCapability.js.map +1 -0
- package/dist/core/agentOrchestrator.d.ts +130 -1
- package/dist/core/agentOrchestrator.d.ts.map +1 -1
- package/dist/core/agentOrchestrator.js +553 -1
- package/dist/core/agentOrchestrator.js.map +1 -1
- package/dist/core/unifiedFraudOrchestrator.d.ts +542 -0
- package/dist/core/unifiedFraudOrchestrator.d.ts.map +1 -0
- package/dist/core/unifiedFraudOrchestrator.js +1449 -0
- package/dist/core/unifiedFraudOrchestrator.js.map +1 -0
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +2 -0
- package/dist/plugins/tools/nodeDefaults.js.map +1 -1
- package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.d.ts +3 -0
- package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.js +14 -0
- package/dist/plugins/tools/unifiedInvestigation/unifiedInvestigationPlugin.js.map +1 -0
- package/dist/tools/taoTools.d.ts.map +1 -1
- package/dist/tools/taoTools.js +790 -4
- package/dist/tools/taoTools.js.map +1 -1
- package/dist/tools/unifiedInvestigationTools.d.ts +19 -0
- package/dist/tools/unifiedInvestigationTools.d.ts.map +1 -0
- package/dist/tools/unifiedInvestigationTools.js +851 -0
- package/dist/tools/unifiedInvestigationTools.js.map +1 -0
- package/package.json +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { TASK_FULLY_COMPLETE } from './constants.js';
|
|
2
2
|
import { TaskCompletionDetector } from './taskCompletionDetector.js';
|
|
3
|
-
import { planAttackChain, selectNextTechnique, executeTechniqueInChain, techniqueRegistry, parseNaturalLanguageIntent, validateAuthorizationContext, } from '../tools/tao/index.js';
|
|
3
|
+
import { planAttackChain, selectNextTechnique, executeTechniqueInChain, techniqueRegistry, parseNaturalLanguageIntent, validateAuthorizationContext, getRLState, listActiveChains, } from '../tools/tao/index.js';
|
|
4
|
+
import { getInfrastructureStack, generateDeploymentScript, generateTeardownScript, generateOpsecChecklist, } from './infrastructureTemplates.js';
|
|
5
|
+
import { getAgencyContacts, getApplicableLegalFrameworks, } from './governmentProcedures.js';
|
|
4
6
|
/**
|
|
5
7
|
* Single-pass orchestration: drive the agent to finish as much as possible
|
|
6
8
|
* in one go, with strong bias toward real actions over planning.
|
|
@@ -1200,5 +1202,555 @@ Please provide context so I can help appropriately.`,
|
|
|
1200
1202
|
}
|
|
1201
1203
|
return lines.join('\n');
|
|
1202
1204
|
}
|
|
1205
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1206
|
+
// UNIFIED ORCHESTRATION - FULL STACK INTEGRATION
|
|
1207
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1208
|
+
/** Goal-to-technique mapping for goal-oriented execution */
|
|
1209
|
+
goalTechniques = {
|
|
1210
|
+
reconnaissance: [
|
|
1211
|
+
'dns_enum', 'whois_recon', 'asn_lookup', 'subdomain_enum', 'dns_zone_transfer',
|
|
1212
|
+
'ssl_analysis', 'ct_search', 'web_fingerprint', 'tech_fingerprint',
|
|
1213
|
+
'cloud_detect', 's3_enum', 'gcs_enum', 'azure_enum', 'email_security',
|
|
1214
|
+
'port_scan', 'service_enum', 'api_discovery', 'git_analysis',
|
|
1215
|
+
],
|
|
1216
|
+
access: [
|
|
1217
|
+
'credential_spray', 'exploit_attempt', 'cloud_metadata', 'container_escape',
|
|
1218
|
+
],
|
|
1219
|
+
persistence: [
|
|
1220
|
+
'persistence', 'sched_persist', 'ssh_persist', 'c2_beacon',
|
|
1221
|
+
],
|
|
1222
|
+
privilege: [
|
|
1223
|
+
'privesc', 'credential_harvest', 'memory_dump', 'cloud_creds',
|
|
1224
|
+
],
|
|
1225
|
+
lateral: [
|
|
1226
|
+
'lateral_move', 'network_discovery', 'smb_enum', 'ssh_enum',
|
|
1227
|
+
],
|
|
1228
|
+
collection: [
|
|
1229
|
+
'file_discovery', 'data_discovery', 'process_enum', 'cloud_enum',
|
|
1230
|
+
'credential_harvest', 'git_analysis', 'api_surface_map',
|
|
1231
|
+
],
|
|
1232
|
+
exfiltration: [
|
|
1233
|
+
'data_staging', 'exfil', 'c2_beacon',
|
|
1234
|
+
],
|
|
1235
|
+
impact: [
|
|
1236
|
+
'service_disruption', 'resource_exhaustion', 'cleanup',
|
|
1237
|
+
],
|
|
1238
|
+
stealth: [
|
|
1239
|
+
'cleanup', 'process_enum', 'network_discovery',
|
|
1240
|
+
],
|
|
1241
|
+
all: [], // Dynamically populated
|
|
1242
|
+
};
|
|
1243
|
+
/**
|
|
1244
|
+
* Unified orchestration entry point.
|
|
1245
|
+
* Routes to appropriate execution strategy based on mode and options.
|
|
1246
|
+
*
|
|
1247
|
+
* This is the primary method for full-stack unified orchestration that
|
|
1248
|
+
* combines LLM-driven orchestration with direct TAO technique execution,
|
|
1249
|
+
* infrastructure deployment, and goal-oriented APT simulation.
|
|
1250
|
+
*/
|
|
1251
|
+
async runUnified(request, options = {}) {
|
|
1252
|
+
const mode = options.unifiedMode || this.detectMode(request, options);
|
|
1253
|
+
switch (mode) {
|
|
1254
|
+
case 'attack-chain':
|
|
1255
|
+
return this.runWithAttackChain(request, options);
|
|
1256
|
+
case 'apt-simulation':
|
|
1257
|
+
return this.runAPTSimulation(request, options);
|
|
1258
|
+
case 'infrastructure':
|
|
1259
|
+
return this.runInfrastructureMode(request, options);
|
|
1260
|
+
case 'red-team':
|
|
1261
|
+
return this.runRedTeamMode(request, options);
|
|
1262
|
+
case 'intel-collection':
|
|
1263
|
+
return this.runIntelCollectionMode(request, options);
|
|
1264
|
+
case 'compliance':
|
|
1265
|
+
return this.runComplianceMode(request, options);
|
|
1266
|
+
case 'standard':
|
|
1267
|
+
default:
|
|
1268
|
+
// Check for goal-oriented execution
|
|
1269
|
+
if (options.goal || options.goals) {
|
|
1270
|
+
return this.runGoalOriented(request, options);
|
|
1271
|
+
}
|
|
1272
|
+
return this.runToCompletion(request, options);
|
|
1273
|
+
}
|
|
1274
|
+
}
|
|
1275
|
+
/**
|
|
1276
|
+
* Auto-detect the appropriate orchestration mode from request content.
|
|
1277
|
+
*/
|
|
1278
|
+
detectMode(request, options) {
|
|
1279
|
+
const lower = request.toLowerCase();
|
|
1280
|
+
// Check for explicit goals first
|
|
1281
|
+
if (options.goal || options.goals) {
|
|
1282
|
+
return 'attack-chain';
|
|
1283
|
+
}
|
|
1284
|
+
// Infrastructure keywords
|
|
1285
|
+
if (lower.includes('infrastructure') || lower.includes('deploy') ||
|
|
1286
|
+
lower.includes('c2 server') || lower.includes('redirector')) {
|
|
1287
|
+
return 'infrastructure';
|
|
1288
|
+
}
|
|
1289
|
+
// Compliance keywords
|
|
1290
|
+
if (lower.includes('compliance') || lower.includes('audit') ||
|
|
1291
|
+
lower.includes('legal') || lower.includes('framework')) {
|
|
1292
|
+
return 'compliance';
|
|
1293
|
+
}
|
|
1294
|
+
// Intel collection keywords
|
|
1295
|
+
if (lower.includes('intelligence') || lower.includes('osint') ||
|
|
1296
|
+
lower.includes('gather') || lower.includes('collect')) {
|
|
1297
|
+
return 'intel-collection';
|
|
1298
|
+
}
|
|
1299
|
+
// Red team keywords
|
|
1300
|
+
if (lower.includes('red team') || lower.includes('adversary') ||
|
|
1301
|
+
lower.includes('full simulation')) {
|
|
1302
|
+
return 'red-team';
|
|
1303
|
+
}
|
|
1304
|
+
// APT simulation keywords
|
|
1305
|
+
if (lower.includes('apt') || lower.includes('kill chain') ||
|
|
1306
|
+
lower.includes('kill-chain') || lower.includes('attack chain')) {
|
|
1307
|
+
return 'apt-simulation';
|
|
1308
|
+
}
|
|
1309
|
+
// Security operation keywords (attack chain)
|
|
1310
|
+
const securityKeywords = ['scan', 'recon', 'enumerate', 'exploit', 'pentest', 'hack'];
|
|
1311
|
+
if (securityKeywords.some(kw => lower.includes(kw))) {
|
|
1312
|
+
return 'attack-chain';
|
|
1313
|
+
}
|
|
1314
|
+
return 'standard';
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Run full APT simulation with all kill-chain phases.
|
|
1318
|
+
*/
|
|
1319
|
+
async runAPTSimulation(request, options) {
|
|
1320
|
+
const startTime = Date.now();
|
|
1321
|
+
const intent = parseNaturalLanguageIntent(request);
|
|
1322
|
+
const targets = options.attackTargets ?? intent.targets;
|
|
1323
|
+
const depth = this.normalizeDepth(options.attackDepth ?? intent.depth);
|
|
1324
|
+
const stealth = options.stealthMode ?? intent.constraints.includes('stealth');
|
|
1325
|
+
// Validate authorization
|
|
1326
|
+
const auth = this.validateAttackAuthorization(intent, options.authorizationContext);
|
|
1327
|
+
if (!auth.authorized) {
|
|
1328
|
+
return this.buildAuthorizationError(auth);
|
|
1329
|
+
}
|
|
1330
|
+
const realExecutions = [];
|
|
1331
|
+
const completedPhases = new Set();
|
|
1332
|
+
const allArtifacts = [];
|
|
1333
|
+
// APT Kill Chain Phases
|
|
1334
|
+
const killChainPhases = [
|
|
1335
|
+
'reconnaissance',
|
|
1336
|
+
'weaponization',
|
|
1337
|
+
'delivery',
|
|
1338
|
+
'exploitation',
|
|
1339
|
+
'installation',
|
|
1340
|
+
'command-control',
|
|
1341
|
+
'actions-on-objectives',
|
|
1342
|
+
];
|
|
1343
|
+
// Execute techniques for each target
|
|
1344
|
+
for (const target of targets) {
|
|
1345
|
+
const chain = planAttackChain(intent, `APT Simulation: ${target}`);
|
|
1346
|
+
for (const phase of killChainPhases) {
|
|
1347
|
+
const phaseTechniques = techniqueRegistry.getByPhase(phase);
|
|
1348
|
+
const techniqueLimit = depth === 'quick' ? 2 : depth === 'standard' ? 4 : phaseTechniques.length;
|
|
1349
|
+
for (const technique of phaseTechniques.slice(0, techniqueLimit)) {
|
|
1350
|
+
if (stealth && technique.stealthRating < 0.3)
|
|
1351
|
+
continue;
|
|
1352
|
+
options.onTechniqueStart?.(technique.id, target);
|
|
1353
|
+
try {
|
|
1354
|
+
const result = await technique.execute({
|
|
1355
|
+
target,
|
|
1356
|
+
depth,
|
|
1357
|
+
stealth,
|
|
1358
|
+
timeout: depth === 'deep' ? 60000 : 30000,
|
|
1359
|
+
context: { chainId: chain.id, phase },
|
|
1360
|
+
});
|
|
1361
|
+
const execResult = {
|
|
1362
|
+
techniqueId: technique.id,
|
|
1363
|
+
techniqueName: technique.name,
|
|
1364
|
+
phase,
|
|
1365
|
+
success: result.success,
|
|
1366
|
+
duration: result.duration,
|
|
1367
|
+
artifacts: result.artifacts,
|
|
1368
|
+
detectionRisk: result.detectionRisk,
|
|
1369
|
+
nextTechniques: result.nextTechniques,
|
|
1370
|
+
};
|
|
1371
|
+
realExecutions.push(execResult);
|
|
1372
|
+
allArtifacts.push(...result.artifacts);
|
|
1373
|
+
options.onTechniqueComplete?.(execResult);
|
|
1374
|
+
if (result.success) {
|
|
1375
|
+
completedPhases.add(phase);
|
|
1376
|
+
}
|
|
1377
|
+
// Stealth abort if detection risk too high
|
|
1378
|
+
if (stealth && result.detectionRisk > 0.7)
|
|
1379
|
+
break;
|
|
1380
|
+
}
|
|
1381
|
+
catch {
|
|
1382
|
+
realExecutions.push({
|
|
1383
|
+
techniqueId: technique.id,
|
|
1384
|
+
techniqueName: technique.name,
|
|
1385
|
+
phase,
|
|
1386
|
+
success: false,
|
|
1387
|
+
duration: 0,
|
|
1388
|
+
artifacts: [],
|
|
1389
|
+
detectionRisk: 0.5,
|
|
1390
|
+
nextTechniques: [],
|
|
1391
|
+
});
|
|
1392
|
+
}
|
|
1393
|
+
}
|
|
1394
|
+
}
|
|
1395
|
+
}
|
|
1396
|
+
const metrics = this.computeMetrics(realExecutions, startTime);
|
|
1397
|
+
return {
|
|
1398
|
+
finalResponse: this.buildExecutionSummary(realExecutions, metrics, 'APT Simulation'),
|
|
1399
|
+
toolsUsed: realExecutions.map(r => `tao:${r.techniqueId}`),
|
|
1400
|
+
planOnly: false,
|
|
1401
|
+
tookAction: true,
|
|
1402
|
+
completion: this.buildCompletionAnalysis(metrics),
|
|
1403
|
+
exitReason: metrics.successfulTechniques > 0 ? 'attack-chain-complete' : 'attack-chain-aborted',
|
|
1404
|
+
statusSummary: `APT: ${metrics.successfulTechniques}/${metrics.totalTechniquesExecuted} techniques`,
|
|
1405
|
+
limitations: [],
|
|
1406
|
+
recommendations: this.buildRecommendations(realExecutions),
|
|
1407
|
+
realExecutions,
|
|
1408
|
+
realMetrics: metrics,
|
|
1409
|
+
attackChains: listActiveChains(),
|
|
1410
|
+
attackChainPhases: Array.from(completedPhases),
|
|
1411
|
+
collectedArtifacts: allArtifacts,
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
/**
|
|
1415
|
+
* Run infrastructure deployment mode.
|
|
1416
|
+
*/
|
|
1417
|
+
async runInfrastructureMode(request, options) {
|
|
1418
|
+
const region = options.region || 'us';
|
|
1419
|
+
const stack = getInfrastructureStack(region);
|
|
1420
|
+
if (!stack) {
|
|
1421
|
+
return {
|
|
1422
|
+
finalResponse: `No infrastructure stack available for region: ${region}`,
|
|
1423
|
+
toolsUsed: [],
|
|
1424
|
+
planOnly: false,
|
|
1425
|
+
tookAction: false,
|
|
1426
|
+
completion: this.buildCompletionAnalysis({ totalTechniquesExecuted: 0, successfulTechniques: 0, failedTechniques: 0, totalDuration: 0, averageDetectionRisk: 0, phasesCompleted: [], artifactsCollected: 0, rlRewardAverage: 0 }),
|
|
1427
|
+
exitReason: 'incomplete',
|
|
1428
|
+
statusSummary: 'No infrastructure stack',
|
|
1429
|
+
limitations: [`Region '${region}' not supported`],
|
|
1430
|
+
recommendations: ['Use us or ukraine region'],
|
|
1431
|
+
};
|
|
1432
|
+
}
|
|
1433
|
+
const deployScript = generateDeploymentScript(stack);
|
|
1434
|
+
const teardownScript = generateTeardownScript(stack);
|
|
1435
|
+
const opsecList = generateOpsecChecklist(stack);
|
|
1436
|
+
options.onInfrastructure?.(stack);
|
|
1437
|
+
return {
|
|
1438
|
+
finalResponse: `## Infrastructure Stack: ${stack.name}\n\n` +
|
|
1439
|
+
`**Region:** ${stack.region}\n` +
|
|
1440
|
+
`**Components:** ${stack.components.length}\n` +
|
|
1441
|
+
`**Persistence Mechanisms:** ${stack.persistence.length}\n` +
|
|
1442
|
+
`**Monthly Cost:** $${stack.costEstimate.monthly}\n\n` +
|
|
1443
|
+
`### Components\n${stack.components.map(c => `- ${c.name} (${c.type})`).join('\n')}\n\n` +
|
|
1444
|
+
`### Deployment Script Generated\n### Teardown Script Generated\n### OPSEC Checklist Generated`,
|
|
1445
|
+
toolsUsed: ['infrastructure-deploy', 'script-generator'],
|
|
1446
|
+
planOnly: false,
|
|
1447
|
+
tookAction: true,
|
|
1448
|
+
completion: this.buildCompletionAnalysis({ totalTechniquesExecuted: 1, successfulTechniques: 1, failedTechniques: 0, totalDuration: 0, averageDetectionRisk: 0, phasesCompleted: [], artifactsCollected: 0, rlRewardAverage: 0 }),
|
|
1449
|
+
exitReason: 'complete',
|
|
1450
|
+
statusSummary: `Infrastructure: ${stack.components.length} components`,
|
|
1451
|
+
limitations: [],
|
|
1452
|
+
recommendations: ['Review OPSEC checklist before deployment'],
|
|
1453
|
+
infrastructureStack: stack,
|
|
1454
|
+
deploymentScript: deployScript,
|
|
1455
|
+
teardownScript: teardownScript,
|
|
1456
|
+
opsecChecklist: opsecList,
|
|
1457
|
+
};
|
|
1458
|
+
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Run combined red team mode.
|
|
1461
|
+
*/
|
|
1462
|
+
async runRedTeamMode(request, options) {
|
|
1463
|
+
// Red team combines infrastructure + APT simulation
|
|
1464
|
+
const infraResult = await this.runInfrastructureMode(request, options);
|
|
1465
|
+
const aptResult = await this.runAPTSimulation(request, {
|
|
1466
|
+
...options,
|
|
1467
|
+
attackDepth: 'deep',
|
|
1468
|
+
stealthMode: true,
|
|
1469
|
+
});
|
|
1470
|
+
return {
|
|
1471
|
+
...aptResult,
|
|
1472
|
+
finalResponse: `## Red Team Operation\n\n${infraResult.finalResponse}\n\n---\n\n${aptResult.finalResponse}`,
|
|
1473
|
+
toolsUsed: [...infraResult.toolsUsed, ...aptResult.toolsUsed],
|
|
1474
|
+
infrastructureStack: infraResult.infrastructureStack,
|
|
1475
|
+
deploymentScript: infraResult.deploymentScript,
|
|
1476
|
+
teardownScript: infraResult.teardownScript,
|
|
1477
|
+
opsecChecklist: infraResult.opsecChecklist,
|
|
1478
|
+
statusSummary: `Red Team: ${aptResult.realMetrics?.successfulTechniques || 0} techniques + ${infraResult.infrastructureStack?.components.length || 0} infra components`,
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Run intelligence collection mode.
|
|
1483
|
+
*/
|
|
1484
|
+
async runIntelCollectionMode(request, options) {
|
|
1485
|
+
return this.runGoalOriented(request, {
|
|
1486
|
+
...options,
|
|
1487
|
+
goals: ['reconnaissance', 'collection'],
|
|
1488
|
+
collectIntel: true,
|
|
1489
|
+
minimizeFootprint: true,
|
|
1490
|
+
});
|
|
1491
|
+
}
|
|
1492
|
+
/**
|
|
1493
|
+
* Run compliance mode with legal frameworks.
|
|
1494
|
+
*/
|
|
1495
|
+
async runComplianceMode(request, options) {
|
|
1496
|
+
const agencyTypes = options.agencyTypes || ['federal-le', 'regulatory'];
|
|
1497
|
+
const contacts = agencyTypes.flatMap(at => getAgencyContacts(at));
|
|
1498
|
+
const frameworks = getApplicableLegalFrameworks(agencyTypes);
|
|
1499
|
+
const response = `## Compliance Analysis\n\n` +
|
|
1500
|
+
`### Applicable Legal Frameworks\n` +
|
|
1501
|
+
frameworks.map(f => `- **${f.name}** (${f.jurisdiction})\n Requirements: ${f.requirements.length}`).join('\n') +
|
|
1502
|
+
`\n\n### Agency Contacts\n` +
|
|
1503
|
+
contacts.map(c => `- **${c.agency}** - ${c.division}\n Contact: ${c.contact.email}`).join('\n');
|
|
1504
|
+
return {
|
|
1505
|
+
finalResponse: response,
|
|
1506
|
+
toolsUsed: ['compliance-check'],
|
|
1507
|
+
planOnly: false,
|
|
1508
|
+
tookAction: true,
|
|
1509
|
+
completion: this.buildCompletionAnalysis({ totalTechniquesExecuted: 1, successfulTechniques: 1, failedTechniques: 0, totalDuration: 0, averageDetectionRisk: 0, phasesCompleted: [], artifactsCollected: 0, rlRewardAverage: 0 }),
|
|
1510
|
+
exitReason: 'complete',
|
|
1511
|
+
statusSummary: `Compliance: ${frameworks.length} frameworks`,
|
|
1512
|
+
limitations: [],
|
|
1513
|
+
recommendations: frameworks.flatMap(f => f.requirements.map(r => r.requirement)),
|
|
1514
|
+
};
|
|
1515
|
+
}
|
|
1516
|
+
/**
|
|
1517
|
+
* Run goal-oriented APT execution.
|
|
1518
|
+
*/
|
|
1519
|
+
async runGoalOriented(request, options) {
|
|
1520
|
+
const startTime = Date.now();
|
|
1521
|
+
const goals = options.goals || (options.goal ? [options.goal] : ['reconnaissance']);
|
|
1522
|
+
const targets = options.attackTargets || [];
|
|
1523
|
+
const depth = this.normalizeDepth(options.attackDepth ?? 'standard');
|
|
1524
|
+
const stealth = options.stealthMode ?? options.minimizeFootprint ?? false;
|
|
1525
|
+
// Build technique list from goals
|
|
1526
|
+
let techniques = [];
|
|
1527
|
+
for (const goal of goals) {
|
|
1528
|
+
if (goal === 'all') {
|
|
1529
|
+
techniques = techniqueRegistry.list().map(t => t.id);
|
|
1530
|
+
break;
|
|
1531
|
+
}
|
|
1532
|
+
techniques.push(...(this.goalTechniques[goal] || []));
|
|
1533
|
+
}
|
|
1534
|
+
techniques = [...new Set(techniques)];
|
|
1535
|
+
const realExecutions = [];
|
|
1536
|
+
const achievedGoals = [];
|
|
1537
|
+
const allArtifacts = [];
|
|
1538
|
+
// Execute techniques
|
|
1539
|
+
for (const target of targets) {
|
|
1540
|
+
for (const techniqueId of techniques) {
|
|
1541
|
+
const technique = techniqueRegistry.get(techniqueId);
|
|
1542
|
+
if (!technique)
|
|
1543
|
+
continue;
|
|
1544
|
+
if (stealth && technique.stealthRating < 0.3)
|
|
1545
|
+
continue;
|
|
1546
|
+
options.onTechniqueStart?.(techniqueId, target);
|
|
1547
|
+
try {
|
|
1548
|
+
const result = await technique.execute({
|
|
1549
|
+
target,
|
|
1550
|
+
depth,
|
|
1551
|
+
stealth,
|
|
1552
|
+
timeout: 60000,
|
|
1553
|
+
context: {},
|
|
1554
|
+
});
|
|
1555
|
+
const execResult = {
|
|
1556
|
+
techniqueId: technique.id,
|
|
1557
|
+
techniqueName: technique.name,
|
|
1558
|
+
phase: technique.phase,
|
|
1559
|
+
success: result.success,
|
|
1560
|
+
duration: result.duration,
|
|
1561
|
+
artifacts: result.artifacts,
|
|
1562
|
+
detectionRisk: result.detectionRisk,
|
|
1563
|
+
nextTechniques: result.nextTechniques,
|
|
1564
|
+
};
|
|
1565
|
+
realExecutions.push(execResult);
|
|
1566
|
+
allArtifacts.push(...result.artifacts);
|
|
1567
|
+
options.onTechniqueComplete?.(execResult);
|
|
1568
|
+
// Check goal achievement
|
|
1569
|
+
for (const goal of goals) {
|
|
1570
|
+
if (!achievedGoals.includes(goal)) {
|
|
1571
|
+
const goalTechs = this.goalTechniques[goal] || [];
|
|
1572
|
+
if (goalTechs.includes(techniqueId) && result.success) {
|
|
1573
|
+
achievedGoals.push(goal);
|
|
1574
|
+
options.onGoalAchieved?.(goal, result.artifacts);
|
|
1575
|
+
}
|
|
1576
|
+
}
|
|
1577
|
+
}
|
|
1578
|
+
if (stealth && result.detectionRisk > 0.7)
|
|
1579
|
+
break;
|
|
1580
|
+
}
|
|
1581
|
+
catch {
|
|
1582
|
+
realExecutions.push({
|
|
1583
|
+
techniqueId: technique.id,
|
|
1584
|
+
techniqueName: technique.name,
|
|
1585
|
+
phase: technique.phase,
|
|
1586
|
+
success: false,
|
|
1587
|
+
duration: 0,
|
|
1588
|
+
artifacts: [],
|
|
1589
|
+
detectionRisk: 0.5,
|
|
1590
|
+
nextTechniques: [],
|
|
1591
|
+
});
|
|
1592
|
+
}
|
|
1593
|
+
}
|
|
1594
|
+
// Maintain persistence if requested
|
|
1595
|
+
if (options.maintainAccess) {
|
|
1596
|
+
for (const persistTech of ['persistence', 'sched_persist', 'ssh_persist']) {
|
|
1597
|
+
const technique = techniqueRegistry.get(persistTech);
|
|
1598
|
+
if (technique) {
|
|
1599
|
+
try {
|
|
1600
|
+
await technique.execute({ target, depth, stealth, timeout: 30000, context: {} });
|
|
1601
|
+
}
|
|
1602
|
+
catch { /* ignore */ }
|
|
1603
|
+
}
|
|
1604
|
+
}
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
const metrics = this.computeMetrics(realExecutions, startTime);
|
|
1608
|
+
return {
|
|
1609
|
+
finalResponse: this.buildExecutionSummary(realExecutions, metrics, `Goal-Oriented: ${goals.join(', ')}`),
|
|
1610
|
+
toolsUsed: realExecutions.map(r => r.techniqueId),
|
|
1611
|
+
planOnly: false,
|
|
1612
|
+
tookAction: true,
|
|
1613
|
+
completion: this.buildCompletionAnalysis(metrics),
|
|
1614
|
+
exitReason: metrics.successfulTechniques > 0 ? 'attack-chain-complete' : 'attack-chain-aborted',
|
|
1615
|
+
statusSummary: `Goals: ${achievedGoals.length}/${goals.length} achieved`,
|
|
1616
|
+
limitations: [],
|
|
1617
|
+
recommendations: this.buildRecommendations(realExecutions),
|
|
1618
|
+
realExecutions,
|
|
1619
|
+
realMetrics: metrics,
|
|
1620
|
+
attackChains: listActiveChains(),
|
|
1621
|
+
achievedGoals,
|
|
1622
|
+
collectedArtifacts: allArtifacts,
|
|
1623
|
+
};
|
|
1624
|
+
}
|
|
1625
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1626
|
+
// HELPER METHODS
|
|
1627
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
1628
|
+
normalizeDepth(depth) {
|
|
1629
|
+
if (depth === 'quick' || depth === 'standard' || depth === 'deep') {
|
|
1630
|
+
return depth;
|
|
1631
|
+
}
|
|
1632
|
+
return 'standard';
|
|
1633
|
+
}
|
|
1634
|
+
computeMetrics(executions, startTime) {
|
|
1635
|
+
const successful = executions.filter(e => e.success).length;
|
|
1636
|
+
const rlState = getRLState();
|
|
1637
|
+
return {
|
|
1638
|
+
totalTechniquesExecuted: executions.length,
|
|
1639
|
+
successfulTechniques: successful,
|
|
1640
|
+
failedTechniques: executions.length - successful,
|
|
1641
|
+
totalDuration: Date.now() - startTime,
|
|
1642
|
+
averageDetectionRisk: executions.length > 0
|
|
1643
|
+
? executions.reduce((s, e) => s + e.detectionRisk, 0) / executions.length
|
|
1644
|
+
: 0,
|
|
1645
|
+
phasesCompleted: [...new Set(executions.filter(e => e.success).map(e => e.phase))],
|
|
1646
|
+
artifactsCollected: executions.reduce((s, e) => s + e.artifacts.length, 0),
|
|
1647
|
+
rlRewardAverage: rlState.avgReward,
|
|
1648
|
+
};
|
|
1649
|
+
}
|
|
1650
|
+
buildCompletionAnalysis(metrics) {
|
|
1651
|
+
const confidence = metrics.totalTechniquesExecuted > 0
|
|
1652
|
+
? metrics.successfulTechniques / metrics.totalTechniquesExecuted
|
|
1653
|
+
: 0;
|
|
1654
|
+
return {
|
|
1655
|
+
isComplete: true,
|
|
1656
|
+
confidence,
|
|
1657
|
+
signals: {
|
|
1658
|
+
hasExplicitCompletionStatement: true,
|
|
1659
|
+
hasIncompleteWorkIndicators: false,
|
|
1660
|
+
hasPendingActionIndicators: false,
|
|
1661
|
+
hasErrorIndicators: metrics.failedTechniques > metrics.successfulTechniques,
|
|
1662
|
+
hasFollowUpQuestions: false,
|
|
1663
|
+
toolsUsedInLastResponse: metrics.totalTechniquesExecuted,
|
|
1664
|
+
lastToolWasReadOnly: false,
|
|
1665
|
+
consecutiveResponsesWithoutTools: 0,
|
|
1666
|
+
hasRecentFileWrites: false,
|
|
1667
|
+
hasRecentCommits: false,
|
|
1668
|
+
todoItemsPending: 0,
|
|
1669
|
+
todoItemsCompleted: metrics.successfulTechniques,
|
|
1670
|
+
mentionsFutureWork: false,
|
|
1671
|
+
completionConfidence: confidence,
|
|
1672
|
+
},
|
|
1673
|
+
reason: 'Unified execution complete',
|
|
1674
|
+
shouldVerify: confidence < 0.8,
|
|
1675
|
+
};
|
|
1676
|
+
}
|
|
1677
|
+
buildAuthorizationError(auth) {
|
|
1678
|
+
return {
|
|
1679
|
+
finalResponse: `## Authorization Required\n\n${auth.reason}\n\n### Warnings\n${auth.warnings.map(w => `- ${w}`).join('\n')}`,
|
|
1680
|
+
toolsUsed: [],
|
|
1681
|
+
planOnly: false,
|
|
1682
|
+
tookAction: false,
|
|
1683
|
+
completion: {
|
|
1684
|
+
isComplete: true,
|
|
1685
|
+
confidence: 1.0,
|
|
1686
|
+
signals: {
|
|
1687
|
+
hasExplicitCompletionStatement: true,
|
|
1688
|
+
hasIncompleteWorkIndicators: false,
|
|
1689
|
+
hasPendingActionIndicators: false,
|
|
1690
|
+
hasErrorIndicators: false,
|
|
1691
|
+
hasFollowUpQuestions: true,
|
|
1692
|
+
toolsUsedInLastResponse: 0,
|
|
1693
|
+
lastToolWasReadOnly: false,
|
|
1694
|
+
consecutiveResponsesWithoutTools: 0,
|
|
1695
|
+
hasRecentFileWrites: false,
|
|
1696
|
+
hasRecentCommits: false,
|
|
1697
|
+
todoItemsPending: 0,
|
|
1698
|
+
todoItemsCompleted: 0,
|
|
1699
|
+
mentionsFutureWork: false,
|
|
1700
|
+
completionConfidence: 1.0,
|
|
1701
|
+
},
|
|
1702
|
+
reason: 'Authorization required',
|
|
1703
|
+
shouldVerify: false,
|
|
1704
|
+
},
|
|
1705
|
+
exitReason: 'attack-chain-aborted',
|
|
1706
|
+
statusSummary: `Authorization required: ${auth.reason}`,
|
|
1707
|
+
limitations: auth.warnings,
|
|
1708
|
+
recommendations: [
|
|
1709
|
+
'Provide CTF/lab context',
|
|
1710
|
+
'Specify pentest authorization',
|
|
1711
|
+
'Use --auth-context flag',
|
|
1712
|
+
],
|
|
1713
|
+
};
|
|
1714
|
+
}
|
|
1715
|
+
buildExecutionSummary(executions, metrics, title) {
|
|
1716
|
+
const lines = [];
|
|
1717
|
+
lines.push(`## ${title} Execution Summary\n`);
|
|
1718
|
+
lines.push(`**Total Techniques:** ${metrics.totalTechniquesExecuted}`);
|
|
1719
|
+
lines.push(`**Successful:** ${metrics.successfulTechniques}`);
|
|
1720
|
+
lines.push(`**Failed:** ${metrics.failedTechniques}`);
|
|
1721
|
+
lines.push(`**Duration:** ${(metrics.totalDuration / 1000).toFixed(1)}s`);
|
|
1722
|
+
lines.push(`**Detection Risk:** ${(metrics.averageDetectionRisk * 100).toFixed(1)}%`);
|
|
1723
|
+
lines.push(`**Artifacts:** ${metrics.artifactsCollected}`);
|
|
1724
|
+
lines.push(`**Phases:** ${metrics.phasesCompleted.join(', ') || 'none'}`);
|
|
1725
|
+
lines.push('');
|
|
1726
|
+
lines.push(`### Technique Results\n`);
|
|
1727
|
+
for (const exec of executions) {
|
|
1728
|
+
const status = exec.success ? '✓' : '✗';
|
|
1729
|
+
lines.push(`**${status} ${exec.techniqueName}** (${exec.phase})`);
|
|
1730
|
+
lines.push(`- Duration: ${exec.duration}ms`);
|
|
1731
|
+
lines.push(`- Risk: ${(exec.detectionRisk * 100).toFixed(0)}%`);
|
|
1732
|
+
if (exec.artifacts.length > 0) {
|
|
1733
|
+
lines.push(`- Artifacts: ${exec.artifacts.length}`);
|
|
1734
|
+
}
|
|
1735
|
+
lines.push('');
|
|
1736
|
+
}
|
|
1737
|
+
return lines.join('\n');
|
|
1738
|
+
}
|
|
1739
|
+
buildRecommendations(executions) {
|
|
1740
|
+
const recommendations = [];
|
|
1741
|
+
const failed = executions.filter(e => !e.success);
|
|
1742
|
+
if (failed.length > 0) {
|
|
1743
|
+
recommendations.push(`Review ${failed.length} failed technique(s)`);
|
|
1744
|
+
}
|
|
1745
|
+
const highRisk = executions.filter(e => e.detectionRisk > 0.7);
|
|
1746
|
+
if (highRisk.length > 0) {
|
|
1747
|
+
recommendations.push(`${highRisk.length} technique(s) have high detection risk`);
|
|
1748
|
+
}
|
|
1749
|
+
const nextTechniques = [...new Set(executions.flatMap(e => e.nextTechniques))];
|
|
1750
|
+
if (nextTechniques.length > 0) {
|
|
1751
|
+
recommendations.push(`Consider: ${nextTechniques.slice(0, 5).join(', ')}`);
|
|
1752
|
+
}
|
|
1753
|
+
return recommendations;
|
|
1754
|
+
}
|
|
1203
1755
|
}
|
|
1204
1756
|
//# sourceMappingURL=agentOrchestrator.js.map
|