豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

[Rule Tuning] Suspicious Child Execution via Web Server (f16fca20-4d6c-43f9-aec1-20b6de3b0aeb) #5815

@tradebot-elastic

Description

@tradebot-elastic

Rule Tuning Analysis

Rule ID: f16fca20-4d6c-43f9-aec1-20b6de3b0aeb
Rule Name: Suspicious Child Execution via Web Server
Rule Type: eql


Classification

Metric Value
Category NOISY_PERFORMANT
Priority MEDIUM
Tuning Score 47.02
Version Status ✅ Established (5 release cycles)

Alert Telemetry

Metric Value
Total Alerts (3d) 54,979
Unique Clusters 21
Cluster Coverage 0.8%
Daily Average 18326
Days Active 3
Coefficient of Variation 0.47 (MODERATE)

Analysis Flags

  • 🔴 Noisy on Latest Version: ✅ Yes
  • 🔴 Widespread False Positive: ❌ No
  • ⚠️ Version Regression: ❌ No
  • ⚠️ Stale and Noisy: ❌ No
  • ⚠️ Low Version / High Volume: ❌ No
  • ℹ️ Low Activity: ❌ No

Recommendation

Action: Add EQL-safe exceptions to exclude known benign Apache OCF (Pacemaker/Heartbeat) monitor executions and the repeated localhost/INTERFACE_HTTPS_PORT curl health-check pattern seen in Events 1–4.

Rationale: The rule is generating extreme noise primarily from benign web-stack health checks where web-facing service accounts (e.g., www-data) spawn network clients (curl/wget) against localhost/127.0.0.1, and from Pacemaker/Heartbeat Apache OCF monitoring scripts that routinely execute curl/wget. These behaviors match the rule’s “suspicious tools” list but are not indicative of web shells in the provided evidence. Add highly specific exclusions for the identified monitor/health-check command lines/paths, and consider tightening the “web server context” clause to reduce non–web-server-parented matches.

Query Modifications

Over-broad web-server context: user.name/user.id OR-conditions can match processes not actually spawned by a web server parent, increasing benign matches. (Impact: accuracy)

Current:

process where ... and (
  process.parent.name like (...) or
  user.name in (...) or
  user.id in (...) or
  (process.name == "java" and ?process.working_directory like "/u0?/*")
) and (...)

Modify →

process where ... and (
  process.parent.name like (
    "apache", "nginx", "apache2", "httpd", "lighttpd", "caddy", "php-fpm*", "mongrel_rails", "haproxy",
    "gunicorn", "uwsgi", "openresty", "cherokee", "h2o", "resin", "puma", "unicorn", "traefik", "uvicorn",
    "tornado", "hypercorn", "daphne", "twistd", "yaws", "webfsd", "httpd.worker", "flask", "rails", "mongrel",
    "php-cgi", "php-fcgi", "php-cgi.cagefs", "catalina.sh", "hiawatha", "lswsctrl"
  )
  or (
    (user.name in ("apache", "www-data", "httpd", "nginx", "lighttpd", "tomcat", "tomcat8", "tomcat9") or user.id in ("33", "498", "48"))
    and process.parent.name in ("sh", "bash", "dash", "ash", "ksh", "zsh", "busybox")
  )
  or (process.parent.name == "java" and ?process.parent.working_directory like "/u0?/*")
) and (...)

This keeps true web-server-parented executions, but when using service accounts (www-data/apache) as the indicator, it requires the parent to be a shell (common for -c command execution from web apps) instead of matching any parent (e.g., cron/systemd), reducing non-web execution noise while preserving the web-shell execution mechanism.

Performance/precision: large like~ list mixes exact names with wildcard patterns; exact matches are faster and clearer as in (...). (Impact: performance)

Current:

process.name like~ (
  ".*",
  "*.elf", "*.sh", "*.py", ...,
  "systemd", "cron", "crond",
  "nc", "netcat", ...,
  "curl", "wget", ...
)

Modify →

(
  process.name like~ (".*", "*.elf", "*.sh", "*.py", "*.rb", "*.pl", "*.lua*", "*.php*", "*.js")
  or process.name in (
    "systemd", "cron", "crond",
    "nc", "netcat", "ncat", "telnet", "socat", "openssl", "nc.openbsd", "ngrok", "nc.traditional",
    "az", "gcloud", "aws",
    "whoami", "ifconfig", "ip", "ss", "top", "htop", "df", "du", "lsblk", "lsof", "tcpdump",
    "strace", "ltrace", "curl", "wget", "dig", "nslookup", "host", "nmap", "arp", "traceroute"
  )
)

Separating wildcard patterns from exact-name checks reduces wildcard evaluation overhead and makes it easier to surgically tune noisy tools (e.g., curl/wget) without affecting wildcard-based detections for dropped scripts/binaries.

The special-case java condition is currently applied to the child process rather than the parent, which can unintentionally match normal Java apps. (Impact: both)

Current:

(process.name == "java" and ?process.working_directory like "/u0?/*")

Modify →

(process.parent.name == "java" and ?process.parent.working_directory like "/u0?/*")

The rule intent appears to be identifying web/app-server parents (Java app servers) spawning suspicious children; applying the working directory constraint to the parent is typically more accurate and avoids flagging ordinary Java processes as the child.

Exception Recommendations

Add exception: process.parent.executable is "/usr/lib/ocf/resource.d/heartbeat/apache" (Confidence: HIGH)

Events 3 and 4 show the parent process identified as apache with process.parent.executable exactly /usr/lib/ocf/resource.d/heartbeat/apache (Pacemaker/Heartbeat OCF resource). This parent repeatedly spawns curl/wget probes to localhost, which is expected HA monitoring behavior and a high-probability dominant FP driver.

Modify →

and process.parent.executable is "/usr/lib/ocf/resource.d/heartbeat/apache"

Add exception: process.parent.command_line wildcard "*/usr/lib/ocf/resource.d/heartbeat/apache*monitor*" (Confidence: MEDIUM)

Events 3 and 4 include process.parent.command_line = /bin/sh /usr/lib/ocf/resource.d/heartbeat/apache monitor. Some telemetry sources may miss process.parent.executable but retain process.parent.command_line; this alternative exception helps suppress the same benign OCF monitor pattern without broadly excluding Apache activity.

Modify →

and process.parent.command_line wildcard "*/usr/lib/ocf/resource.d/heartbeat/apache*monitor*"

Add exception: process.parent.command_line wildcard "*curl --fail -k https://127.0.0.1:${INTERFACE_HTTPS_PORT*" (Confidence: HIGH)

Events 1 and 2 repeatedly show process.parent.command_line as /bin/sh -c curl --fail -k https://127.0.0.1:${INTERFACE_HTTPS_PORT:-443} || exit 1 executed as www-data (container context). This is a clear health-check loop and is responsible for high-frequency alerting when included.

Modify →

and process.parent.command_line wildcard "*curl --fail -k https://127.0.0.1:${INTERFACE_HTTPS_PORT*"

Add exception: process.parent.command_line wildcard "*INTERFACE_HTTPS_PORT*127.0.0.1*|| exit 1*" (Confidence: MEDIUM)

A slightly more flexible variant of the Event 1–2 health-check exception to tolerate minor formatting/port-default differences (still anchored on the uncommon ${INTERFACE_HTTPS_PORT...} token plus localhost and exit 1). Use if the exact-string variant misses near-identical container health checks.

Modify →

and process.parent.command_line wildcard "*INTERFACE_HTTPS_PORT*127.0.0.1*|| exit 1*"

Field-Level Recommendations

Field Value Alert % Cluster % Confidence Type
process.parent.executable /usr/lib/ocf/resource.d/heartb... 0.0% 15.0% HIGH EXCEPTION
process.parent.command_line */usr/lib/ocf/resource.d/heart... 0.0% 15.0% MEDIUM EXCEPTION
process.parent.command_line *curl --fail -k https://127.0.... 0.0% 20.0% HIGH EXCEPTION
process.parent.command_line *INTERFACE_HTTPS_PORT*127.0.0.... 0.0% 20.0% MEDIUM EXCEPTION

This issue was generated by the GenAI Tradecraft Rule Tuning Advisor.
Analysis timestamp: 2026-03-09T06:25:34.637610

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions