AWS EC2 LOLBin Execution via SSM SendCommand

Identifies the execution of Living Off the Land Binaries (LOLBins) or GTFOBins on EC2 instances via AWS Systems Manager (SSM) SendCommand API. This detection correlates AWS CloudTrail SendCommand events with endpoint process execution by matching SSM command IDs. While AWS redacts command parameters in CloudTrail logs, this correlation technique reveals the actual commands executed on EC2 instances. Adversaries may abuse SSM to execute malicious commands remotely without requiring SSH or RDP access, using legitimate system utilities for data exfiltration, establishing reverse shells, or lateral movement.

Elastic rule (View on GitHub)

  1[metadata]
  2creation_date = "2025/11/23"
  3integration = ["aws", "endpoint"]
  4maturity = "production"
  5updated_date = "2026/09/18"
  6
  7[rule]
  8author = ["Elastic"]
  9description = """
 10Identifies the execution of Living Off the Land Binaries (LOLBins) or GTFOBins on EC2 instances via AWS Systems Manager
 11(SSM) `SendCommand` API. This detection correlates AWS CloudTrail `SendCommand` events with endpoint process execution
 12by matching SSM command IDs. While AWS redacts command parameters in CloudTrail logs, this correlation technique reveals
 13the actual commands executed on EC2 instances. Adversaries may abuse SSM to execute malicious commands remotely without
 14requiring SSH or RDP access, using legitimate system utilities for data exfiltration, establishing reverse shells, or
 15lateral movement.
 16"""
 17false_positives = [
 18    """
 19    Legitimate administrative tasks using SSM to run system utilities may trigger this rule. Review the command context,
 20    user identity, and timing to determine if the activity is authorized.
 21    """,
 22    """
 23    Automated configuration management or monitoring scripts that use LOLBins via SSM for legitimate purposes. Consider
 24    excluding known automation accounts or specific command patterns.
 25    """,
 26]
 27from = "now-9m"
 28interval = "8m"
 29language = "esql"
 30license = "Elastic License v2"
 31name = "AWS EC2 LOLBin Execution via SSM SendCommand"
 32note = """## Triage and analysis
 33
 34### Investigating AWS EC2 LOLBin Execution via SSM SendCommand
 35
 36AWS Systems Manager (SSM) enables remote command execution on EC2 instances without SSH/RDP access. While legitimate for administration, adversaries exploit this by running LOLBins—system utilities abused for malicious purposes like data theft or backdoors. This detection correlates CloudTrail API logs with endpoint telemetry using SSM command IDs, bypassing AWS's parameter redaction to reveal actual executed commands and identify suspicious activity.
 37
 38This is an ESQL aggregation-based rule, thus all original event fields and detail may not be present in the alert. It is recommended to pivot into the raw events from both data sources for full context during investigation.
 39
 40### Possible investigation steps
 41
 42- Review the SSM command ID in the alert to track the full lifecycle of the command from initiation to execution across both CloudTrail and endpoint data
 43- Examine the CloudTrail user identity, including the ARN and access key ID, to determine who initiated the SSM command and verify if the activity is authorized
 44- Analyze the command lines of the executed LOLBins to understand what commands were run and assess their intent, looking for indicators of data exfiltration, reverse shells, or reconnaissance
 45- Check the source IP address and user agent from the CloudTrail event to identify if the request came from an expected location or tool
 46- Investigate the affected EC2 instances for other suspicious activities or signs of compromise during the same timeframe, including network connections and file modifications
 47- Review the SSM shell process details to see the full context of what the SSM agent executed and identify the parent-child process relationships
 48- Correlate the timing between the CloudTrail event and endpoint execution to ensure they occurred within the detection window and represent the same activity
 49- Check if the same user identity or source IP has executed similar SSM commands on other EC2 instances in your environment
 50
 51### False positive analysis
 52
 53- Routine administrative scripts that use utilities like curl, wget, or python for legitimate configuration management should be documented and excluded by user identity or source IP
 54- Automated monitoring tools that execute commands via SSM for health checks or data collection can be filtered by identifying their consistent patterns and access key IDs
 55- DevOps CI/CD pipelines that deploy or test applications using SSM may trigger alerts; create exceptions based on known automation roles or specific command patterns
 56- Security scanning tools that legitimately use SSM for vulnerability assessments should be allowlisted by their known IAM roles or source IPs
 57- Scheduled maintenance tasks using LOLBins for backup, log rotation, or data synchronization can be excluded by command pattern matching or execution timing
 58
 59### Response and remediation
 60
 61- Immediately isolate the affected EC2 instance from the network to prevent further unauthorized command execution or lateral movement
 62- Review AWS CloudTrail logs to identify the IAM user, role, or access key associated with the suspicious SSM command and revoke or rotate compromised credentials
 63- Terminate any unauthorized processes identified on the endpoint that match the LOLBin execution patterns detected in the alert
 64- Conduct a forensic analysis of the affected EC2 instance to identify any persistence mechanisms, backdoors, or data exfiltration indicators
 65- Implement stricter IAM policies to limit SSM `SendCommand` permissions to only trusted users and roles, following the principle of least privilege
 66- Enable multi-factor authentication (MFA) for IAM users with SSM execution privileges to reduce the risk of credential compromise
 67- Review and update VPC security groups and network ACLs to restrict outbound traffic from EC2 instances to only necessary destinations, preventing data exfiltration
 68- Escalate the incident to the security operations center (SOC) for further investigation and to determine if additional AWS resources or accounts have been compromised
 69"""
 70references = [
 71    "https://www.mitiga.io/blog/abusing-the-amazon-web-services-ssm-agent-as-a-remote-access-trojan",
 72    "https://www.kali.org/tools/pacu/",
 73    "https://www.100daysofredteam.com/p/ghost-in-the-cloud-abusing-aws-ssm",
 74    "https://hackingthe.cloud/aws/post_exploitation/run_shell_commands_on_ec2/",
 75    "https://gtfobins.github.io/",
 76]
 77risk_score = 47
 78rule_id = "a8b3e2f0-8c7d-11ef-b4c6-f661ea17fbcd"
 79severity = "medium"
 80tags = [
 81    "Domain: Cloud",
 82    "Domain: Endpoint",
 83    "OS: Linux",
 84    "Use Case: Threat Detection",
 85    "Tactic: Execution",
 86    "Tactic: Command and Control",
 87    "Data Source: AWS",
 88    "Data Source: Amazon Web Services",
 89    "Data Source: AWS CloudTrail",
 90    "Data Source: AWS EC2",
 91    "Data Source: AWS SSM",
 92    "Data Source: AWS Systems Manager",
 93    "Data Source: Elastic Defend",
 94    "Resources: Investigation Guide",
 95    "Noise: Low",
 96    "Performance: Normal",
 97    "Profile: Recommended",
 98    "Threat: Living off the Land",
 99    "Threat: Cloud VM Execution",
100    "Rule Type: ES|QL",
101    "Platform: Linux",
102    "Platform: AWS",
103    "Service: AWS EC2",
104    "Service: AWS SSM",
105]
106timestamp_override = "event.ingested"
107type = "esql"
108
109query = '''
110FROM logs-aws.cloudtrail*, logs-endpoint.events.process-* METADATA _id, _version, _index
111| WHERE
112  // CloudTrail SSM SendCommand with AWS-RunShellScript
113  (
114    data_stream.dataset == "aws.cloudtrail"
115    AND event.action == "SendCommand"
116    AND aws.cloudtrail.request_parameters LIKE "*documentName=AWS-RunShellScript*"
117  )
118  // Linux endpoint process events, prefiltered to SSM shell runner OR LOLBins/GTFOBins
119  OR
120  (
121    data_stream.dataset == "endpoint.events.process"
122    AND host.os.type == "linux"
123    AND (
124      // SSM shell (_script.sh) runner
125      process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh"
126      // LOLBins / GTFOBins
127      OR process.name IN (
128        "base64",
129        "curl",
130        "wget",
131        "openssl",
132        "nc", "ncat", "netcat",
133        "socat",
134        "python", "python3",
135        "perl",
136        "php",
137        "ruby",
138        "ssh",
139        "scp",
140        "sftp",
141        "rsync"
142      )
143    )
144  )
145
146// Endpoint leg: extract SSM command ID from parent command line
147| DISSECT process.parent.command_line
148    "%{}/document/orchestration/%{Esql.process_parent_command_line_ssm_command_id}/%{}"
149
150// CloudTrail leg: extract SSM command ID from response_elements
151| DISSECT aws.cloudtrail.response_elements
152    "%{}commandId=%{Esql.aws_cloudtrail_response_elements_ssm_command_id},%{}"
153
154// Coalesce SSM command ID from both data sources
155| EVAL Esql.aws_ssm_command_id = COALESCE(
156    Esql.aws_cloudtrail_response_elements_ssm_command_id,
157    Esql.process_parent_command_line_ssm_command_id
158)
159| WHERE Esql.aws_ssm_command_id IS NOT NULL
160
161// Role flags
162| EVAL Esql.is_cloud_event    = data_stream.dataset == "aws.cloudtrail"
163| EVAL Esql.is_endpoint_event = data_stream.dataset == "endpoint.events.process"
164
165// Identify the SSM shell processes (the _script.sh runners)
166| EVAL Esql.is_ssm_shell_process =
167    Esql.is_endpoint_event
168    AND process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh"
169
170// LOLBins / GTFOBins on Linux
171| EVAL Esql.is_lolbin_process =
172    Esql.is_endpoint_event AND NOT Esql.is_ssm_shell_process
173
174// Aggregate per SSM command ID
175| STATS
176    // Core correlation counts & timing
177    Esql.aws_cloudtrail_event_count                 = SUM(CASE(Esql.is_cloud_event, 1, 0)),
178    Esql.endpoint_events_process_lolbin_count       = SUM(CASE(Esql.is_lolbin_process, 1, 0)),
179    Esql.endpoint_events_process_ssm_shell_count    = SUM(CASE(Esql.is_ssm_shell_process, 1, 0)),
180    Esql.aws_cloudtrail_first_event_ts              = MIN(CASE(Esql.is_cloud_event, @timestamp, null)),
181    Esql.endpoint_events_process_first_lolbin_ts    = MIN(CASE(Esql.is_lolbin_process, @timestamp, null)),
182
183    // AWS / CloudTrail identity & request context
184    Esql_priv.aws_cloudtrail_user_identity_arn_values          =
185      VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.arn, null)),
186    Esql_priv.aws_cloudtrail_user_identity_access_key_id_values =
187      VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.access_key_id, null)),
188    Esql_priv.user_name_values                                 =
189      VALUES(CASE(Esql.is_cloud_event, user.name, null)),
190
191    // AWS environment / request metadata
192    Esql.cloud_region_values     = VALUES(CASE(Esql.is_cloud_event, cloud.region, null)),
193    Esql.source_ip_values        = VALUES(CASE(Esql.is_cloud_event, source.ip, null)),
194    Esql.user_agent_original_values =
195      VALUES(CASE(Esql.is_cloud_event, user_agent.original, null)),
196
197    // Endpoint host & user context
198    Esql.host_name_values        = VALUES(CASE(Esql.is_endpoint_event, host.name, null)),
199    Esql_priv.endpoint_user_name_values =
200      VALUES(CASE(Esql.is_endpoint_event, user.name, null)),
201
202    // SSM shell processes on endpoint
203    Esql.process_command_line_ssm_shell_values =
204      VALUES(CASE(Esql.is_ssm_shell_process, process.command_line, null)),
205    Esql.process_pid_ssm_shell_values =
206      VALUES(CASE(Esql.is_ssm_shell_process, process.pid, null)),
207
208    // LOLBin processes on endpoint
209    Esql.process_name_lolbin_values =
210      VALUES(CASE(Esql.is_lolbin_process, process.name, null)),
211    Esql.process_executable_lolbin_values =
212      VALUES(CASE(Esql.is_lolbin_process, process.executable, null)),
213    Esql.process_command_line_lolbin_values =
214      VALUES(CASE(Esql.is_lolbin_process, process.command_line, null)),
215    Esql.process_pid_lolbin_values =
216      VALUES(CASE(Esql.is_lolbin_process, process.pid, null)),
217    Esql.process_parent_command_line_lolbin_values =
218      VALUES(CASE(Esql.is_lolbin_process, process.parent.command_line, null)),
219
220    Esql.data_stream_namespace_values = VALUES(data_stream.namespace)
221  BY Esql.aws_ssm_command_id
222
223// Detection condition: SSM SendCommand + AWS-RunShellScript + LOLBin on endpoint
224| WHERE Esql.aws_cloudtrail_event_count > 0
225  AND Esql.endpoint_events_process_lolbin_count > 0
226  AND DATE_DIFF(
227        "minutes",
228        Esql.endpoint_events_process_first_lolbin_ts,
229        Esql.aws_cloudtrail_first_event_ts
230      ) <= 5
231| SORT Esql.aws_cloudtrail_first_event_ts ASC
232| KEEP Esql.*, Esql_priv.*
233'''
234
235
236[[rule.threat]]
237framework = "MITRE ATT&CK"
238
239[[rule.threat.technique]]
240id = "T1059"
241name = "Command and Scripting Interpreter"
242reference = "https://attack.mitre.org/techniques/T1059/"
243
244[[rule.threat.technique.subtechnique]]
245id = "T1059.004"
246name = "Unix Shell"
247reference = "https://attack.mitre.org/techniques/T1059/004/"
248
249[[rule.threat.technique]]
250id = "T1651"
251name = "Cloud Administration Command"
252reference = "https://attack.mitre.org/techniques/T1651/"
253
254[rule.threat.tactic]
255id = "TA0002"
256name = "Execution"
257reference = "https://attack.mitre.org/tactics/TA0002/"
258
259[[rule.threat]]
260framework = "MITRE ATT&CK"
261
262[[rule.threat.technique]]
263id = "T1105"
264name = "Ingress Tool Transfer"
265reference = "https://attack.mitre.org/techniques/T1105/"
266
267[rule.threat.tactic]
268id = "TA0011"
269name = "Command and Control"
270reference = "https://attack.mitre.org/tactics/TA0011/"

Triage and analysis

Investigating AWS EC2 LOLBin Execution via SSM SendCommand

AWS Systems Manager (SSM) enables remote command execution on EC2 instances without SSH/RDP access. While legitimate for administration, adversaries exploit this by running LOLBins—system utilities abused for malicious purposes like data theft or backdoors. This detection correlates CloudTrail API logs with endpoint telemetry using SSM command IDs, bypassing AWS's parameter redaction to reveal actual executed commands and identify suspicious activity.

This is an ESQL aggregation-based rule, thus all original event fields and detail may not be present in the alert. It is recommended to pivot into the raw events from both data sources for full context during investigation.

Possible investigation steps

  • Review the SSM command ID in the alert to track the full lifecycle of the command from initiation to execution across both CloudTrail and endpoint data
  • Examine the CloudTrail user identity, including the ARN and access key ID, to determine who initiated the SSM command and verify if the activity is authorized
  • Analyze the command lines of the executed LOLBins to understand what commands were run and assess their intent, looking for indicators of data exfiltration, reverse shells, or reconnaissance
  • Check the source IP address and user agent from the CloudTrail event to identify if the request came from an expected location or tool
  • Investigate the affected EC2 instances for other suspicious activities or signs of compromise during the same timeframe, including network connections and file modifications
  • Review the SSM shell process details to see the full context of what the SSM agent executed and identify the parent-child process relationships
  • Correlate the timing between the CloudTrail event and endpoint execution to ensure they occurred within the detection window and represent the same activity
  • Check if the same user identity or source IP has executed similar SSM commands on other EC2 instances in your environment

False positive analysis

  • Routine administrative scripts that use utilities like curl, wget, or python for legitimate configuration management should be documented and excluded by user identity or source IP
  • Automated monitoring tools that execute commands via SSM for health checks or data collection can be filtered by identifying their consistent patterns and access key IDs
  • DevOps CI/CD pipelines that deploy or test applications using SSM may trigger alerts; create exceptions based on known automation roles or specific command patterns
  • Security scanning tools that legitimately use SSM for vulnerability assessments should be allowlisted by their known IAM roles or source IPs
  • Scheduled maintenance tasks using LOLBins for backup, log rotation, or data synchronization can be excluded by command pattern matching or execution timing

Response and remediation

  • Immediately isolate the affected EC2 instance from the network to prevent further unauthorized command execution or lateral movement
  • Review AWS CloudTrail logs to identify the IAM user, role, or access key associated with the suspicious SSM command and revoke or rotate compromised credentials
  • Terminate any unauthorized processes identified on the endpoint that match the LOLBin execution patterns detected in the alert
  • Conduct a forensic analysis of the affected EC2 instance to identify any persistence mechanisms, backdoors, or data exfiltration indicators
  • Implement stricter IAM policies to limit SSM SendCommand permissions to only trusted users and roles, following the principle of least privilege
  • Enable multi-factor authentication (MFA) for IAM users with SSM execution privileges to reduce the risk of credential compromise
  • Review and update VPC security groups and network ACLs to restrict outbound traffic from EC2 instances to only necessary destinations, preventing data exfiltration
  • Escalate the incident to the security operations center (SOC) for further investigation and to determine if additional AWS resources or accounts have been compromised

References

Related rules

to-top