Skip to content

Commit ff2ecad

Browse files
[New Rule] Adding Coverage for AWS S3 Static Site JavaScript File Uploaded (#4617)
* new rule 'AWS S3 Static Site JavaScript File Uploaded' * adjusting name * updated keep command --------- Co-authored-by: Jonhnathan <[email protected]>
1 parent ba959f2 commit ff2ecad

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
[metadata]
2+
creation_date = "2025/04/15"
3+
integration = ["aws"]
4+
maturity = "production"
5+
updated_date = "2025/04/15"
6+
7+
[rule]
8+
author = ["Elastic"]
9+
description = """
10+
This rule detects when a JavaScript file is uploaded or accessed in an S3 static site directory (`static/js/`) by an IAM
11+
user or assumed role. This can indicate suspicious modification of web content hosted on S3, such as injecting malicious scripts into a
12+
static website frontend.
13+
"""
14+
false_positives = [
15+
"""
16+
Development or deployment pipelines that update static frontends frequently (e.g., React/Vue apps) may trigger this.
17+
Verify the user agent, source IP, and whether the modification was expected.
18+
""",
19+
]
20+
from = "now-9m"
21+
language = "esql"
22+
license = "Elastic License v2"
23+
name = "AWS S3 Static Site JavaScript File Uploaded"
24+
note = """## Triage and Analysis
25+
26+
### Investigating AWS S3 Static Site JavaScript File Uploaded
27+
28+
An S3 `PutObject` action that targets a path like `static/js/` and uploads a `.js` file is a potential signal for web content modification. If done by an unexpected IAM user or outside of CI/CD workflows, it may indicate a compromise.
29+
30+
#### Possible Investigation Steps
31+
32+
- **Identify the Source User**: Check `aws.cloudtrail.user_identity.arn`, access key ID, and session type (`IAMUser`, `AssumedRole`, etc).
33+
- **Review File Content**: Use the S3 `GetObject` or CloudTrail `requestParameters` to inspect the uploaded file for signs of obfuscation or injection.
34+
- **Correlate to Other Events**: Review events from the same IAM user before and after the upload (e.g., `ListBuckets`, `GetCallerIdentity`, IAM activity).
35+
- **Look for Multiple Uploads**: Attackers may attempt to upload several files or modify multiple directories.
36+
37+
### False Positive Analysis
38+
39+
- This behavior may be expected during app deployments. Look at:
40+
- The `user_agent.original` to detect legitimate CI tools (like Terraform or GitHub Actions).
41+
- Timing patterns—does this match a regular release window?
42+
- The origin IP and device identity.
43+
44+
### Response and Remediation
45+
46+
- **Revert Malicious Code**: Replace the uploaded JS file with a clean version and invalidate CloudFront cache if applicable.
47+
- **Revoke Access**: If compromise is confirmed, revoke the IAM credentials and disable the user.
48+
- **Audit IAM Policies**: Ensure that only deployment users can modify static site buckets.
49+
- **Enable Bucket Versioning**: This can allow for quick rollback and historical review.
50+
"""
51+
references = [
52+
"https://www.sygnia.co/blog/sygnia-investigation-bybit-hack/",
53+
"https://docs.aws.amazon.com/AmazonS3/latest/userguide/WebsiteHosting.html",
54+
"https://docs.aws.amazon.com/AmazonS3/latest/API/API_PutObject.html",
55+
]
56+
risk_score = 47
57+
rule_id = "16acac42-b2f9-4802-9290-d6c30914db6e"
58+
severity = "medium"
59+
tags = [
60+
"Domain: Cloud",
61+
"Data Source: AWS",
62+
"Data Source: Amazon Web Services",
63+
"Data Source: AWS S3",
64+
"Tactic: Impact",
65+
"Use Case: Web Application Compromise",
66+
"Use Case: Cloud Threat Detection",
67+
"Resources: Investigation Guide",
68+
]
69+
timestamp_override = "event.ingested"
70+
type = "esql"
71+
72+
query = '''
73+
from logs-aws.cloudtrail* metadata _id, _version, _index
74+
| where
75+
76+
// filter on CloudTrail logs for S3 PutObject actions
77+
event.dataset == "aws.cloudtrail"
78+
and event.provider == "s3.amazonaws.com"
79+
and event.action in ("GetObject","PutObject")
80+
81+
// filter for IAM users, not federated identities
82+
and aws.cloudtrail.user_identity.type in ("IAMUser", "AssumedRole")
83+
84+
// filter for S3 static site bucket paths from webpack or similar
85+
and aws.cloudtrail.request_parameters LIKE "*static/js/*.js*"
86+
87+
// exclude common IaC tools and automation scripts
88+
and not (
89+
user_agent.original LIKE "*Terraform*"
90+
or user_agent.original LIKE "*Ansible*"
91+
or user_agent.original LIKE "*Pulumni*"
92+
)
93+
94+
// extract bucket and object details from request parameters
95+
| dissect aws.cloudtrail.request_parameters "%{{?bucket.name.key}=%{bucket.name}, %{?host.key}=%{bucket.host}, %{?bucket.object.location.key}=%{bucket.object.location}}"
96+
97+
// filter for specific bucket and object structure
98+
| dissect bucket.object.location "%{}static/js/%{bucket.object}"
99+
100+
// filter for JavaScript files
101+
| where ENDS_WITH(bucket.object, ".js")
102+
| keep
103+
aws.cloudtrail.user_identity.arn,
104+
aws.cloudtrail.user_identity.access_key_id,
105+
aws.cloudtrail.user_identity.type,
106+
aws.cloudtrail.request_parameters,
107+
bucket.name,
108+
bucket.object,
109+
user_agent.original,
110+
source.ip,
111+
event.action,
112+
@timestamp
113+
'''
114+
115+
116+
[[rule.threat]]
117+
framework = "MITRE ATT&CK"
118+
[[rule.threat.technique]]
119+
id = "T1565"
120+
name = "Data Manipulation"
121+
reference = "https://attack.mitre.org/techniques/T1565/"
122+
[[rule.threat.technique.subtechnique]]
123+
id = "T1565.001"
124+
name = "Stored Data Manipulation"
125+
reference = "https://attack.mitre.org/techniques/T1565/001/"
126+
127+
128+
129+
[rule.threat.tactic]
130+
id = "TA0040"
131+
name = "Impact"
132+
reference = "https://attack.mitre.org/tactics/TA0040/"
133+

0 commit comments

Comments
 (0)