From d31032ef3c43cb32abf7ef06bb8927c8446aeba9 Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Sun, 23 Nov 2025 22:19:21 -0500 Subject: [PATCH 01/10] [New Rule] AWS EC2 LOLBin Execution via SSM Fixes #5353 --- .../execution_aws_ec2_lolbin_via_ssm.toml | 253 ++++++++++++++++++ 1 file changed, 253 insertions(+) create mode 100644 rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml new file mode 100644 index 00000000000..316d799c568 --- /dev/null +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -0,0 +1,253 @@ +[metadata] +creation_date = "2025/11/23" +integration = ["aws", "endpoint"] +maturity = "production" +updated_date = "2025/11/23" + +[rule] +author = ["Elastic"] +description = """ +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. +""" +false_positives = [ + """ + Legitimate administrative tasks using SSM to run system utilities may trigger this rule. Review the command context, + user identity, and timing to determine if the activity is authorized. + """, + """ + Automated configuration management or monitoring scripts that use LOLBins via SSM for legitimate purposes. Consider + excluding known automation accounts or specific command patterns. + """, +] +from = "now-9m" +interval = "8m" +language = "esql" +license = "Elastic License v2" +name = "AWS EC2 LOLBin Execution via SSM SendCommand" +note = """## 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 = [ + "https://www.mitiga.io/blog/abusing-the-amazon-web-services-ssm-agent-as-a-remote-access-trojan", + "https://www.kali.org/tools/pacu/", + "https://www.100daysofredteam.com/p/ghost-in-the-cloud-abusing-aws-ssm", + "https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ssm-privesc", + "https://gtfobins.github.io/", +] +risk_score = 73 +rule_id = "a8b3e2f0-8c7d-11ef-b4c6-f661ea17fbcd" +severity = "high" +tags = [ + "Domain: Cloud", + "Domain: Endpoint", + "OS: Linux", + "Use Case: Threat Detection", + "Tactic: Execution", + "Tactic: Command and Control", + "Data Source: AWS", + "Data Source: Amazon Web Services", + "Data Source: AWS CloudTrail", + "Data Source: Elastic Defend", + "Resources: Investigation Guide", + "Rule Type: Higher-Order Rule", +] +timestamp_override = "event.ingested" +type = "esql" + +query = ''' +FROM logs-* +| WHERE + // CloudTrail SSM SendCommand with AWS-RunShellScript + ( + event.dataset == "aws.cloudtrail" + AND event.action == "SendCommand" + AND aws.cloudtrail.request_parameters LIKE "*documentName=AWS-RunShellScript*" + ) + // Linux endpoint process events, prefiltered to SSM shell runner OR LOLBins/GTFOBins + OR + ( + event.dataset == "endpoint.events.process" + AND host.os.type == "linux" + AND ( + // SSM shell (_script.sh) runner + process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh" + // LOLBins / GTFOBins + OR process.executable IN ( + "/usr/bin/base64", + "/usr/bin/curl", + "/usr/bin/wget", + "/usr/bin/openssl", + "/usr/bin/nc", "/bin/nc", + "/usr/bin/ncat", "/usr/bin/netcat", + "/usr/bin/socat", + "/usr/bin/python", "/usr/bin/python3", + "/usr/bin/perl", + "/usr/bin/php", + "/usr/bin/ruby", + "/usr/bin/ssh", + "/usr/bin/scp", + "/usr/bin/sftp", + "/usr/bin/rsync" + ) + ) + ) + +// Endpoint leg: extract SSM command ID from parent command line +// .../document/orchestration//AWS-RunShellScript/... +| DISSECT process.parent.command_line + "%{}/document/orchestration/%{Esql.process_parent_command_line_ssm_command_id}/%{}" + +// CloudTrail leg: extract SSM command ID from response_elements +// ...commandId=,... +| DISSECT aws.cloudtrail.response_elements + "%{}commandId=%{Esql.aws_cloudtrail_response_elements_ssm_command_id},%{}" + +// Normalize into a single SSM command id +| EVAL Esql.aws_ssm_command_id = + CASE( + event.dataset == "aws.cloudtrail", Esql.aws_cloudtrail_response_elements_ssm_command_id, + CASE( + event.dataset == "endpoint.events.process", Esql.process_parent_command_line_ssm_command_id, + null + ) + ) +| WHERE Esql.aws_ssm_command_id IS NOT NULL + +// Role flags +| EVAL Esql.is_cloud_event = event.dataset == "aws.cloudtrail" +| EVAL Esql.is_endpoint_event = event.dataset == "endpoint.events.process" + +// Identify the SSM shell processes (the _script.sh runners) +| EVAL Esql.is_ssm_shell_process = + Esql.is_endpoint_event + AND process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh" + +// LOLBins / GTFOBins on Linux +| EVAL Esql.is_lolbin_process = + Esql.is_endpoint_event AND NOT Esql.is_ssm_shell_process + +// Aggregate per SSM command ID +| STATS + // Core correlation counts & timing + Esql.aws_cloudtrail_event_count = SUM(CASE(Esql.is_cloud_event, 1, 0)), + Esql.endpoint_events_process_lolbin_count = SUM(CASE(Esql.is_lolbin_process, 1, 0)), + Esql.endpoint_events_process_ssm_shell_count = SUM(CASE(Esql.is_ssm_shell_process, 1, 0)), + Esql.aws_cloudtrail_first_event_ts = MIN(CASE(Esql.is_cloud_event, @timestamp, null)), + Esql.endpoint_events_process_first_lolbin_ts = MIN(CASE(Esql.is_lolbin_process, @timestamp, null)), + + // AWS / CloudTrail identity & request context (PII → Esql_priv.) + Esql_priv.aws_cloudtrail_user_identity_arn_values = + VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.arn, null)), + Esql_priv.aws_cloudtrail_user_identity_access_key_id_values = + VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.access_key_id, null)), + Esql_priv.user_name_values = + VALUES(CASE(Esql.is_cloud_event, user.name, null)), + + // AWS environment / request metadata + Esql.cloud_region_values = VALUES(CASE(Esql.is_cloud_event, cloud.region, null)), + Esql.source_ip_values = VALUES(CASE(Esql.is_cloud_event, source.ip, null)), + Esql.user_agent_original_values = + VALUES(CASE(Esql.is_cloud_event, user_agent.original, null)), + + // Endpoint host & user context + Esql.host_name_values = VALUES(CASE(Esql.is_endpoint_event, host.name, null)), + Esql_priv.endpoint_user_name_values = + VALUES(CASE(Esql.is_endpoint_event, user.name, null)), + + // SSM shell processes on endpoint + Esql.process_command_line_ssm_shell_values = + VALUES(CASE(Esql.is_ssm_shell_process, process.command_line, null)), + Esql.process_pid_ssm_shell_values = + VALUES(CASE(Esql.is_ssm_shell_process, process.pid, null)), + + // LOLBin processes on endpoint + Esql.process_name_lolbin_values = + VALUES(CASE(Esql.is_lolbin_process, process.name, null)), + Esql.process_executable_lolbin_values = + VALUES(CASE(Esql.is_lolbin_process, process.executable, null)), + Esql.process_command_line_lolbin_values = + VALUES(CASE(Esql.is_lolbin_process, process.command_line, null)), + Esql.process_pid_lolbin_values = + VALUES(CASE(Esql.is_lolbin_process, process.pid, null)), + Esql.process_parent_command_line_lolbin_values = + VALUES(CASE(Esql.is_lolbin_process, process.parent.command_line, null)) + BY Esql.aws_ssm_command_id + +// Detection condition: SSM SendCommand + AWS-RunShellScript + LOLBin on endpoint +| WHERE Esql.aws_cloudtrail_event_count > 0 + AND Esql.endpoint_events_process_lolbin_count > 0 + AND DATE_DIFF( + "minutes", + Esql.endpoint_events_process_first_lolbin_ts, + Esql.aws_cloudtrail_first_event_ts + ) <= 5 +| SORT Esql.aws_cloudtrail_first_event_ts ASC +| KEEP Esql.* +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1651" +name = "Cloud Administration Command" +reference = "https://attack.mitre.org/techniques/T1651/" + + +[rule.threat.tactic] +id = "TA0002" +name = "Execution" +reference = "https://attack.mitre.org/tactics/TA0002/" +[[rule.threat]] +framework = "MITRE ATT&CK" +[[rule.threat.technique]] +id = "T1105" +name = "Ingress Tool Transfer" +reference = "https://attack.mitre.org/techniques/T1105/" + + +[rule.threat.tactic] +id = "TA0011" +name = "Command and Control" +reference = "https://attack.mitre.org/tactics/TA0011/" + From a3f56d4aa8ee74b310d7f23bee32d6d370b62467 Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Sun, 23 Nov 2025 22:23:41 -0500 Subject: [PATCH 02/10] updated from command --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 316d799c568..ec2df61fc20 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -95,7 +95,7 @@ timestamp_override = "event.ingested" type = "esql" query = ''' -FROM logs-* +FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index | WHERE // CloudTrail SSM SendCommand with AWS-RunShellScript ( From afa26de9c755836c07c722525a2e17bf177dd21a Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Sun, 23 Nov 2025 22:24:50 -0500 Subject: [PATCH 03/10] removed high order tag --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index ec2df61fc20..22f4f5e2072 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -89,7 +89,6 @@ tags = [ "Data Source: AWS CloudTrail", "Data Source: Elastic Defend", "Resources: Investigation Guide", - "Rule Type: Higher-Order Rule", ] timestamp_override = "event.ingested" type = "esql" From d93597eac333cb594379a85ae65c8ab6910dc1b5 Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Sun, 23 Nov 2025 22:27:10 -0500 Subject: [PATCH 04/10] adjusted query logic --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 22f4f5e2072..52be5f7f466 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -109,7 +109,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index AND host.os.type == "linux" AND ( // SSM shell (_script.sh) runner - process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh" + process.command_line LIKE "*/document/orchestration/%/awsrunShellScript/*/_script.sh" // LOLBins / GTFOBins OR process.executable IN ( "/usr/bin/base64", @@ -159,7 +159,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index // Identify the SSM shell processes (the _script.sh runners) | EVAL Esql.is_ssm_shell_process = Esql.is_endpoint_event - AND process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh" + AND process.command_line LIKE "*/document/orchestration/*/awsrunShellScript/*/_script.sh" // LOLBins / GTFOBins on Linux | EVAL Esql.is_lolbin_process = From c594c439e61278e52d231c1b49fd7d244575dc7b Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Sun, 23 Nov 2025 22:47:14 -0500 Subject: [PATCH 05/10] updated reference --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 52be5f7f466..8bce70ef1df 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -71,7 +71,7 @@ references = [ "https://www.mitiga.io/blog/abusing-the-amazon-web-services-ssm-agent-as-a-remote-access-trojan", "https://www.kali.org/tools/pacu/", "https://www.100daysofredteam.com/p/ghost-in-the-cloud-abusing-aws-ssm", - "https://cloud.hacktricks.xyz/pentesting-cloud/aws-security/aws-privilege-escalation/aws-ssm-privesc", + "https://hackingthe.cloud/aws/post_exploitation/run_shell_commands_on_ec2/", "https://gtfobins.github.io/", ] risk_score = 73 From 9aa9adf253066f7c9143d31d0a7ab4e9ee5f2ff4 Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Sun, 23 Nov 2025 22:56:01 -0500 Subject: [PATCH 06/10] add ESQL_priv. to keep --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 8bce70ef1df..79733abc298 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -221,7 +221,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index Esql.aws_cloudtrail_first_event_ts ) <= 5 | SORT Esql.aws_cloudtrail_first_event_ts ASC -| KEEP Esql.* +| KEEP Esql.*, Esql_priv.* ''' From 8b47c8fdf4aa8fe92ef59baa1ece54aa21be35b8 Mon Sep 17 00:00:00 2001 From: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> Date: Mon, 24 Nov 2025 11:43:50 -0500 Subject: [PATCH 07/10] Update rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml Co-authored-by: Ruben Groenewoud <78494512+Aegrah@users.noreply.github.com> --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 79733abc298..b81c1b14266 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -8,7 +8,7 @@ updated_date = "2025/11/23" author = ["Elastic"] description = """ 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 +(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 From 072e31df6f37af4b0d64a6fcdbf8c5f0e469db9f Mon Sep 17 00:00:00 2001 From: Terrance DeJesus <99630311+terrancedejesus@users.noreply.github.com> Date: Mon, 24 Nov 2025 11:51:02 -0500 Subject: [PATCH 08/10] Update rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml --- rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index b81c1b14266..2534f8ab771 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -109,7 +109,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index AND host.os.type == "linux" AND ( // SSM shell (_script.sh) runner - process.command_line LIKE "*/document/orchestration/%/awsrunShellScript/*/_script.sh" + process.command_line LIKE "*/document/orchestration/*/awsrunShellScript/*/_script.sh" // LOLBins / GTFOBins OR process.executable IN ( "/usr/bin/base64", From 8d539fc0bdd9993bf09419e2b7e1c8ea598aa453 Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Mon, 24 Nov 2025 15:08:25 -0500 Subject: [PATCH 09/10] cleaned up comments --- .../execution_aws_ec2_lolbin_via_ssm.toml | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 2534f8ab771..692d5f2e628 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -8,7 +8,7 @@ updated_date = "2025/11/23" author = ["Elastic"] description = """ 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 +(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 @@ -109,7 +109,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index AND host.os.type == "linux" AND ( // SSM shell (_script.sh) runner - process.command_line LIKE "*/document/orchestration/*/awsrunShellScript/*/_script.sh" + process.command_line LIKE "*/document/orchestration/%/awsrunShellScript/*/_script.sh" // LOLBins / GTFOBins OR process.executable IN ( "/usr/bin/base64", @@ -132,12 +132,10 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index ) // Endpoint leg: extract SSM command ID from parent command line -// .../document/orchestration//AWS-RunShellScript/... | DISSECT process.parent.command_line "%{}/document/orchestration/%{Esql.process_parent_command_line_ssm_command_id}/%{}" // CloudTrail leg: extract SSM command ID from response_elements -// ...commandId=,... | DISSECT aws.cloudtrail.response_elements "%{}commandId=%{Esql.aws_cloudtrail_response_elements_ssm_command_id},%{}" @@ -174,7 +172,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index Esql.aws_cloudtrail_first_event_ts = MIN(CASE(Esql.is_cloud_event, @timestamp, null)), Esql.endpoint_events_process_first_lolbin_ts = MIN(CASE(Esql.is_lolbin_process, @timestamp, null)), - // AWS / CloudTrail identity & request context (PII → Esql_priv.) + // AWS / CloudTrail identity & request context Esql_priv.aws_cloudtrail_user_identity_arn_values = VALUES(CASE(Esql.is_cloud_event, aws.cloudtrail.user_identity.arn, null)), Esql_priv.aws_cloudtrail_user_identity_access_key_id_values = @@ -221,7 +219,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index Esql.aws_cloudtrail_first_event_ts ) <= 5 | SORT Esql.aws_cloudtrail_first_event_ts ASC -| KEEP Esql.*, Esql_priv.* +| KEEP Esql.*, Esql_priv.*, @timestamp ''' From 37fbac5322a7c6a2280dc178569e440a11ae02bc Mon Sep 17 00:00:00 2001 From: terrancedejesus Date: Mon, 24 Nov 2025 18:58:12 -0500 Subject: [PATCH 10/10] updating query logic to use coalesce --- .../execution_aws_ec2_lolbin_via_ssm.toml | 55 +++++++++---------- 1 file changed, 25 insertions(+), 30 deletions(-) diff --git a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml index 692d5f2e628..d66ad8b04ae 100644 --- a/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml +++ b/rules/cross-platform/execution_aws_ec2_lolbin_via_ssm.toml @@ -74,9 +74,9 @@ references = [ "https://hackingthe.cloud/aws/post_exploitation/run_shell_commands_on_ec2/", "https://gtfobins.github.io/", ] -risk_score = 73 +risk_score = 47 rule_id = "a8b3e2f0-8c7d-11ef-b4c6-f661ea17fbcd" -severity = "high" +severity = "medium" tags = [ "Domain: Cloud", "Domain: Endpoint", @@ -109,24 +109,23 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index AND host.os.type == "linux" AND ( // SSM shell (_script.sh) runner - process.command_line LIKE "*/document/orchestration/%/awsrunShellScript/*/_script.sh" + process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh" // LOLBins / GTFOBins - OR process.executable IN ( - "/usr/bin/base64", - "/usr/bin/curl", - "/usr/bin/wget", - "/usr/bin/openssl", - "/usr/bin/nc", "/bin/nc", - "/usr/bin/ncat", "/usr/bin/netcat", - "/usr/bin/socat", - "/usr/bin/python", "/usr/bin/python3", - "/usr/bin/perl", - "/usr/bin/php", - "/usr/bin/ruby", - "/usr/bin/ssh", - "/usr/bin/scp", - "/usr/bin/sftp", - "/usr/bin/rsync" + OR process.name IN ( + "base64", + "curl", + "wget", + "openssl", + "nc", "ncat", "netcat", + "socat", + "python", "python3", + "perl", + "php", + "ruby", + "ssh", + "scp", + "sftp", + "rsync" ) ) ) @@ -139,15 +138,11 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index | DISSECT aws.cloudtrail.response_elements "%{}commandId=%{Esql.aws_cloudtrail_response_elements_ssm_command_id},%{}" -// Normalize into a single SSM command id -| EVAL Esql.aws_ssm_command_id = - CASE( - event.dataset == "aws.cloudtrail", Esql.aws_cloudtrail_response_elements_ssm_command_id, - CASE( - event.dataset == "endpoint.events.process", Esql.process_parent_command_line_ssm_command_id, - null - ) - ) +// Coalesce SSM command ID from both data sources +| EVAL Esql.aws_ssm_command_id = COALESCE( + Esql.aws_cloudtrail_response_elements_ssm_command_id, + Esql.process_parent_command_line_ssm_command_id +) | WHERE Esql.aws_ssm_command_id IS NOT NULL // Role flags @@ -157,7 +152,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index // Identify the SSM shell processes (the _script.sh runners) | EVAL Esql.is_ssm_shell_process = Esql.is_endpoint_event - AND process.command_line LIKE "*/document/orchestration/*/awsrunShellScript/*/_script.sh" + AND process.command_line LIKE "%/document/orchestration/%/awsrunShellScript/%/_script.sh" // LOLBins / GTFOBins on Linux | EVAL Esql.is_lolbin_process = @@ -219,7 +214,7 @@ FROM logs-aws.cloudtrail*, logs-endpoint.* METADATA _id, _version, _index Esql.aws_cloudtrail_first_event_ts ) <= 5 | SORT Esql.aws_cloudtrail_first_event_ts ASC -| KEEP Esql.*, Esql_priv.*, @timestamp +| KEEP Esql.*, Esql_priv.* '''