Copilot Studio - Exploit or RCE intent followed by MCP execution
Copilot Studio Mcp Exploit Execution Chain
Query
let IsExploitIntent = (Content:string) {
isnotempty(Content) and (
Content has_any ("remote code execution", "reverse shell", "metasploit",
"run_shell_command", "vulnerabilities/exec", "kali linux",
"execute command", "ejecuta el comando", "ejecuta un comando")
or Content matches regex @"(?i)(execute|ejecuta|run).{0,40}(command|comando|shell)"
)
};
let IsCommandTool = (Value:string) {
tolower(Value) matches regex @"(run[_ -]?(shell|command|code)|execute[_ -]?(shell|command|code)|powershell|cmd\.exe|terminal|reverse[_ -]?shell|metasploit|kali|ssh[_ -]?exec|remote[_ -]?code[_ -]?execution|vulnerabilities/exec)"
};
let LegacyPrompts = AppEvents
| where Name == "BotMessageReceived"
| extend ConvId = tostring(Properties["conversationId"]),
Content = tostring(Properties["text"])
| where IsExploitIntent(Content)
| summarize PromptSignals = count(), PromptFirstSeen = min(TimeGenerated),
PromptLastSeen = max(TimeGenerated), UserId = take_any(UserId),
ClientIP = take_any(ClientIP), ChannelId = take_any(tostring(Properties["channelId"])) by ConvId;
let LegacyTools = AppDependencies
| where AppRoleName == "Microsoft Copilot Studio" or DependencyType == "Connector"
| extend ConvId = tostring(Properties["conversationId"]), Tool = Name,
ToolTarget = tostring(Target)
| where IsCommandTool(strcat(Tool, " ", ToolTarget))
| summarize ToolCalls = count(), ToolFailures = countif(Success == false),
Tools = make_set(Tool, 20), Targets = make_set(ToolTarget, 20),
ToolLastSeen = max(TimeGenerated) by ConvId;
let LegacyChain = LegacyPrompts
| join kind=inner LegacyTools on ConvId
| project TimeGenerated = max_of(PromptLastSeen, ToolLastSeen),
FirstSeen = PromptFirstSeen, AccountName = iff(isempty(UserId), "unknown-agent", UserId),
ClientIP, ConvId, OperationId = "", Agent = "", ChannelId,
PromptSignals, ToolCalls, ToolFailures, Tools, Targets, Source = "Agent-level telemetry";
let ModernPrompts = AppDependencies
| where tostring(Properties["gen_ai.operation.name"]) == "invoke_agent"
| extend Content = tostring(Properties["gen_ai.input.messages"])
| where IsExploitIntent(Content)
| summarize PromptSignals = count(), PromptFirstSeen = min(TimeGenerated),
PromptLastSeen = max(TimeGenerated),
Agent = take_any(tostring(Properties["gen_ai.agent.name"])),
ConvId = take_any(tostring(Properties["gen_ai.conversation.id"])),
AccountName = take_any(coalesce(tostring(Properties["user.email"]),
tostring(Properties["user.id"]), tostring(Properties["gen_ai.agent.name"]))),
ClientIP = take_any(ClientIP),
ChannelId = take_any(tostring(Properties["microsoft.channel.name"])) by OperationId;
let ModernTools = AppDependencies
| where tostring(Properties["gen_ai.operation.name"]) == "execute_tool"
| extend Tool = tostring(Properties["gen_ai.tool.name"]),
ToolTarget = tostring(Target), ToolType = tostring(Properties["gen_ai.tool.type"])
| where IsCommandTool(strcat(Tool, " ", ToolType, " ", ToolTarget))
| summarize ToolCalls = count(), ToolFailures = countif(Success == false),
Tools = make_set(Tool, 20), Targets = make_set(ToolTarget, 20),
ToolLastSeen = max(TimeGenerated) by OperationId;
let ModernChain = ModernPrompts
| join kind=inner ModernTools on OperationId
| project TimeGenerated = max_of(PromptLastSeen, ToolLastSeen),
FirstSeen = PromptFirstSeen, AccountName, ClientIP, ConvId, OperationId,
Agent, ChannelId, PromptSignals, ToolCalls, ToolFailures, Tools, Targets,
Source = "Environment telemetry";
union LegacyChain, ModernChain
| project TimeGenerated, FirstSeen, AccountName, ClientIP, Agent, ConvId,
OperationId, ChannelId, PromptSignals, ToolCalls, ToolFailures, Tools,
Targets, Source
| order by TimeGenerated descExplanation
This query is designed to detect potential security threats in a system by monitoring for specific patterns of behavior that indicate an exploit or remote code execution (RCE) attempt. Here's a simplified breakdown of what the query does:
-
Purpose: The query identifies scenarios where there is an intent to exploit or execute remote commands, followed by the execution of a command-capable tool. This is particularly focused on activities within Copilot Studio and related tools.
-
Data Sources: It uses data from Application Insights, specifically looking at
AppEventsandAppDependencies. -
Detection Logic:
- Exploit Intent: It checks for certain keywords or patterns in the content of messages that suggest an attempt to execute commands or use offensive tools (e.g., "remote code execution", "reverse shell").
- Command Tool Usage: It identifies when tools capable of executing commands are used (e.g., PowerShell, cmd.exe, Metasploit).
-
Correlation:
- Legacy Systems: It correlates events and dependencies based on conversation IDs for older systems.
- Modern Systems: It uses operation IDs for newer systems to correlate agent invocation and tool execution.
-
Alerting:
- If both exploit intent and command tool usage are detected in the same conversation or operation, it raises an alert.
- The alert includes details like the time of the event, user account, client IP, and tools used.
-
Severity and Frequency: The query is set to run every hour and has a high severity level, meaning it is considered a significant security risk.
-
Incident Management: When an alert is triggered, it creates an incident in the system, grouping similar alerts to manage them efficiently.
Overall, this query is part of a security monitoring system that helps detect and respond to potential cyber threats by identifying suspicious activities related to remote command execution.