Skip to content

Commit 34da4f2

Browse files
committed
Merge branch 'additional_genai_coverage' of https://github.com/elastic/detection-rules into additional_genai_coverage
2 parents 55c41fb + 3e43fa4 commit 34da4f2

File tree

26 files changed

+750
-181
lines changed

26 files changed

+750
-181
lines changed

rules/cross-platform/defense_evasion_genai_process_encoding_prior_to_network_activity.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ communications.
1515
from = "now-9m"
1616
index = [
1717
"logs-endpoint.events.process-*",
18+
"logs-endpoint.events.network-*",
1819
"logs-windows.sysmon_operational-*",
1920
"winlogbeat-*",
2021
"logs-m365_defender.event-*",
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
[metadata]
2+
creation_date = "2025/12/02"
3+
integration = ["nginx", "apache", "apache_tomcat", "iis"]
4+
maturity = "production"
5+
min_stack_version = "9.2.0"
6+
min_stack_comments = "The esql url_decode() operator was introduced in version 9.2.0"
7+
updated_date = "2025/12/02"
8+
9+
[rule]
10+
author = ["Elastic"]
11+
description = """
12+
This rule detects potential Local File Inclusion (LFI) activity on web servers by identifying HTTP GET requests that
13+
attempt to access sensitive local files through directory traversal techniques or known file paths. Attackers may
14+
exploit LFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.
15+
"""
16+
from = "now-11m"
17+
interval = "10m"
18+
language = "esql"
19+
license = "Elastic License v2"
20+
name = "Web Server Local File Inclusion Activity"
21+
risk_score = 21
22+
rule_id = "90e4ceab-79a5-4f8e-879b-513cac7fcad9"
23+
severity = "low"
24+
tags = [
25+
"Domain: Web",
26+
"Use Case: Threat Detection",
27+
"Tactic: Discovery",
28+
"Data Source: Nginx",
29+
"Data Source: Apache",
30+
"Data Source: Apache Tomcat",
31+
"Data Source: IIS",
32+
]
33+
timestamp_override = "event.ingested"
34+
type = "esql"
35+
query = '''
36+
from
37+
logs-nginx.access-*,
38+
logs-apache.access-*,
39+
logs-apache_tomcat.access-*,
40+
logs-iis.access-*
41+
| where
42+
http.request.method == "GET" and
43+
http.response.status_code == 200 and
44+
url.original like "*=*"
45+
46+
| eval Esql.url_original_url_decoded_to_lower = to_lower(URL_DECODE(url.original))
47+
48+
| where
49+
/* 1) Relative traversal */
50+
Esql.url_original_url_decoded_to_lower like "*../../../../*" or // Unix-style traversal
51+
Esql.url_original_url_decoded_to_lower like "*..\\\\..\\\\..\\\\..*" or // Windows-style traversal
52+
// Potential security check bypassing (enforcing multiple dots and shortening the pattern)
53+
Esql.url_original_url_decoded_to_lower like "*..././*" or
54+
Esql.url_original_url_decoded_to_lower like "*...\\*" or
55+
Esql.url_original_url_decoded_to_lower like "*....\\*" or
56+
57+
/* 2) Linux system identity / basic info */
58+
Esql.url_original_url_decoded_to_lower like "*etc/passwd*" or
59+
Esql.url_original_url_decoded_to_lower like "*etc/shadow*" or
60+
Esql.url_original_url_decoded_to_lower like "*etc/hosts*" or
61+
Esql.url_original_url_decoded_to_lower like "*etc/os-release*" or
62+
Esql.url_original_url_decoded_to_lower like "*etc/issue*" or
63+
64+
/* 3) Linux /proc enumeration */
65+
Esql.url_original_url_decoded_to_lower like "*proc/self/environ*" or
66+
Esql.url_original_url_decoded_to_lower like "*proc/self/cmdline*" or
67+
Esql.url_original_url_decoded_to_lower like "*proc/self/fd*" or
68+
Esql.url_original_url_decoded_to_lower like "*proc/self/exe*" or
69+
70+
/* 4) Linux webroots, configs & logs */
71+
Esql.url_original_url_decoded_to_lower like "*var/www*" or // generic webroot
72+
Esql.url_original_url_decoded_to_lower like "*wp-config.php*" or // classic WP config
73+
Esql.url_original_url_decoded_to_lower like "*etc/apache2*" or
74+
Esql.url_original_url_decoded_to_lower like "*etc/httpd*" or
75+
Esql.url_original_url_decoded_to_lower like "*etc/nginx*" or
76+
Esql.url_original_url_decoded_to_lower like "*var/log/apache2*" or
77+
Esql.url_original_url_decoded_to_lower like "*var/log/httpd*" or
78+
Esql.url_original_url_decoded_to_lower like "*var/log/nginx*" or
79+
80+
/* 5) Windows core files / identity */
81+
Esql.url_original_url_decoded_to_lower like "*windows/panther/*unattend*" or
82+
Esql.url_original_url_decoded_to_lower like "*windows/debug/netsetup.log*" or
83+
Esql.url_original_url_decoded_to_lower like "*windows/win.ini*" or
84+
Esql.url_original_url_decoded_to_lower like "*windows/system32/drivers/etc/hosts*" or
85+
Esql.url_original_url_decoded_to_lower like "*boot.ini*" or
86+
Esql.url_original_url_decoded_to_lower like "*windows/system32/config/*" or
87+
Esql.url_original_url_decoded_to_lower like "*windows/repair/sam*" or
88+
Esql.url_original_url_decoded_to_lower like "*windows/system32/license.rtf*" or
89+
90+
/* 6) Windows IIS / .NET configs, webroots & logs */
91+
Esql.url_original_url_decoded_to_lower like "*/inetpub/wwwroot*" or
92+
Esql.url_original_url_decoded_to_lower like "*/inetpub/logs/logfiles*" or
93+
Esql.url_original_url_decoded_to_lower like "*applicationhost.config*" or
94+
Esql.url_original_url_decoded_to_lower like "*/microsoft.net/framework64/*/config/web.config*" or
95+
Esql.url_original_url_decoded_to_lower like "*windows/system32/inetsrv/*" or
96+
97+
/* 7) PHP & protocol wrappers */
98+
Esql.url_original_url_decoded_to_lower like "*php://*" or
99+
Esql.url_original_url_decoded_to_lower like "*zip://*" or
100+
Esql.url_original_url_decoded_to_lower like "*phar://*" or
101+
Esql.url_original_url_decoded_to_lower like "*expect://*" or
102+
Esql.url_original_url_decoded_to_lower like "*file://*" or
103+
Esql.url_original_url_decoded_to_lower like "*data://text/plain;base64*"
104+
105+
| keep
106+
@timestamp,
107+
Esql.url_original_url_decoded_to_lower,
108+
source.ip,
109+
agent.id,
110+
host.name,
111+
http.request.method,
112+
http.response.status_code,
113+
event.dataset,
114+
data_stream.namespace
115+
116+
| stats
117+
Esql.event_count = count(),
118+
Esql.url_original_url_decoded_to_lower_count_distinct = count_distinct(Esql.url_original_url_decoded_to_lower),
119+
Esql.host_name_values = values(host.name),
120+
Esql.agent_id_values = values(agent.id),
121+
Esql.http_request_method_values = values(http.request.method),
122+
Esql.http_response_status_code_values = values(http.response.status_code),
123+
Esql.url_original_url_decoded_to_lower_values = values(Esql.url_original_url_decoded_to_lower),
124+
Esql.event_dataset_values = values(event.dataset),
125+
Esql.data_stream_namespace_values = values(data_stream.namespace)
126+
by source.ip
127+
'''
128+
129+
[[rule.threat]]
130+
framework = "MITRE ATT&CK"
131+
132+
[[rule.threat.technique]]
133+
id = "T1083"
134+
name = "File and Directory Discovery"
135+
reference = "https://attack.mitre.org/techniques/T1083/"
136+
137+
[rule.threat.tactic]
138+
id = "TA0007"
139+
name = "Discovery"
140+
reference = "https://attack.mitre.org/tactics/TA0007/"
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
[metadata]
2+
creation_date = "2025/12/02"
3+
integration = ["nginx", "apache", "apache_tomcat", "iis"]
4+
maturity = "production"
5+
min_stack_version = "9.2.0"
6+
min_stack_comments = "The esql url_decode() operator was introduced in version 9.2.0"
7+
updated_date = "2025/12/02"
8+
9+
[rule]
10+
author = ["Elastic"]
11+
description = """
12+
This rule detects potential Remote File Inclusion (RFI) activity on web servers by identifying HTTP GET requests that
13+
attempt to access sensitive remote files through directory traversal techniques or known file paths. Attackers may
14+
exploit RFI vulnerabilities to read sensitive files, gain system information, or further compromise the server.
15+
"""
16+
from = "now-11m"
17+
interval = "10m"
18+
language = "esql"
19+
license = "Elastic License v2"
20+
name = "Web Server Potential Remote File Inclusion Activity"
21+
risk_score = 21
22+
rule_id = "45d099b4-a12e-4913-951c-0129f73efb41"
23+
severity = "low"
24+
tags = [
25+
"Domain: Web",
26+
"Use Case: Threat Detection",
27+
"Tactic: Discovery",
28+
"Tactic: Command and Control",
29+
"Data Source: Nginx",
30+
"Data Source: Apache",
31+
"Data Source: Apache Tomcat",
32+
"Data Source: IIS",
33+
]
34+
timestamp_override = "event.ingested"
35+
type = "esql"
36+
query = '''
37+
from
38+
logs-nginx.access-*,
39+
logs-apache.access-*,
40+
logs-apache_tomcat.access-*,
41+
logs-iis.access-*
42+
| where
43+
http.request.method == "GET" and
44+
http.response.status_code == 200 and
45+
url.original like "*=*"
46+
47+
| eval Esql.url_original_url_decoded_to_lower = to_lower(URL_DECODE(url.original))
48+
49+
| where
50+
Esql.url_original_url_decoded_to_lower like "*=http://*" or
51+
Esql.url_original_url_decoded_to_lower like "*=https://*" or
52+
Esql.url_original_url_decoded_to_lower like "*=ftp://*" or
53+
Esql.url_original_url_decoded_to_lower like "*=smb://*" or
54+
Esql.url_original_url_decoded_to_lower like "*=file://*" or
55+
Esql.url_original_url_decoded_to_lower rlike """.*=.*[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}.*"""
56+
57+
| keep
58+
@timestamp,
59+
Esql.url_original_url_decoded_to_lower,
60+
source.ip,
61+
agent.id,
62+
host.name,
63+
http.request.method,
64+
http.response.status_code,
65+
event.dataset,
66+
data_stream.namespace
67+
68+
| stats
69+
Esql.event_count = count(),
70+
Esql.url_original_url_decoded_to_lower_count_distinct = count_distinct(Esql.url_original_url_decoded_to_lower),
71+
Esql.host_name_values = values(host.name),
72+
Esql.agent_id_values = values(agent.id),
73+
Esql.http_request_method_values = values(http.request.method),
74+
Esql.http_response_status_code_values = values(http.response.status_code),
75+
Esql.url_original_url_decoded_to_lower_values = values(Esql.url_original_url_decoded_to_lower),
76+
Esql.event_dataset_values = values(event.dataset),
77+
Esql.data_stream_namespace_values = values(data_stream.namespace)
78+
by source.ip
79+
'''
80+
81+
[[rule.threat]]
82+
framework = "MITRE ATT&CK"
83+
84+
[[rule.threat.technique]]
85+
id = "T1083"
86+
name = "File and Directory Discovery"
87+
reference = "https://attack.mitre.org/techniques/T1083/"
88+
89+
[rule.threat.tactic]
90+
id = "TA0007"
91+
name = "Discovery"
92+
reference = "https://attack.mitre.org/tactics/TA0007/"
93+
94+
[[rule.threat]]
95+
framework = "MITRE ATT&CK"
96+
97+
[rule.threat.tactic]
98+
id = "TA0011"
99+
name = "Command and Control"
100+
reference = "https://attack.mitre.org/tactics/TA0011/"
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
[metadata]
2+
creation_date = "2025/12/04"
3+
integration = ["endpoint", "windows", "auditd_manager", "sentinel_one_cloud_funnel"]
4+
maturity = "production"
5+
updated_date = "2025/12/05"
6+
7+
[rule]
8+
author = ["Elastic"]
9+
description = """
10+
This rule detects suspicious child process activity from a React server application. This could be related to successful
11+
exploitation of CVE-2025-55182 or CVE-2025-66478. These vulnerabilities allow attackers to execute remote code due to
12+
insecure deserialization of React Server Components (RSC) Flight payloads, leading to unauthenticated RCE on servers
13+
running React 19.x or Next.js 14.3.0-canary+, 15.x, and 16.x with the App Router enabled
14+
"""
15+
from = "now-9m"
16+
index = [
17+
"auditbeat-*",
18+
"logs-auditd_manager.auditd-*",
19+
"logs-endpoint.events.process*",
20+
"logs-sentinel_one_cloud_funnel.*",
21+
"logs-windows.sysmon_operational-*"
22+
]
23+
language = "eql"
24+
license = "Elastic License v2"
25+
name = "Suspicious React Server Child Process"
26+
note = """## Triage and analysis
27+
28+
> **Disclaimer**:
29+
> This investigation guide was created using generative AI technology and has been reviewed to improve its accuracy and relevance. While every effort has been made to ensure its quality, we recommend validating the content and adapting it to suit your specific environment and operational needs.
30+
31+
### Investigating Suspicious React Server Child Process
32+
33+
This rule flags suspicious shell or system utility processes spawned by a React or Next.js server application—clear evidence of CVE-2025-55182 or CVE-2025-66478 exploitation enabling arbitrary code execution. An attacker sends a specially crafted RSC Flight protocol payload to a vulnerable Next.js or React Server Components endpoint, causing the server to deserialize untrusted data and execute attacker-controlled JavaScript, which then spawns shell commands or system utilities to establish initial access and persistence.
34+
35+
### Possible investigation steps
36+
37+
- Extract the parent Node.js process command line and working directory to identify the React or Next.js application, then check package.json or package-lock.json for React version (19.0-19.2) and Next.js version (14.3.0-canary, 15.x, 16.x) to confirm vulnerability.
38+
- Review web server access logs (Nginx, Apache, ALB) for suspicious POST requests to RSC endpoints (/_next/data/, /.next/, /api/) in the minutes before the shell spawn, focusing on requests with unusual Content-Type headers (text/x-component, application/rsc) or large payload sizes.
39+
- Analyze the spawned child process command line, arguments, working directory, and any downloaded files or scripts to identify the payload type (reverse shell, data exfiltration, credential theft, persistence mechanism) and compute file hashes for threat intelligence correlation.
40+
- Pivot on the source IP address from web logs across other hosts and applications to identify additional compromised servers, and check for lateral movement attempts or scanning activity from the compromised host to internal networks.
41+
- Examine the host for post-exploitation artifacts including new cron jobs, modified .bashrc/.profile files, SSH authorized_keys additions, new user accounts, unusual network connections to external IPs, files in /tmp or /var/tmp directories, and container escape attempts (nsenter, docker socket access).
42+
43+
### False positive analysis
44+
45+
- Legitimate build or deployment scripts triggered by CI/CD pipelines may cause Next.js build workers (jest-worker/processChild.js) to spawn shell commands; filter these by excluding processes with --node-ipc flags or running in /builds/, /workspace/, or other CI directories.
46+
- Development servers (next dev, expo start, react-scripts start) running on developer workstations may spawn legitimate shells for tooling; consider excluding NODE_ENV=development or processes running from user home directories if appropriate for your environment.
47+
- Server-side rendering (SSR) frameworks may legitimately invoke system utilities for image processing, PDF generation, or other server-side tasks; maintain an allowlist of expected child processes and their arguments for known applications.
48+
49+
### Response and remediation
50+
51+
- Immediately isolate the affected host to prevent lateral movement, terminate the Node.js parent process and all child processes spawned from the React/Next.js server, and block the source IP address at the firewall and WAF level.
52+
- Remove any persistence mechanisms installed by the attacker including cron jobs (check crontab -l for all users), modified shell initialization files (~/.bashrc, ~/.profile, /etc/profile.d/), SSH keys in ~/.ssh/authorized_keys, and systemd timers or service units.
53+
- Rotate all credentials and secrets accessible to the compromised application including database passwords, API keys, cloud service credentials (AWS/Azure/GCP), and session tokens, assuming they may have been exfiltrated.
54+
- Collect forensic artifacts including memory dumps of the Node.js process (if still running), packet captures of the malicious HTTP request, web server access and error logs, application logs from the React/Next.js server, and copies of any files created in /tmp, /var/tmp, or the application directory.
55+
- Escalate to incident command if the attacker achieved container escape (nsenter usage detected), accessed sensitive data or credentials, established C2 communication to external infrastructure, or if multiple hosts show similar exploitation patterns from the same source.
56+
- Patch immediately by upgrading React to version 19.0.1+, 19.1.2+, or 19.2.1+, and Next.js to versions 14.3.0-canary.88+, 15.0.5+, 15.1.9+, 15.2.6+, 15.3.6+, 15.4.8+, 15.5.7+, or 16.0.7+ depending on your major version, and deploy WAF rules to block malformed RSC payloads at the application edge.
57+
"""
58+
references = [
59+
"https://www.wiz.io/blog/critical-vulnerability-in-react-cve-2025-55182"
60+
]
61+
risk_score = 73
62+
rule_id = "ae3e9625-89ad-4fc3-a7bf-fced5e64f01b"
63+
severity = "high"
64+
tags = [
65+
"Domain: Endpoint",
66+
"OS: Linux",
67+
"OS: macOS",
68+
"OS: Windows",
69+
"Use Case: Threat Detection",
70+
"Tactic: Initial Access",
71+
"Data Source: Elastic Defend",
72+
"Data Source: Auditd Manager",
73+
"Data Source: SentinelOne",
74+
"Data Source: Sysmon",
75+
"Resources: Investigation Guide",
76+
]
77+
timestamp_override = "event.ingested"
78+
type = "eql"
79+
query = '''
80+
process where event.type == "start" and event.action != "fork" and (
81+
process.name in (
82+
"sh", "bash", "zsh", "curl", "wget", "id", "whoami", "uname", "cmd.exe", "cat", "powershell.exe", "java", "rundll32.exe", "wget.exe", "certutil.exe",
83+
"nc", "ncat", "netcat", "nc.openbsd", "nc.traditional", "socat", "busybox", "mkfifo", "nohup", "setsid", "xterm"
84+
) or
85+
(process.name : "python*" and process.args : "-c" and process.args : (
86+
"*import*pty*spawn*", "*import*subprocess*call*"
87+
)) or
88+
(process.name : "perl*" and process.args : "-e" and process.args : "*socket*" and process.args : (
89+
"*exec*", "*system*"
90+
)) or
91+
(process.name : "ruby*" and process.args : ("-e", "-rsocket") and process.args : (
92+
"*TCPSocket.new*", "*TCPSocket.open*"
93+
)) or
94+
(process.name : "lua*" and process.args : "-e" and process.args : "*socket.tcp*" and process.args : (
95+
"*io.popen*", "*os.execute*"
96+
)) or
97+
(process.name : "php*" and process.args : "-r" and process.args : "*fsockopen*" and process.args : "*/bin/*sh*") or
98+
(process.name == "node" and process.args == "-e" and process.args : "*spawn*sh*" and process.args : "*connect*") or
99+
(process.name : ("awk", "gawk", "mawk", "nawk") and process.args : "*/inet/tcp/*") or
100+
(process.name in ("rvim", "vim", "vimdiff", "rview", "view") and process.args == "-c" and process.args : "*socket*")
101+
)
102+
and (
103+
?process.working_directory : (
104+
"*react-dom*", "*.next*", "*node_modules/next*", "*react-server*", "*bin/next*", "*--experimental-https*", "*app/server*",
105+
"*.pnpm/next*", "*/app/*", "*next/dist/server*", "*react-scripts*") or
106+
(
107+
process.parent.name in ("node", "bun", "node.exe", "bun.exe") and
108+
process.parent.command_line : (
109+
"*react-dom*", "*.next*", "*node_modules/next*", "*react-server*", "*next-server*", "*server.js*", "*bin/next*",
110+
"*--experimental-https*", "*app/server*", "*.pnpm/next*", "*next start*", "*next dev*", "*react-scripts start*", "*next/dist/server*"
111+
)
112+
)
113+
) and not (
114+
?process.parent.executable in ("./runc", "/opt/google/chrome/chrome") or
115+
process.command_line like "/bin/sh -c git config*"
116+
)
117+
'''
118+
119+
[[rule.threat]]
120+
framework = "MITRE ATT&CK"
121+
122+
[[rule.threat.technique]]
123+
id = "T1190"
124+
name = "Exploit Public-Facing Application"
125+
reference = "https://attack.mitre.org/techniques/T1190/"
126+
127+
[rule.threat.tactic]
128+
id = "TA0001"
129+
name = "Initial Access"
130+
reference = "https://attack.mitre.org/tactics/TA0001/"

0 commit comments

Comments
 (0)