erosolar-cli 2.1.242 → 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/iMessageVerificationCapability.d.ts +31 -0
- package/dist/capabilities/iMessageVerificationCapability.d.ts.map +1 -0
- package/dist/capabilities/iMessageVerificationCapability.js +56 -0
- package/dist/capabilities/iMessageVerificationCapability.js.map +1 -0
- package/dist/capabilities/index.d.ts +2 -0
- package/dist/capabilities/index.d.ts.map +1 -1
- package/dist/capabilities/index.js +2 -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 +161 -1
- package/dist/core/agentOrchestrator.d.ts.map +1 -1
- package/dist/core/agentOrchestrator.js +880 -0
- package/dist/core/agentOrchestrator.js.map +1 -1
- package/dist/core/iMessageVerification.d.ts +408 -0
- package/dist/core/iMessageVerification.d.ts.map +1 -0
- package/dist/core/iMessageVerification.js +883 -0
- package/dist/core/iMessageVerification.js.map +1 -0
- package/dist/core/techFraudInvestigator.d.ts +131 -0
- package/dist/core/techFraudInvestigator.d.ts.map +1 -0
- package/dist/core/techFraudInvestigator.js +992 -0
- package/dist/core/techFraudInvestigator.js.map +1 -0
- 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/imessageVerification/iMessageVerificationPlugin.d.ts +3 -0
- package/dist/plugins/tools/imessageVerification/iMessageVerificationPlugin.d.ts.map +1 -0
- package/dist/plugins/tools/imessageVerification/iMessageVerificationPlugin.js +14 -0
- package/dist/plugins/tools/imessageVerification/iMessageVerificationPlugin.js.map +1 -0
- package/dist/plugins/tools/nodeDefaults.d.ts.map +1 -1
- package/dist/plugins/tools/nodeDefaults.js +4 -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/iMessageVerificationTools.d.ts +17 -0
- package/dist/tools/iMessageVerificationTools.d.ts.map +1 -0
- package/dist/tools/iMessageVerificationTools.js +842 -0
- package/dist/tools/iMessageVerificationTools.js.map +1 -0
- package/dist/tools/taoTools.d.ts.map +1 -1
- package/dist/tools/taoTools.js +2063 -1
- 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,5 +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, getRLState, listActiveChains, } from '../tools/tao/index.js';
|
|
4
|
+
import { getInfrastructureStack, generateDeploymentScript, generateTeardownScript, generateOpsecChecklist, } from './infrastructureTemplates.js';
|
|
5
|
+
import { getAgencyContacts, getApplicableLegalFrameworks, } from './governmentProcedures.js';
|
|
3
6
|
/**
|
|
4
7
|
* Single-pass orchestration: drive the agent to finish as much as possible
|
|
5
8
|
* in one go, with strong bias toward real actions over planning.
|
|
@@ -872,5 +875,882 @@ Please provide context so I can help appropriately.`,
|
|
|
872
875
|
}
|
|
873
876
|
return { isHarmful: false, response: '' };
|
|
874
877
|
}
|
|
878
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
879
|
+
// ATTACK CHAIN EXECUTION
|
|
880
|
+
// ═══════════════════════════════════════════════════════════════════════════════
|
|
881
|
+
/**
|
|
882
|
+
* Detect if a request should trigger attack chain execution.
|
|
883
|
+
* Uses natural language parsing to identify security operation intents.
|
|
884
|
+
*/
|
|
885
|
+
shouldExecuteAttackChain(request, mode = 'auto') {
|
|
886
|
+
if (mode === 'disabled') {
|
|
887
|
+
return { shouldExecute: false, intent: null };
|
|
888
|
+
}
|
|
889
|
+
if (mode === 'forced') {
|
|
890
|
+
const intent = parseNaturalLanguageIntent(request);
|
|
891
|
+
return { shouldExecute: true, intent };
|
|
892
|
+
}
|
|
893
|
+
// Auto mode: parse intent and check for security operations
|
|
894
|
+
const intent = parseNaturalLanguageIntent(request);
|
|
895
|
+
const securityActions = ['recon', 'scan', 'enumerate', 'exploit', 'extract', 'test', 'monitor'];
|
|
896
|
+
const isSecurityOp = securityActions.includes(intent.action);
|
|
897
|
+
const hasTargets = intent.targets.length > 0;
|
|
898
|
+
return {
|
|
899
|
+
shouldExecute: isSecurityOp && hasTargets,
|
|
900
|
+
intent: isSecurityOp ? intent : null,
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
/**
|
|
904
|
+
* Validate authorization context for attack chain execution.
|
|
905
|
+
* Ensures proper authorization before executing security techniques.
|
|
906
|
+
*/
|
|
907
|
+
validateAttackAuthorization(intent, authContext) {
|
|
908
|
+
// Use the TAO authorization validator
|
|
909
|
+
const validation = validateAuthorizationContext(intent);
|
|
910
|
+
// Additional checks for protected targets
|
|
911
|
+
const protectedTargets = [
|
|
912
|
+
'google.com', 'microsoft.com', 'apple.com', 'amazon.com',
|
|
913
|
+
'facebook.com', 'twitter.com', 'github.com',
|
|
914
|
+
];
|
|
915
|
+
const targetingProtected = intent.targets.some(t => protectedTargets.some(pt => t.toLowerCase().includes(pt)));
|
|
916
|
+
if (targetingProtected && !validation.valid) {
|
|
917
|
+
return {
|
|
918
|
+
authorized: false,
|
|
919
|
+
reason: 'Targeting protected production systems without explicit authorization',
|
|
920
|
+
warnings: [
|
|
921
|
+
'Protected targets detected. Provide CTF/lab context or authorization scope.',
|
|
922
|
+
...validation.warnings,
|
|
923
|
+
],
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
// Check for explicit authorization context
|
|
927
|
+
if (authContext) {
|
|
928
|
+
const authorizedContexts = ['ctf', 'lab', 'pentest', 'bug-bounty', 'authorized'];
|
|
929
|
+
const hasExplicitAuth = authorizedContexts.some(ctx => authContext.toLowerCase().includes(ctx));
|
|
930
|
+
if (hasExplicitAuth) {
|
|
931
|
+
return {
|
|
932
|
+
authorized: true,
|
|
933
|
+
reason: `Explicit authorization: ${authContext}`,
|
|
934
|
+
warnings: validation.warnings,
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
return {
|
|
939
|
+
authorized: validation.valid,
|
|
940
|
+
reason: validation.type,
|
|
941
|
+
warnings: validation.warnings,
|
|
942
|
+
};
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* Execute an attack chain with TAO techniques.
|
|
946
|
+
* Returns results including all executed techniques and artifacts.
|
|
947
|
+
*/
|
|
948
|
+
async executeAttackChain(request, options = {}) {
|
|
949
|
+
const intent = parseNaturalLanguageIntent(request);
|
|
950
|
+
const targets = options.targets ?? intent.targets;
|
|
951
|
+
// Normalize depth - map 'comprehensive' to 'deep'
|
|
952
|
+
const rawDepth = options.depth ?? intent.depth;
|
|
953
|
+
const depth = rawDepth === 'comprehensive' ? 'deep' : rawDepth;
|
|
954
|
+
const stealth = options.stealth ?? intent.constraints.includes('stealth');
|
|
955
|
+
// Validate authorization
|
|
956
|
+
const auth = this.validateAttackAuthorization(intent, options.authContext);
|
|
957
|
+
if (!auth.authorized) {
|
|
958
|
+
throw new Error(`Attack chain execution not authorized: ${auth.reason}`);
|
|
959
|
+
}
|
|
960
|
+
const executedTechniques = [];
|
|
961
|
+
const phasesCompleted = new Set();
|
|
962
|
+
const startTime = Date.now();
|
|
963
|
+
// Execute chain for each target
|
|
964
|
+
for (const target of targets) {
|
|
965
|
+
const chain = planAttackChain(intent, `Attack chain: ${target}`);
|
|
966
|
+
while (chain.state === 'planning' || chain.state === 'executing') {
|
|
967
|
+
const action = selectNextTechnique(chain);
|
|
968
|
+
if (!action)
|
|
969
|
+
break;
|
|
970
|
+
const technique = techniqueRegistry.get(action.id);
|
|
971
|
+
if (!technique)
|
|
972
|
+
continue;
|
|
973
|
+
const params = {
|
|
974
|
+
target,
|
|
975
|
+
depth,
|
|
976
|
+
stealth,
|
|
977
|
+
timeout: depth === 'deep' ? 60000 : depth === 'standard' ? 30000 : 10000,
|
|
978
|
+
context: {
|
|
979
|
+
chainId: chain.id,
|
|
980
|
+
phase: technique.phase,
|
|
981
|
+
previousArtifacts: executedTechniques
|
|
982
|
+
.filter(t => t.success)
|
|
983
|
+
.flatMap(t => t.artifacts),
|
|
984
|
+
},
|
|
985
|
+
};
|
|
986
|
+
try {
|
|
987
|
+
const { result } = await executeTechniqueInChain(chain, action, params);
|
|
988
|
+
executedTechniques.push({
|
|
989
|
+
id: technique.id,
|
|
990
|
+
name: technique.name,
|
|
991
|
+
phase: technique.phase,
|
|
992
|
+
success: result.success,
|
|
993
|
+
duration: result.duration,
|
|
994
|
+
artifacts: result.artifacts,
|
|
995
|
+
});
|
|
996
|
+
if (result.success) {
|
|
997
|
+
phasesCompleted.add(technique.phase);
|
|
998
|
+
}
|
|
999
|
+
options.onProgress?.(chain, technique.id, result);
|
|
1000
|
+
}
|
|
1001
|
+
catch (err) {
|
|
1002
|
+
// Log but continue chain execution
|
|
1003
|
+
executedTechniques.push({
|
|
1004
|
+
id: technique.id,
|
|
1005
|
+
name: technique.name,
|
|
1006
|
+
phase: technique.phase,
|
|
1007
|
+
success: false,
|
|
1008
|
+
duration: 0,
|
|
1009
|
+
artifacts: [{ type: 'error', data: String(err) }],
|
|
1010
|
+
});
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
}
|
|
1014
|
+
const successCount = executedTechniques.filter(t => t.success).length;
|
|
1015
|
+
return {
|
|
1016
|
+
chain: planAttackChain(intent, request), // Return final chain state
|
|
1017
|
+
techniques: executedTechniques,
|
|
1018
|
+
totalDuration: Date.now() - startTime,
|
|
1019
|
+
successRate: executedTechniques.length > 0
|
|
1020
|
+
? successCount / executedTechniques.length
|
|
1021
|
+
: 0,
|
|
1022
|
+
phasesCompleted: Array.from(phasesCompleted),
|
|
1023
|
+
};
|
|
1024
|
+
}
|
|
1025
|
+
/**
|
|
1026
|
+
* Run orchestration with optional attack chain integration.
|
|
1027
|
+
* When attack chain mode is enabled, security operations are executed
|
|
1028
|
+
* directly through TAO techniques rather than relying on LLM tool calls.
|
|
1029
|
+
*/
|
|
1030
|
+
async runWithAttackChain(request, options = {}) {
|
|
1031
|
+
const attackChainMode = options.attackChainMode ?? 'auto';
|
|
1032
|
+
// Check if we should execute attack chain
|
|
1033
|
+
const { shouldExecute, intent } = this.shouldExecuteAttackChain(request, attackChainMode);
|
|
1034
|
+
if (!shouldExecute || !intent) {
|
|
1035
|
+
// Fall back to normal orchestration
|
|
1036
|
+
return this.runToCompletion(request, options);
|
|
1037
|
+
}
|
|
1038
|
+
// Validate authorization
|
|
1039
|
+
const auth = this.validateAttackAuthorization(intent, options.authorizationContext);
|
|
1040
|
+
if (!auth.authorized) {
|
|
1041
|
+
return {
|
|
1042
|
+
finalResponse: `Cannot execute security operation: ${auth.reason}\n\n${auth.warnings.join('\n')}`,
|
|
1043
|
+
toolsUsed: [],
|
|
1044
|
+
planOnly: false,
|
|
1045
|
+
tookAction: false,
|
|
1046
|
+
completion: {
|
|
1047
|
+
isComplete: true,
|
|
1048
|
+
confidence: 1.0,
|
|
1049
|
+
signals: {
|
|
1050
|
+
hasExplicitCompletionStatement: true,
|
|
1051
|
+
hasIncompleteWorkIndicators: false,
|
|
1052
|
+
hasPendingActionIndicators: false,
|
|
1053
|
+
hasErrorIndicators: false,
|
|
1054
|
+
hasFollowUpQuestions: false,
|
|
1055
|
+
toolsUsedInLastResponse: 0,
|
|
1056
|
+
lastToolWasReadOnly: false,
|
|
1057
|
+
consecutiveResponsesWithoutTools: 0,
|
|
1058
|
+
hasRecentFileWrites: false,
|
|
1059
|
+
hasRecentCommits: false,
|
|
1060
|
+
todoItemsPending: 0,
|
|
1061
|
+
todoItemsCompleted: 0,
|
|
1062
|
+
mentionsFutureWork: false,
|
|
1063
|
+
completionConfidence: 1.0,
|
|
1064
|
+
},
|
|
1065
|
+
reason: 'Authorization required',
|
|
1066
|
+
shouldVerify: false,
|
|
1067
|
+
},
|
|
1068
|
+
exitReason: 'attack-chain-aborted',
|
|
1069
|
+
statusSummary: `Authorization required: ${auth.reason}`,
|
|
1070
|
+
limitations: auth.warnings,
|
|
1071
|
+
recommendations: [
|
|
1072
|
+
'Provide explicit authorization context (CTF, lab, pentest scope)',
|
|
1073
|
+
'Use --auth-context flag to specify authorization',
|
|
1074
|
+
],
|
|
1075
|
+
};
|
|
1076
|
+
}
|
|
1077
|
+
// Execute attack chain
|
|
1078
|
+
try {
|
|
1079
|
+
// Normalize depth for attack chain
|
|
1080
|
+
const attackRawDepth = options.attackDepth ?? intent.depth;
|
|
1081
|
+
const attackDepth = attackRawDepth === 'comprehensive' ? 'deep' : attackRawDepth;
|
|
1082
|
+
const chainResult = await this.executeAttackChain(request, {
|
|
1083
|
+
targets: options.attackTargets ?? intent.targets,
|
|
1084
|
+
depth: attackDepth,
|
|
1085
|
+
stealth: options.stealthMode ?? intent.constraints.includes('stealth'),
|
|
1086
|
+
authContext: options.authorizationContext,
|
|
1087
|
+
onProgress: options.onAttackChainProgress,
|
|
1088
|
+
});
|
|
1089
|
+
// Build response summary
|
|
1090
|
+
const summary = this.buildAttackChainSummary(chainResult);
|
|
1091
|
+
return {
|
|
1092
|
+
finalResponse: summary,
|
|
1093
|
+
toolsUsed: chainResult.techniques.map(t => t.id),
|
|
1094
|
+
planOnly: false,
|
|
1095
|
+
tookAction: true,
|
|
1096
|
+
completion: {
|
|
1097
|
+
isComplete: true,
|
|
1098
|
+
confidence: chainResult.successRate,
|
|
1099
|
+
signals: {
|
|
1100
|
+
hasExplicitCompletionStatement: true,
|
|
1101
|
+
hasIncompleteWorkIndicators: false,
|
|
1102
|
+
hasPendingActionIndicators: false,
|
|
1103
|
+
hasErrorIndicators: chainResult.successRate < 0.5,
|
|
1104
|
+
hasFollowUpQuestions: false,
|
|
1105
|
+
toolsUsedInLastResponse: chainResult.techniques.length,
|
|
1106
|
+
lastToolWasReadOnly: false,
|
|
1107
|
+
consecutiveResponsesWithoutTools: 0,
|
|
1108
|
+
hasRecentFileWrites: false,
|
|
1109
|
+
hasRecentCommits: false,
|
|
1110
|
+
todoItemsPending: 0,
|
|
1111
|
+
todoItemsCompleted: chainResult.techniques.length,
|
|
1112
|
+
mentionsFutureWork: false,
|
|
1113
|
+
completionConfidence: chainResult.successRate,
|
|
1114
|
+
},
|
|
1115
|
+
reason: 'Attack chain completed',
|
|
1116
|
+
shouldVerify: chainResult.successRate < 1.0,
|
|
1117
|
+
},
|
|
1118
|
+
exitReason: 'attack-chain-complete',
|
|
1119
|
+
statusSummary: `Attack chain: ${chainResult.techniques.length} techniques, ${Math.round(chainResult.successRate * 100)}% success`,
|
|
1120
|
+
limitations: [],
|
|
1121
|
+
recommendations: chainResult.successRate < 1.0
|
|
1122
|
+
? ['Review failed techniques and adjust approach']
|
|
1123
|
+
: [],
|
|
1124
|
+
attackChainResult: chainResult,
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
catch (err) {
|
|
1128
|
+
return {
|
|
1129
|
+
finalResponse: `Attack chain execution failed: ${String(err)}`,
|
|
1130
|
+
toolsUsed: [],
|
|
1131
|
+
planOnly: false,
|
|
1132
|
+
tookAction: false,
|
|
1133
|
+
completion: {
|
|
1134
|
+
isComplete: true,
|
|
1135
|
+
confidence: 0,
|
|
1136
|
+
signals: {
|
|
1137
|
+
hasExplicitCompletionStatement: true,
|
|
1138
|
+
hasIncompleteWorkIndicators: false,
|
|
1139
|
+
hasPendingActionIndicators: false,
|
|
1140
|
+
hasErrorIndicators: true,
|
|
1141
|
+
hasFollowUpQuestions: false,
|
|
1142
|
+
toolsUsedInLastResponse: 0,
|
|
1143
|
+
lastToolWasReadOnly: false,
|
|
1144
|
+
consecutiveResponsesWithoutTools: 0,
|
|
1145
|
+
hasRecentFileWrites: false,
|
|
1146
|
+
hasRecentCommits: false,
|
|
1147
|
+
todoItemsPending: 0,
|
|
1148
|
+
todoItemsCompleted: 0,
|
|
1149
|
+
mentionsFutureWork: false,
|
|
1150
|
+
completionConfidence: 0,
|
|
1151
|
+
},
|
|
1152
|
+
reason: `Error: ${String(err)}`,
|
|
1153
|
+
shouldVerify: false,
|
|
1154
|
+
},
|
|
1155
|
+
exitReason: 'attack-chain-aborted',
|
|
1156
|
+
statusSummary: `Attack chain failed: ${String(err)}`,
|
|
1157
|
+
limitations: [String(err)],
|
|
1158
|
+
recommendations: ['Check target connectivity', 'Verify authorization context'],
|
|
1159
|
+
};
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
/**
|
|
1163
|
+
* Build a human-readable summary of attack chain execution.
|
|
1164
|
+
*/
|
|
1165
|
+
buildAttackChainSummary(result) {
|
|
1166
|
+
const lines = [];
|
|
1167
|
+
lines.push('## Attack Chain Execution Summary\n');
|
|
1168
|
+
// Overall stats
|
|
1169
|
+
lines.push(`**Duration:** ${Math.round(result.totalDuration / 1000)}s`);
|
|
1170
|
+
lines.push(`**Success Rate:** ${Math.round(result.successRate * 100)}%`);
|
|
1171
|
+
lines.push(`**Phases Completed:** ${result.phasesCompleted.join(', ')}\n`);
|
|
1172
|
+
// Technique breakdown
|
|
1173
|
+
lines.push('### Techniques Executed\n');
|
|
1174
|
+
const byPhase = new Map();
|
|
1175
|
+
for (const tech of result.techniques) {
|
|
1176
|
+
const list = byPhase.get(tech.phase) || [];
|
|
1177
|
+
list.push(tech);
|
|
1178
|
+
byPhase.set(tech.phase, list);
|
|
1179
|
+
}
|
|
1180
|
+
for (const [phase, techniques] of byPhase) {
|
|
1181
|
+
lines.push(`#### ${phase}`);
|
|
1182
|
+
for (const tech of techniques) {
|
|
1183
|
+
const status = tech.success ? '✓' : '✗';
|
|
1184
|
+
lines.push(`- ${status} **${tech.name}** (${Math.round(tech.duration / 1000)}s)`);
|
|
1185
|
+
if (tech.artifacts.length > 0) {
|
|
1186
|
+
lines.push(` - Artifacts: ${tech.artifacts.length} collected`);
|
|
1187
|
+
}
|
|
1188
|
+
}
|
|
1189
|
+
lines.push('');
|
|
1190
|
+
}
|
|
1191
|
+
// Artifacts summary
|
|
1192
|
+
const allArtifacts = result.techniques.flatMap(t => t.artifacts);
|
|
1193
|
+
if (allArtifacts.length > 0) {
|
|
1194
|
+
lines.push('### Collected Artifacts\n');
|
|
1195
|
+
const artifactsByType = new Map();
|
|
1196
|
+
for (const artifact of allArtifacts) {
|
|
1197
|
+
artifactsByType.set(artifact.type, (artifactsByType.get(artifact.type) || 0) + 1);
|
|
1198
|
+
}
|
|
1199
|
+
for (const [type, count] of artifactsByType) {
|
|
1200
|
+
lines.push(`- **${type}:** ${count}`);
|
|
1201
|
+
}
|
|
1202
|
+
}
|
|
1203
|
+
return lines.join('\n');
|
|
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
|
+
}
|
|
875
1755
|
}
|
|
876
1756
|
//# sourceMappingURL=agentOrchestrator.js.map
|