शेलशॉक की जाँच करने के लिए कमांड का स्पष्टीकरण


32

यहाँ वह कमांड है जिसका उपयोग मैंने शेलशॉक बग के लिए अपने बैश शेल की जाँच के लिए किया है:

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

किसी को भी कृपया विवरण में आदेश की व्याख्या कर सकते हैं?


4
इसे भी देखें: unix.stackexchange.com/q/157329/70524 - फिक्सि का जवाब मदद का हो सकता है।
मुरु

जवाबों:


45

यह उत्तर मैथ्यू मिलर द्वारा फेडोरा मैगज़ीन के एक मूल लेख का व्युत्पन्न है , जो क्रिएटिव कॉमन्स एट्रिब्यूशन-शेयर अलाइक 4.0 लाइसेंस के तहत लाइसेंस प्राप्त है ।

मुझे समझाने दो:

env x='() { :;}; echo OOPS' bash -c :

यह एक कमजोर सिस्टम पर "OOPS" प्रिंट करेगा, लेकिन अगर बैश पैच किया गया है तो चुपचाप बाहर निकलें।

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

यह एक कमजोर प्रणाली पर "OOPS" प्रिंट करेगा, लेकिन प्रिंट “this is a test”अगर बैश पैच किया गया है।

और आपने शायद सुना है कि इसका पर्यावरण चर के साथ कुछ करना है। लेकिन, पर्यावरण चर में कोड क्यों निष्पादित हो रहा है? ठीक है, यह माना नहीं जाता है - लेकिन, एक विशेषता के कारण जो मुझे अपने स्वयं के अच्छे के लिए थोड़ा बहुत चालाक कहने के लिए लुभाता है, एक दोष के लिए कुछ जगह है। बैश जिसे आप एक टर्मिनल प्रॉम्प्ट के रूप में देखते हैं, लेकिन यह एक स्क्रिप्टिंग भाषा है, और इसमें फ़ंक्शन को परिभाषित करने की क्षमता है। आप ऐसा करते हैं:

$ Ubuntu()  { echo "Ubuntu is awesome."; }

और फिर आपके पास एक नई कमांड है। ध्यान रखें कि echoयहाँ वास्तव में अभी तक नहीं चलाया गया है; जब हम अपना नया कमांड चलाते हैं, तो यह केवल सहेजा जाता है। यह एक मिनट में महत्वपूर्ण होगा!

$ Ubuntu
 Ubuntu is awesome.

उपयोगी! लेकिन, मान लीजिए, किसी कारण के लिए, हमें एक नए उदाहरण को मारना चाहिए, एक उपप्रकार के रूप में, और उसी के तहत अपनी भयानक नई कमांड चलाना चाहते हैं। कथन bash -c somecommandठीक यही करता है: दिए गए कमांड को एक नए शेल में चलाता है:

$ bash -c Ubuntu
  bash: Ubuntu: command not found

ऊह। उदास। बच्चे को कार्य की परिभाषा विरासत में नहीं मिली। लेकिन, यह पर्यावरण को निहित करता है - कुंजी-मूल्य जोड़े का एक संग्रह जो शेल से निर्यात किया गया है। (यह पूरी तरह से 'न्यूट्रर कॉन्सेप्ट है; अगर आप इससे परिचित नहीं हैं, तो अब मुझ पर भरोसा करें।) और, यह पता चला है, बैश फंक्शन भी एक्सपोर्ट कर सकते हैं। इसलिए:

$ export -f Ubuntu
$ bash -c Ubuntu
  Ubuntu is awesome.

जो सभी अच्छी तरह से और अच्छा है - सिवाय इसके कि जिस तंत्र द्वारा यह पूरा किया जाता है वह सॉर्ट डॉगी है । असल में, चूंकि पर्यावरण चर में कार्य करने के लिए कोई लिनक्स / यूनिक्स जादू नहीं है, इसलिए निर्यात फ़ंक्शन वास्तव में फ़ंक्शन परिभाषा युक्त एक नियमित वातावरण चर बनाता है। फिर, जब दूसरा शेल "इनकमिंग" वातावरण को पढ़ता है और एक फ़ंक्शन की तरह दिखने वाली सामग्री के साथ एक चर का सामना करता है, तो यह इसका मूल्यांकन करता है।

सिद्धांत रूप में, यह पूरी तरह से सुरक्षित है , क्योंकि, याद रखें, एक फ़ंक्शन को परिभाषित करना वास्तव में इसे निष्पादित नहीं करता है । सिवाय इसके - और यही कारण है कि हम यहां हैं - कोड में एक बग था जहां फ़ंक्शन परिभाषा के अंत तक मूल्यांकन बंद नहीं हुआ था। यह सिर्फ जा रहा kepts।

ऐसा कभी नहीं होगा जब पर्यावरण चर में संग्रहित फ़ंक्शन को वैध रूप से, के साथ बनाया गया हो export -f। लेकिन, कानूनी क्यों? एक हमलावर किसी भी पुराने पर्यावरण चर को बना सकता है, और यदि यह एक फ़ंक्शन की तरह दिखता है, तो नए बैश गोले सोचेंगे कि यह है!

तो, हमारे पहले उदाहरण में:

env x='() { :;}; echo OOPS' bash -c "echo this is a test"

envआदेश दिए गए चर सेट के साथ एक कमांड चलाता है। इस मामले में, हम xएक फ़ंक्शन की तरह दिखने वाली चीज़ पर सेट कर रहे हैं । फ़ंक्शन केवल एक है :, जो वास्तव में एक साधारण कमांड है जिसे कुछ भी नहीं करने के रूप में परिभाषित किया गया है। लेकिन फिर, जिसके बाद semi-colonफ़ंक्शन परिभाषा के अंत का संकेत मिलता है, एक echoकमांड है। यह वहाँ नहीं माना जाता है, लेकिन हमें ऐसा करने से कुछ भी नहीं रोक रहा है।

फिर, इस नए वातावरण के साथ चलने के लिए दिया गया कमांड एक नया बैश शेल है, फिर से एक " echo this is a test" या "कुछ भी नहीं :" कमांड के साथ, जिसके बाद यह बाहर निकलेगा, पूरी तरह से हानिरहित।

लेकिन - उफ़! जब वह नया शेल शुरू होता है और पर्यावरण को पढ़ता है, तो वह xपरिवर्तनशील हो जाता है , और चूंकि यह एक फ़ंक्शन की तरह दिखता है, इसलिए यह इसका मूल्यांकन करता है। फ़ंक्शन की परिभाषा हानिरहित रूप से भरी हुई है - और फिर हमारे दुर्भावनापूर्ण पेलोड को भी ट्रिगर किया गया है। इसलिए, यदि आप एक कमजोर प्रणाली पर ऊपर चला रहे हैं, तो आप पर “OOPS”वापस मुद्रित किया जाएगा। या, एक हमलावर सिर्फ चीजों को प्रिंट करने की तुलना में बहुत खराब कर सकता है।


1
यह क्यों काम करता है की एक उत्कृष्ट व्याख्या के लिए Muchas gracias।
डग आर।

2
ध्यान दें कि envआवश्यक नहीं है। इसके बिना कमांड का उपयोग करके आप एक ही परिणाम प्राप्त कर सकते हैं (बैश अपडेट किया गया है) के आधार पर (पास / असफल) x='() { :;}; echo OOPS' bash -c "echo this is a test"। ऐसा इसलिए है क्योंकि एक चर असाइनमेंट के साथ एक कमांड से पहले उस वेरिएबल और उसके मान को कमांड में ( bash -c "..."इस मामले में) वातावरण में पास किया जाता है।
अगली सूचना तक रोक दिया गया।

1
... लेकिन यह हाल के कुछ पैच में आवश्यक हो सकता है। चीजें प्रवाह में हैं।
अगली सूचना तक रोक दिया गया।

4
@DennisWilliamson envआवश्यक है या नहीं यह उस शेल द्वारा निर्धारित किया जाता है जिसमें से कोई परीक्षण चलाता है, न कि शेल का परीक्षण किया जा रहा है। (ये समान हो सकते हैं। फिर भी, हम परीक्षण कर रहे हैं कि कैसे bash अपने पर्यावरण को संसाधित करता है।) बॉर्न-शैली के गोले NAME=value commandवाक्यविन्यास स्वीकार करते हैं; सी-शैली के गोले (जैसे csh, tcsh) नहीं। इसलिए परीक्षण थोड़ा अधिक पोर्टेबल है env(कभी-कभी यह कैसे काम करता है इसके बारे में भ्रम पैदा करने की कीमत पर)।
एलिया कगन

2

इसके अप्रकाशित संस्करणbash में पर्यावरण चर के रूप में फ़ंक्शन परिभाषाओं का निर्यात किया जाता है।

एक समारोह के xरूप में स्टोर ,

$ x() { bar; }
$ export -f x

और इसकी परिभाषा की जाँच करें,

$ env | grep -A1 x
x=() {  bar
}

तो कोई अपने स्वयं के पर्यावरण चर को परिभाषित करके इसका फायदा उठा सकता है, और उन्हें फ़ंक्शन परिभाषाओं के रूप में व्याख्या करता है। उदाहरण के लिए के env x='() { :;}'रूप में इलाज किया जाएगा

x() { :;
}

शेलशॉक की जाँच करने के लिए कमांड क्या करती है,

env x='() { :;}; echo vulnerable' bash -c "echo this is a test"

से man env,

  1. env - एक संशोधित वातावरण में एक कार्यक्रम चलाएं।

  2. :बाहर निकलने की स्थिति से बाहर निकलने के अलावा कुछ नहीं करते 0। देखना अधिक

  3. जब अप्रकाशित बैश का एक नया उदाहरण के रूप में लॉन्च किया गया bash -c "echo this is a test", तो तैयार किए गए पर्यावरण चर को एक फ़ंक्शन के रूप में माना जाता है और लोड किया जाता है। उसी हिसाब से आउटपुट मिलता है

    चपेट में
    यह एक परीक्षण है

नोट: फ़ंक्शन परिभाषा के बाहर की गूंज को बैश स्टार्टअप के दौरान अप्रत्याशित रूप से निष्पादित किया गया है। फंक्शन डेफिनिशन मूल्यांकन और शोषण होने के लिए केवल एक कदम है, फंक्शन डेफिनिशन और उपयोग किया गया पर्यावरण चर मनमाना है। शेल पर्यावरण चर को देखता है, एक्स को देखता है, जो ऐसा दिखता है कि यह उन बाधाओं से मिलता है जिनके बारे में यह जानता है कि फ़ंक्शन परिभाषा क्या दिखती है, और यह रेखा का मूल्यांकन करता है, अनजाने में भी गूंज को निष्पादित करता है (जो किसी भी आदेश, दुर्भावनापूर्ण या नहीं हो सकता है) । इन्हें भी देखें इस


मैंने अभी भी पाया है कि किसी भी परिभाषित बैश फ़ंक्शन को, यदि बाल के खोल में पैच के संस्करण में मूल्यांकन किया जा रहा है। इसे देखें: chayan @ chayan: ~ / testr $ test () {गूंज "कुछ भी"; }; निर्यात -f परीक्षण; bash -c test Ouput: कुछ भी तो आपका उत्तर कुछ हद तक ठीक से निर्देशित नहीं है। बग की कसिया की व्याख्या इसकी परिभाषा से परे चर का विस्तार करने के रूप में सही है, मुझे लगता है।
हेमायल सेप

@ हेमायल यह व्यवहार स्वाभाविक है। लेकिन अगर आप कोशिश env test='() { echo "anything"; }' bash -c "echo otherthing"करेंगे तो आप आउटपुट पर देखेंगे otherthing। जिसे पैच में सही किया गया है। यदि मैं अभी भी स्पष्ट नहीं हूं तो स्वतंत्र महसूस करें।
सौरव

कृपया मुझे एक बार फिर से स्पष्ट करें। आपकी अंतिम टिप्पणी में हम मूल रूप से फ़ंक्शन को परिभाषित कर रहे हैं और फिर बैश को इको निष्पादित करने के लिए कह रहे हैं। इस उदाहरण में हमने फ़ंक्शन को बैश में नहीं कहा है। क्या यह पैक्ड और नॉन-पैचेड बैश दोनों में समान आउटपुट नहीं होगा? मुझे यह धारणा है कि बग मूल रूप से बैश था क्योंकि फ़ंक्शन परिभाषा के बाद रखा गया कमांड निष्पादित कर रहा था, जबकि फ़ंक्शन को कभी भी उदाहरण के लिए बाद में नहीं बुलाया गया था यदि हम यह एनवी टेस्ट करते हैं = '() {इको "कुछ भी"; }; इको "फू" 'बैश-सी "इको अन्यिंग"। कृपया मुझे इस संदर्भ में स्पष्ट करें।
heemayl

@heemayl मैंने अपना उत्तर संपादित किया है, आशा है कि अब यह स्पष्ट है। आप मेरी पिछली टिप्पणी में उदाहरण में सही हैं जिसे हमने फ़ंक्शन नहीं कहा है। लेकिन अंतर यह है कि unpatched bashआप फ़ंक्शन को कॉल कर सकते हैं क्योंकि यह परिभाषित है, लेकिन एक पैच bashमें परिभाषा स्वयं नहीं है।
12

@ हेमायल: नहीं, यह गलत है। एक पैच बैश अभी भी बच्चे के वातावरण में फ़ंक्शन परिभाषा को पारित करेगा। वह अंतर जो पैच बनाता है, वह कोड है जो फंक्शन डेफिनेशन ( echo vulnerable) का अनुसरण नहीं करता है। ध्यान दें कि नवीनतम पैच में, पारित फ़ंक्शन में एक विशिष्ट उपसर्ग ( env 'BASH_FUNC_x()'='() { :;}; echo vulnerable' bash -c "echo this is a test") होना चाहिए । कुछ और हालिया पैच %%पहले के बजाय उपयोग कर सकते हैं ()
अगली सूचना तक रोक दिया गया।
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.