Curl or Wget Execution from Container Context


Description

Detects execution of curl or wget from processes whose title aligns with runc init, a common fingerprint for workloads running inside OCI/runc-backed containers on Linux hosts instrumented with Auditd Manager. After breaking out of an application container or abusing a privileged workload, attackers often pull ingress tooling (stagers, scripts, implants) or stage exfiltration with minimal HTTP clients. Those utilities are also used benignly in images, so context matters; the runc init anchor narrows the signal to the container runtime boundary where unexpected download clients are more worthy of review than the same binaries on a bare-metal admin shell.

Query · kuery

host.os.type:linux and 
data_stream.dataset:"auditd_manager.auditd" and
event.action:("executed" or "exec") and
process.title:"runc init" and
(
  process.name:(curl or wget) or
  process.args:(* curl* or */bin/curl* or *wget*)
) and 
not process.args :(*127.0.0.1* or *localhost* or "wget --no-verbose --tries=1 --spider --no-check-certificate http://${WEB_HOST}:${WEB_PORT}/api/ping || exit 1")

Implementation guide

This rule requires data from Auditd Manager (or legacy Auditbeat shipping comparable ECS fields).

Auditd Manager Integration Setup

The Auditd Manager integration receives audit events from the Linux Audit Framework. With auditd_manager, administrators can define audit rules, track system events, and generate reports.

Steps to deploy Auditd Manager

  • In Kibana, open Add integrations, search for Auditd Manager, and add it to an agent policy deployed on Linux hosts that should emit syscall audit data.
  • For integration details, see the Auditd Manager documentation.

Rule-specific notes

  • Ensure syscall coverage includes execve (or equivalent) for processes inside containers so curl, wget, and argument lists are captured on the host.
  • Confirm that process.title (or the mapped proctitle field) reflects runc init for your runtime; other runtimes may use different titles—tune the predicate if you standardize on crun, containerd-shim, etc.

Known false positives

  • Base images, entrypoints, or init wrappers may legitimately invoke curl or wget during container startup (package installs, health checks); baseline trusted images and exclude stable image digests or namespaces when noisy.
  • Developer-oriented containers and CI build pods can run curl/wget from PID 1 descendants under runc; correlate with build pipelines and approved registries.

Analyst notes

Investigating Curl or Wget Execution from Container Context

The rule matches Auditd-backed process events where process.title is runc init and the executed program is curl/wget (by process.name) or the argument vector suggests curl or wget paths. Use it to spot ingress tool transfer or scripted downloads from inside a container as seen at the host audit layer.

Possible investigation steps

  • Reconstruct the full command line from process.args / process.command_line and identify URLs, output paths, and flags such as -O, --post-file, or TLS bypass (-k).
  • Map the event to the container: cgroup, container.id, kubernetes.pod.*, or runtime metadata if present on the document; identify the image, namespace, and workload owner.
  • Review egress from the host or pod network policy logs for destinations contacted shortly after the execution.
  • Compare against recent image or manifest changes for the workload to rule out intentional startup scripts.

False positive analysis

  • Package managers and bootstrap scripts in official images may run curl/wget once at start; document and exclude when verified.
  • Security scanners or health checks running in sidecars could match; validate agent type and schedule.

Response and remediation

  • If unauthorized, isolate the node or workload, revoke credentials available to the container, inspect for dropped binaries or cron/systemd additions, and rotate any secrets the container could reach.
Raw source Curl or Wget Execution from Container Context · Elastic TOML
Esc
Published by elastic/detection-rules ↗, licensed under Elastic License 2.0 ↗. Reproduced here unmodified.
[metadata]
creation_date = "2026/04/22"
integration = ["auditd_manager"]
maturity = "production"
updated_date = "2026/05/11"

[rule]
author = ["Elastic"]
description = """
Detects execution of curl or wget from processes whose title aligns with **`runc init`**, a common fingerprint 
for workloads running inside **OCI/runc-backed containers** on Linux hosts instrumented with Auditd Manager. 
After breaking out of an application container or abusing a privileged workload, attackers often pull ingress tooling
(stagers, scripts, implants) or stage exfiltration with minimal HTTP clients. Those utilities are also used
benignly in images, so context matters; the `runc init` anchor narrows the signal to the container runtime boundary
where unexpected download clients are more worthy of review than the same binaries on a bare-metal admin shell.
"""
false_positives = [
    """
    Base images, entrypoints, or init wrappers may legitimately invoke curl or wget during container startup (package
    installs, health checks); baseline trusted images and exclude stable image digests or namespaces when noisy.
    """,
    """
    Developer-oriented containers and CI build pods can run curl/wget from PID 1 descendants under runc; correlate with
    build pipelines and approved registries.
    """,
]
from = "now-9m"
index = ["auditbeat-*", "logs-auditd_manager.auditd-*"]
language = "kuery"
license = "Elastic License v2"
name = "Curl or Wget Execution from Container Context"
note = """## Triage and analysis

### Investigating Curl or Wget Execution from Container Context

The rule matches Auditd-backed process events where `process.title` is `runc init` and the executed program is
curl/wget (by `process.name`) or the argument vector suggests curl or wget paths. Use it to spot ingress tool 
transfer or scripted downloads from inside a container as seen at the host audit layer.

### Possible investigation steps

- Reconstruct the full command line from `process.args` / `process.command_line` and identify URLs, output paths, and
  flags such as `-O`, `--post-file`, or TLS bypass (`-k`).
- Map the event to the container: cgroup, `container.id`, `kubernetes.pod.*`, or runtime metadata if present on the
  document; identify the image, namespace, and workload owner.
- Review egress from the host or pod network policy logs for destinations contacted shortly after the execution.
- Compare against recent image or manifest changes for the workload to rule out intentional startup scripts.

### False positive analysis

- Package managers and bootstrap scripts in official images may run curl/wget once at start; document and exclude when
  verified.
- Security scanners or health checks running in sidecars could match; validate agent type and schedule.

### Response and remediation

- If unauthorized, isolate the node or workload, revoke credentials available to the container, inspect for dropped
  binaries or cron/systemd additions, and rotate any secrets the container could reach.
"""
references = [
    "https://attack.mitre.org/techniques/T1105/",
    "https://gtfobins.github.io/gtfobins/curl/",
    "https://gtfobins.github.io/gtfobins/wget/",
]
risk_score = 47
rule_id = "e7b2c3d4-5a6b-4e8f-9c0d-1a2b3e4f5a6b"
setup = """## Setup

This rule requires data from **Auditd Manager** (or legacy Auditbeat shipping comparable ECS fields).

### Auditd Manager Integration Setup
The Auditd Manager integration receives audit events from the Linux Audit Framework. With `auditd_manager`,
administrators can define audit rules, track system events, and generate reports.

#### Steps to deploy Auditd Manager
- In Kibana, open **Add integrations**, search for **Auditd Manager**, and add it to an agent policy deployed on Linux
  hosts that should emit syscall audit data.
- For integration details, see the [Auditd Manager documentation](https://docs.elastic.co/integrations/auditd_manager).

#### Rule-specific notes
- Ensure syscall coverage includes **execve** (or equivalent) for processes inside containers so `curl`, `wget`, and
  argument lists are captured on the host.
- Confirm that **`process.title`** (or the mapped proctitle field) reflects **`runc init`** for your runtime; other
  runtimes may use different titles—tune the predicate if you standardize on `crun`, `containerd-shim`, etc.
"""
severity = "medium"
tags = [
    "Domain: Endpoint",
    "OS: Linux",
    "Use Case: Threat Detection",
    "Tactic: Command and Control",
    "Tactic: Execution",
    "Domain: Containers",
    "Data Source: Auditd Manager",
    "Resources: Investigation Guide",
]
timestamp_override = "event.ingested"
type = "query"
query = '''
host.os.type:linux and 
data_stream.dataset:"auditd_manager.auditd" and
event.action:("executed" or "exec") and
process.title:"runc init" and
(
  process.name:(curl or wget) or
  process.args:(* curl* or */bin/curl* or *wget*)
) and 
not process.args :(*127.0.0.1* or *localhost* or "wget --no-verbose --tries=1 --spider --no-check-certificate http://${WEB_HOST}:${WEB_PORT}/api/ping || exit 1")
'''

[[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/"

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.