AWS SageMaker Notebook Lifecycle Configuration With Suspicious Script Content
Identifies an Amazon SageMaker notebook lifecycle configuration whose OnStart or OnCreate script, after base64 decoding, contains patterns associated with malicious activity such as reverse shells, EC2 instance metadata (IMDS) credential access, or download-and-execute commands. A lifecycle configuration runs as root on the notebook instance, so a script with these patterns is a strong indicator of an attempt to backdoor the notebook, steal the execution role's credentials, or establish persistent code execution. This rule decodes the script in the request and matches high-signal indicators; it is a higher-fidelity companion to the rule that alerts on any lifecycle configuration change.
Elastic rule (View on GitHub)
1[metadata]
2creation_date = "2026/06/29"
3integration = ["aws"]
4maturity = "production"
5updated_date = "2026/06/29"
6
7[rule]
8author = ["Elastic"]
9description = """
10Identifies an Amazon SageMaker notebook lifecycle configuration whose OnStart or OnCreate script, after base64 decoding,
11contains patterns associated with malicious activity such as reverse shells, EC2 instance metadata (IMDS) credential
12access, or download-and-execute commands. A lifecycle configuration runs as root on the notebook instance, so a script
13with these patterns is a strong indicator of an attempt to backdoor the notebook, steal the execution role's
14credentials, or establish persistent code execution. This rule decodes the script in the request and matches high-signal
15indicators; it is a higher-fidelity companion to the rule that alerts on any lifecycle configuration change.
16"""
17false_positives = [
18 """
19 Legitimate setup scripts may reference metadata endpoints or download tooling. Review the decoded script in
20 "Esql_priv.aws_cloudtrail_lifecycle_script", verify the principal in "aws.cloudtrail.user_identity.arn", and confirm
21 the activity is approved. Note this rule only matches unobfuscated patterns; a clean result does not guarantee a
22 benign script.
23 """,
24]
25from = "now-60m"
26interval = "10m"
27language = "esql"
28license = "Elastic License v2"
29name = "AWS SageMaker Notebook Lifecycle Configuration With Suspicious Script Content"
30note = """## Triage and analysis
31
32### Investigating AWS SageMaker Notebook Lifecycle Configuration With Suspicious Script Content
33
34A SageMaker notebook lifecycle configuration is a shell script that runs as root on the notebook instance at create or start. This rule base64-decodes the OnStart/OnCreate script from the request (surfaced as "Esql_priv.aws_cloudtrail_lifecycle_script") and flags high-signal indicators across several categories: reverse shells ("/dev/tcp/", "/dev/udp/", "bash -i", "nc -e", "ncat", "socat", "mkfifo", "import socket", "pty.spawn", "perl"/"ruby"/"php" socket idioms), IMDS credential access ("169.254.169.254", "/latest/meta-data/", "/latest/api/token"), download-and-execute and decode-and-execute ("| sh", "| bash", "base64 -d"), cryptominers ("xmrig", "minerd", "stratum+"), and persistence ("authorized_keys", "crontab", "/etc/cron"). A match is a strong indicator of an implant attempt.
35
36### Possible investigation steps
37
38- Review the decoded "Esql_priv.aws_cloudtrail_lifecycle_script" field and the full "aws.cloudtrail.request_parameters" to understand what the script does.
39- Identify the actor in "aws.cloudtrail.user_identity.arn" and review "source.ip" and "user_agent.original" for an unexpected origin.
40- Determine which notebook instances reference this configuration and whether they have started since the change.
41- Correlate with adjacent activity by the same principal, such as notebook creation, presigned URL generation, or use of the execution role's credentials outside SageMaker.
42
43### False positive analysis
44
45- Setup scripts can legitimately reference metadata endpoints or download tooling. Confirm the script is expected and exclude known automation roles after validation. This rule only matches unobfuscated indicators, so it can miss obfuscated scripts (use the broad lifecycle-configuration-change rule for full coverage) and can match benign scripts that contain these strings.
46
47### Response and remediation
48
49- If unauthorized, remove the lifecycle configuration, stop affected notebook instances, and rotate the notebook execution role's credentials.
50- Review actions taken by the execution role since the change, and restrict "sagemaker:CreateNotebookInstanceLifecycleConfig" and "sagemaker:UpdateNotebookInstanceLifecycleConfig" to trusted administrators.
51"""
52references = ["https://docs.aws.amazon.com/sagemaker/latest/dg/notebook-lifecycle-config.html"]
53risk_score = 73
54rule_id = "0471a12b-c740-4a72-91f0-12bf95014d3c"
55setup = "This rule requires AWS CloudTrail logs ingested via the Elastic AWS integration. See https://docs.elastic.co/integrations/aws/cloudtrail for setup details."
56severity = "high"
57tags = [
58 "Domain: Cloud",
59 "Data Source: AWS",
60 "Data Source: Amazon Web Services",
61 "Data Source: AWS SageMaker",
62 "Use Case: Threat Detection",
63 "Tactic: Persistence",
64 "Tactic: Execution",
65 "Resources: Investigation Guide",
66]
67timestamp_override = "event.ingested"
68type = "esql"
69
70query = '''
71FROM logs-aws.cloudtrail-* METADATA _id, _version, _index
72| WHERE event.provider == "sagemaker.amazonaws.com"
73 AND event.action IN ("CreateNotebookInstanceLifecycleConfig", "UpdateNotebookInstanceLifecycleConfig")
74 AND event.outcome == "success"
75 AND aws.cloudtrail.user_identity.type != "AWSService"
76| GROK aws.cloudtrail.request_parameters "[Cc]ontent=(?<script_b64>[A-Za-z0-9+/=]+)"
77| EVAL Esql_priv.aws_cloudtrail_lifecycle_script = FROM_BASE64(script_b64)
78| WHERE TO_LOWER(Esql_priv.aws_cloudtrail_lifecycle_script) RLIKE """.*(/dev/tcp/|/dev/udp/|bash -i|sh -i|nc -e|ncat |socat |mkfifo|169\.254\.169\.254|/latest/meta-data/|/latest/api/token|\| ?sh|\| ?bash|base64 -d|import socket|pty\.spawn|perl -e|ruby -rsocket|php -r|xmrig|minerd|stratum\+|authorized_keys|/etc/cron|crontab ).*"""
79| KEEP _id, _version, _index, @timestamp, aws.*, cloud.*, event.*, source.*, user.*, user_agent.*, Esql_priv.aws_cloudtrail_lifecycle_script
80'''
81
82
83[[rule.threat]]
84framework = "MITRE ATT&CK"
85[[rule.threat.technique]]
86id = "T1546"
87name = "Event Triggered Execution"
88reference = "https://attack.mitre.org/techniques/T1546/"
89
90
91[rule.threat.tactic]
92id = "TA0003"
93name = "Persistence"
94reference = "https://attack.mitre.org/tactics/TA0003/"
95[[rule.threat]]
96framework = "MITRE ATT&CK"
97[[rule.threat.technique]]
98id = "T1059"
99name = "Command and Scripting Interpreter"
100reference = "https://attack.mitre.org/techniques/T1059/"
101[[rule.threat.technique.subtechnique]]
102id = "T1059.004"
103name = "Unix Shell"
104reference = "https://attack.mitre.org/techniques/T1059/004/"
105
106
107
108[rule.threat.tactic]
109id = "TA0002"
110name = "Execution"
111reference = "https://attack.mitre.org/tactics/TA0002/"
112
113[rule.investigation_fields]
114field_names = [
115 "@timestamp",
116 "aws.cloudtrail.user_identity.arn",
117 "aws.cloudtrail.user_identity.type",
118 "source.ip",
119 "cloud.account.id",
120 "event.action",
121 "Esql_priv.aws_cloudtrail_lifecycle_script",
122 "aws.cloudtrail.request_parameters",
123]
Triage and analysis
Investigating AWS SageMaker Notebook Lifecycle Configuration With Suspicious Script Content
A SageMaker notebook lifecycle configuration is a shell script that runs as root on the notebook instance at create or start. This rule base64-decodes the OnStart/OnCreate script from the request (surfaced as "Esql_priv.aws_cloudtrail_lifecycle_script") and flags high-signal indicators across several categories: reverse shells ("/dev/tcp/", "/dev/udp/", "bash -i", "nc -e", "ncat", "socat", "mkfifo", "import socket", "pty.spawn", "perl"/"ruby"/"php" socket idioms), IMDS credential access ("169.254.169.254", "/latest/meta-data/", "/latest/api/token"), download-and-execute and decode-and-execute ("| sh", "| bash", "base64 -d"), cryptominers ("xmrig", "minerd", "stratum+"), and persistence ("authorized_keys", "crontab", "/etc/cron"). A match is a strong indicator of an implant attempt.
Possible investigation steps
- Review the decoded "Esql_priv.aws_cloudtrail_lifecycle_script" field and the full "aws.cloudtrail.request_parameters" to understand what the script does.
- Identify the actor in "aws.cloudtrail.user_identity.arn" and review "source.ip" and "user_agent.original" for an unexpected origin.
- Determine which notebook instances reference this configuration and whether they have started since the change.
- Correlate with adjacent activity by the same principal, such as notebook creation, presigned URL generation, or use of the execution role's credentials outside SageMaker.
False positive analysis
- Setup scripts can legitimately reference metadata endpoints or download tooling. Confirm the script is expected and exclude known automation roles after validation. This rule only matches unobfuscated indicators, so it can miss obfuscated scripts (use the broad lifecycle-configuration-change rule for full coverage) and can match benign scripts that contain these strings.
Response and remediation
- If unauthorized, remove the lifecycle configuration, stop affected notebook instances, and rotate the notebook execution role's credentials.
- Review actions taken by the execution role since the change, and restrict "sagemaker:CreateNotebookInstanceLifecycleConfig" and "sagemaker:UpdateNotebookInstanceLifecycleConfig" to trusted administrators.
References
Related rules
- AWS IAM Inline Policy Added to a Group
- AWS Lambda Function Invoked Cross-Account
- AWS Lambda Function Invoked from an Unusual Source ASN
- AWS Lambda Function Invoked by an Unusual Principal
- AWS Lambda Function Policy Updated to Allow Cross-Account Invocation