Env x = '() {:;}; कमांड 'बैश करते हैं और यह असुरक्षित क्यों है?


237

जाहिरा तौर पर एक भेद्यता है (CVE-2014-6271) बैश में: बैश विशेष रूप से तैयार किए गए पर्यावरण चर कोड इंजेक्शन हमले

मैं यह पता लगाने की कोशिश कर रहा हूं कि क्या हो रहा है, लेकिन मुझे पूरी तरह से यकीन नहीं है कि मैं इसे समझ पा रहा हूं। echoएकल उद्धरणों में इसे कैसे निष्पादित किया जा सकता है?

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

संपादित 1 : एक पैच सिस्टम इस तरह दिखता है:

$ env x='() { :;}; echo vulnerable' bash -c "echo this is a test"
bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
this is a test

EDIT 2 : एक संबंधित भेद्यता / पैच है: CVE-2014-7169 जो थोड़ा अलग परीक्षण का उपयोग करता है:

$ env 'x=() { :;}; echo vulnerable' 'BASH_FUNC_x()=() { :;}; echo vulnerable' bash -c "echo test"

अप्रकाशित आउटपुट :

vulnerable
bash: BASH_FUNC_x(): line 0: syntax error near unexpected token `)'
bash: BASH_FUNC_x(): line 0: `BASH_FUNC_x() () { :;}; echo vulnerable'
bash: error importing function definition for `BASH_FUNC_x'
test

आंशिक रूप से (प्रारंभिक संस्करण) पैक्ड आउटपुट :

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `x'
bash: error importing function definition for `BASH_FUNC_x()'
test

समझौता उत्पादन करने के लिए और CVE-2014-7169 सहित:

bash: warning: x: ignoring function definition attempt
bash: error importing function definition for `BASH_FUNC_x'
test

संपादित 3 : कहानी के साथ जारी है:


यह इको नहीं है जो निष्पादित हो जाता है। इसकी x की परिभाषा परिभाषा। यदि x में परिभाषित फ़ंक्शन कुछ डरपोक काम करता है, तो कोई तरीका नहीं है यदि फ़ंक्शन x वास्तविक थे, तो वापसी मूल्य की जांच कर सकते हैं। ध्यान दें कि फ़ंक्शन परीक्षण कोड में खाली है। एक अनियंत्रित वापसी मूल्य स्क्रिप्ट इंजेक्शन को जन्म दे सकता है। स्क्रिप्ट इंजेक्शन विशेषाधिकार वृद्धि की ओर जाता है और विशेषाधिकार वृद्धि रूट एक्सेस की ओर जाता है। पैच एक समारोह के रूप में x के निर्माण को अक्षम करता है
eyoung100

26
eyoung100, कोई गूंज रहा है निष्पादित हो रही। आप देख सकते हैं कि यह निष्पादित हो रहा है क्योंकि शब्द vulnerableआउटपुट में दिखाई देता है। मुख्य समस्या यह है कि bash पार्स कर रहा है और फ़ंक्शन परिभाषा के बाद कोड को निष्पादित भी कर रहा है। दूसरे उदाहरण के लिए seclists.org/oss-sec/2014/q3/650 का /bin/idहिस्सा देखें ।
मिकेल

4
बस एक त्वरित पक्ष की टिप्पणी। रेड हैट ने सलाह दी है कि जो पैच जारी किया गया है वह केवल आंशिक पैच है और अभी भी सिस्टम खतरे में है।
पीटर

2
@ eyoung100 अंतर यह है कि फ़ंक्शन के अंदर कोड केवल तभी निष्पादित होता है जब पर्यावरण चर स्पष्ट रूप से कहा जाता है। फ़ंक्शन परिभाषा के बाद कोड हर बार एक नई बैश प्रक्रिया शुरू होता है।
डेविड फैरेल

1
अतिरिक्त विवरण के लिए stackoverflow.com/questions/26022248/… देखें
बरमार

जवाबों:


204

बैश स्टोर पर्यावरण चर के रूप में फ़ंक्शन परिभाषाओं का निर्यात करते हैं। निर्यातित कार्य इस तरह दिखते हैं:

$ foo() { bar; }
$ export -f foo
$ env | grep -A1 foo
foo=() {  bar
}

यही है, पर्यावरण चर fooमें शाब्दिक सामग्री है:

() {  bar
}

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

$ export foo='() { echo "Inside function"; }'
$ bash -c 'foo'
Inside function

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

$ export foo='() { echo "Inside function" ; }; echo "Executed echo"'
$ bash -c 'foo'
Executed echo
Inside function

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

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

यहाँ एक व्यवहार्य हमले का एक उदाहरण है। आप एक वेब सर्वर चलाते हैं, जो अपने जीवनकाल के भाग के रूप में एक असुरक्षित शेल चलाता है। यह वेब सर्वर पर्यावरण चर को बैश स्क्रिप्ट में भेजता है, उदाहरण के लिए, यदि आप CGI का उपयोग कर रहे हैं, तो HTTP अनुरोध के बारे में जानकारी अक्सर वेब सर्वर से पर्यावरण चर के रूप में शामिल की जाती है। उदाहरण के लिए, HTTP_USER_AGENTआपके उपयोगकर्ता एजेंट की सामग्री पर सेट किया जा सकता है। इसका मतलब है कि यदि आप अपने उपयोगकर्ता एजेंट को कुछ '() {:; }; इको फू ’, जब वह शेल स्क्रिप्ट चलती है, echo fooतो निष्पादित की जाएगी। फिर, echo fooकुछ भी हो सकता है, दुर्भावनापूर्ण या नहीं।


3
क्या यह बाश की तरह किसी भी अन्य बैश-शेल को प्रभावित कर सकता है?
एमिलियो वाज़केज़-रीना

3
@ user815423426 नहीं, zsh में यह सुविधा नहीं है। Ksh के पास है, लेकिन अलग तरह से लागू किया गया है, मुझे लगता है कि फ़ंक्शन केवल बहुत ही संकीर्ण परिस्थितियों में प्रसारित किए जा सकते हैं, केवल अगर शेल कांटे, पर्यावरण के माध्यम से नहीं।
गाइल्स

20
@ user815423426 आरसी अन्य शेल है जो पर्यावरण में कार्यों को पारित करता है, लेकिन इसके नाम "fn_" के साथ उपसर्ग वाले चर के साथ हैं और उन्हें केवल तब ही व्याख्या किया जाता है जब आह्वान किया जाता है।
स्टीफन चेज़लस

18
@ स्टीफनचेज़लस - बग की रिपोर्ट करने के लिए धन्यवाद।
हिरण

13
@gnclmorais आपका मतलब है कि आप दौड़ते हैं export bar='() { echo "bar" ; }'; zsh -c barऔर यह barबजाय प्रदर्शित करता है zsh:1: command not found: bar? क्या आप सुनिश्चित हैं कि आप उस शेल को भ्रमित नहीं कर रहे हैं जिसे आप उस शेल से जोड़ रहे हैं जिसे आप परीक्षण सेट करने के लिए उपयोग कर रहे हैं?
गाइल्स

85

यह आगे क्या हो रहा है यह प्रदर्शित करने में मदद कर सकता है:

$ export dummy='() { echo "hi"; }; echo "pwned"'
$ bash
pwned
$

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

दुर्भाग्य से, यह केवल फ़ंक्शन परिभाषा का मूल्यांकन नहीं करता है, यह पर्यावरण चर के पूरे पाठ का मूल्यांकन करता है, जिसमें संभवतः दुर्भावनापूर्ण कथन (एस) भी शामिल हैं जो फ़ंक्शन परिभाषा का पालन करते हैं। ध्यान दें कि प्रारंभिक फ़ंक्शन परिभाषा के बिना, पर्यावरण चर का मूल्यांकन नहीं किया जाएगा, यह केवल पाठ स्ट्रिंग के रूप में पर्यावरण में जोड़ा जाएगा। जैसा कि क्रिस डाउन ने बताया, यह निर्यात शेल कार्यों के आयात को लागू करने के लिए एक विशिष्ट तंत्र है।

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

$ declare -f
dummy ()
{
    echo "hi"
}
declare -fx dummy
$ dummy
hi
$echo $dummy
$

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


17
जबकि स्वीकृत उत्तर वास्तव में यह कहता है यदि आप इसे ध्यान से पढ़ते हैं, तो मुझे यह उत्तर और भी स्पष्ट और समझने में अधिक सहायक लगा कि यह परिभाषा का मूल्यांकन है (बजाय कार्य को निष्पादित करने के) यही समस्या है।
natevw

1
इस उदाहरण की exportआज्ञा क्यों है जबकि दूसरों के पास थी env? मैं सोच envरहा था कि पर्यावरणीय चर को परिभाषित करने के लिए उपयोग किया जा रहा है जिसे एक और बैश शेल लॉन्च होने पर कहा जाएगा। फिर यह कैसे काम कर रहा हैexport
हरीस

इस क्षण तक कोई स्वीकृत उत्तर नहीं मिला है। मैं शायद एक को स्वीकार करने से पहले कुछ और दिनों का इंतजार करूंगा। इस उत्तर का नकारात्मक पक्ष यह है कि यह मूल कमांड को नहीं तोड़ता है, और न ही चर्चा करता है कि मूल उत्तर से इस उत्तर में कमांड को कैसे प्राप्त किया जाए, यह दर्शाता है कि वे समान हैं। इसके अलावा यह एक अच्छी व्याख्या है।
जिप्पी

@ralph - पर्यावरण परिभाषाएँ envऔर exportनिर्यात दोनों ताकि वे एक उपधारा में उपलब्ध हों। समस्या वास्तव में यह है कि इन निर्यात परिभाषाओं को एक उपधारा के वातावरण में आयात किया जाता है, और विशेष रूप से तंत्र में जो फ़ंक्शन परिभाषाओं को आयात करता है।
sdenham

1
@ralph - envकुछ विकल्पों और पर्यावरण चर के साथ एक कमांड चलाता है। ध्यान दें कि मूल प्रश्न उदाहरण में, एक स्ट्रिंग पर envसेट xहोता है, और bash -cचलाने के लिए एक कमांड के साथ कॉल करता है। यदि आप करते हैं env x='foo' vim, तो विम लॉन्च होगा, और वहां आप इसके शेल / पर्यावरण युक्त कॉल आउट कर सकते हैं !echo $x, और यह प्रिंट करेगा foo, लेकिन अगर आप तब बाहर निकलते हैं और echo $xइसे परिभाषित नहीं किया जाएगा, क्योंकि यह केवल मौजूद था जबकि विम चल रहा था के माध्यम से envआदेश। इसके exportबजाय आदेश वर्तमान परिवेश में लगातार मान सेट करता है ताकि बाद में चलने वाला सब- वे उनका उपयोग करेगा।
गैरी फिक्सर

72

मैंने इसे क्रिस-डाउन के उत्कृष्ट उत्तर के ट्यूटोरियल-स्टाइल के रूप में लिखा है।


बैश में आप इस तरह से शेल वैरिएबल रख सकते हैं

$ t="hi there"
$ echo $t
hi there
$

डिफ़ॉल्ट रूप से, ये चर बच्चे प्रक्रियाओं द्वारा विरासत में नहीं मिले हैं।

$ bash
$ echo $t

$ exit

लेकिन अगर आप उन्हें निर्यात के लिए चिह्नित करते हैं, तो बैश एक ध्वज सेट करेगा जिसका अर्थ है कि वे उपप्रकारों के वातावरण में जाएंगे (हालांकि envpपैरामीटर बहुत अधिक नहीं देखा गया है, mainआपके सी प्रोग्राम में तीन पैरामीटर हैं: main(int argc, char *argv[], char *envp[])जहां अंतिम व्यूअर बिंदु एक सरणी है उनकी परिभाषाओं के साथ शैल चर)।

तो चलो निर्यात tइस प्रकार है:

$ echo $t
hi there
$ export t
$ bash
$ echo $t
hi there
$ exit

जबकि उपर्युक्त tउपधारा में अपरिभाषित था, अब यह हमारे द्वारा निर्यात किए जाने के बाद प्रकट होता है ( export -n tयदि आप इसका निर्यात रोकना चाहते हैं तो इसका उपयोग करें )।

लेकिन बाश में कार्य एक अलग जानवर हैं। आप उन्हें इस तरह घोषित करते हैं:

$ fn() { echo "test"; }

और अब आप इसे कॉल करके फ़ंक्शन को आमंत्रित कर सकते हैं जैसे कि यह एक और शेल कमांड था:

$ fn
test
$

एक बार फिर, यदि आप एक सब-टाइम स्पॉन करते हैं, तो हमारा फ़ंक्शन निर्यात नहीं किया जाता है:

$ bash
$ fn
fn: command not found
$ exit

हम एक समारोह के साथ निर्यात कर सकते हैं export -f:

$ export -f fn
$ bash
$ fn
test
$ exit

यहाँ मुश्किल हिस्सा है: एक निर्यात समारोह की तरह fnएक पर्यावरण चर में बदल जाता है, जैसे कि शेल चर tका हमारा निर्यात ऊपर था। fnस्थानीय चर होने पर ऐसा नहीं होता है , लेकिन निर्यात के बाद हम इसे शेल चर के रूप में देख सकते हैं। हालाँकि, आप एक ही नाम के साथ एक नियमित (यानी, गैर फ़ंक्शन) शेल चर भी कर सकते हैं । बैश चर की सामग्री के आधार पर अलग होता है:

$ echo $fn

$ # See, nothing was there
$ export fn=regular
$ echo $fn
regular
$ 

अब हम envनिर्यात के लिए चिन्हित सभी शेल चरों को दिखाने के लिए उपयोग कर सकते हैं और नियमित fnऔर फंक्शन दोनों fnदिखा सकते हैं:

$ env
.
.
.
fn=regular
fn=() {  echo "test"
}
$

एक उप-शेल दोनों परिभाषाओं को निगलेगा: एक नियमित चर के रूप में और एक फ़ंक्शन के रूप में:

$ bash
$ echo $fn
regular
$ fn
test
$ exit

fnजैसा कि हमने ऊपर या सीधे एक नियमित चर असाइनमेंट के रूप में किया था, आप इसे परिभाषित कर सकते हैं :

$ fn='() { echo "direct" ; }'

ध्यान दें कि यह एक उच्च असामान्य बात है! आम तौर पर हम फ़ंक्शन fnको परिभाषित करेंगे जैसा कि हमने fn() {...}सिंटैक्स के साथ किया था । लेकिन चूंकि बैश इसे पर्यावरण के माध्यम से निर्यात करता है, इसलिए हम उपरोक्त नियमित परिभाषा के लिए सीधे "शॉर्ट कट" कर सकते हैं। ध्यान दें कि (अपने अंतर्ज्ञान के लिए काउंटर, शायद) यह वर्तमान शेल में उपलब्ध एक नए फ़ंक्शन के परिणामस्वरूप नहीं हैfn । लेकिन अगर आप एक ** उप ** शेल को स्पॉन करते हैं, तो यह होगा।

आइए फ़ंक्शन के निर्यात को रद्द करें fnऔर नए नियमित fn(जैसा कि ऊपर दिखाया गया है) बरकरार छोड़ दें ।

$ export -nf fn

अब फ़ंक्शन fnनिर्यात नहीं किया जाता है, लेकिन नियमित चर fnहै, और इसमें यह शामिल () { echo "direct" ; }है।

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

और अब "शंख" बग:

जैसा कि हमने अभी देखा, जब एक नया शेल एक नियमित चर की परिभाषा को शुरू करता है, जिसके साथ शुरू होने से ()यह एक फ़ंक्शन के रूप में व्याख्या करता है। हालांकि, यदि फ़ंक्शन को परिभाषित करने वाले समापन ब्रेस के बाद अधिक दिया जाता है, तो यह जो कुछ भी है उसे निष्पादित करता है।

ये आवश्यकताएं हैं, एक बार और:

  1. नए बैश का प्रचार किया जाता है
  2. एक पर्यावरण चर का प्रवेश होता है
  3. यह पर्यावरण चर "()" से शुरू होता है और फिर ब्रेसिज़ के अंदर एक फ़ंक्शन बॉडी होता है, और फिर बाद में कमांड होता है

इस मामले में, एक कमजोर बैश बाद के आदेशों को निष्पादित करेगा।

उदाहरण:

$ export ex='() { echo "function ex" ; }; echo "this is bad"; '
$ bash
this is bad
$ ex
function ex
$

नियमित रूप से निर्यात किया exगया चर उपसमूह में पारित किया गया था जिसे एक फ़ंक्शन के रूप में व्याख्या किया गया था exलेकिन अनुगामी आदेशों को निष्पादित किया गया था ( this is bad) उपधारा के रूप में पैदा किया गया था।


स्लीक वन-लाइन टेस्ट की व्याख्या करते हुए

शेलशॉक भेद्यता के परीक्षण के लिए एक लोकप्रिय वन-लाइनर @ जिप्पी के प्रश्न में उद्धृत है:

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

यहाँ एक ब्रेक-डाउन है: पहले :बैश में सिर्फ एक शॉर्टहैंड है truetrueऔर :दोनों का मूल्यांकन (आप यह अनुमान लगाते हैं) सच है, बाश में:

$ if true; then echo yes; fi
yes
$ if :; then echo yes; fi
yes
$

दूसरा, envकमांड (बाश में भी बनाया गया) पर्यावरण चर (जैसा कि हमने ऊपर देखा था) को प्रिंट करता है, लेकिन उस कमांड को दिए गए निर्यात चर (या चर) के साथ एक ही कमांड को चलाने के लिए भी इस्तेमाल किया जा सकता है, और bash -cइसके से एक कमांड चलाता है कमांड लाइन:

$ bash -c 'echo hi'
hi
$ bash -c 'echo $t'

$ env t=exported bash -c 'echo $t'
exported
$

इसलिए इस सभी सामान को एक साथ सिलाई करके, हम एक कमांड के रूप में बैश चला सकते हैं, इसे करने के लिए कुछ डमी चीज़ दे सकते हैं (जैसे bash -c echo this is a test) और एक चर निर्यात करें जो कि ()उपधारा के साथ शुरू होता है, इसे एक फ़ंक्शन के रूप में व्याख्या करेगा। यदि शेलशॉक मौजूद है, तो यह तुरंत उप-क्रम में किसी भी अनुगामी आदेश को निष्पादित करेगा। चूंकि हम जिस समारोह से गुजरते हैं, वह हमारे लिए अप्रासंगिक है (लेकिन पार्स करना चाहिए!) हम सबसे कम वैध फ़ंक्शन का उपयोग कल्पना करते हैं:

$ f() { :;}
$ f
$ 

यहां फ़ंक्शन fकेवल :कमांड निष्पादित करता है , जो सच लौटाता है और बाहर निकलता है। अब उस कुछ "बुराई" कमांड के लिए अपील करें और एक उपधारा के लिए एक नियमित चर निर्यात करें और आप जीतें। यहाँ फिर से एक लाइनर है:

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

तो xएक साधारण वैध फ़ंक्शन के साथ एक नियमित चर के रूप में निर्यात किया जाता echo vulnerableहै, जो अंत में से निपटने के साथ होता है। इसे बैश करने के लिए पास किया जाता है, और बैश xएक फ़ंक्शन के रूप में व्याख्या करता है (जिसे हम परवाह नहीं करते हैं) तो शायद echo vulnerableशेलशॉक मौजूद है।

हम this is a testसंदेश को हटाकर एक-लाइनर को थोड़ा छोटा कर सकते हैं :

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

यह परेशान नहीं करता है, this is a testलेकिन :फिर से मूक कमांड चलाता है । (यदि आप बंद हो जाते हैं -c :तो आप उपधारा में बैठते हैं और मैन्युअल रूप से बाहर निकलना पड़ता है।) शायद सबसे उपयोगकर्ता के अनुकूल संस्करण यह होगा:

$ env x='() { :;}; echo vulnerable' bash -c "echo If you see the word vulnerable above, you are vulnerable to shellshock"

12
अच्छी व्याख्या। इस सवाल को बहुत सारे विचार मिल रहे हैं (शायद हर कोई दूसरों की तरह बेशर्म होने में सक्षम नहीं है) और मेरा मानना ​​है कि कोई भी अभी तक एक दो शब्दों को खर्च नहीं करता है जो { :;};वास्तव में कहते हैं। मेरी राय में आपके उत्तर के लिए यह एक अच्छा जोड़ होगा। यह बताएं कि प्रश्न में आप अपने उदाहरण से मूल कमांड तक कैसे पहुँचें?
जिप्पी

20

यदि आप किसी प्रोग्राम के लिए मनमाने ढंग से पर्यावरण चर खिला सकते हैं, तो आप इसे अपने चयन के पुस्तकालयों को लोड करके किसी भी चीज़ के बारे में कर सकते हैं। ज्यादातर मामलों में यह उन पर्यावरण चर को प्राप्त करने वाले कार्यक्रम में एक भेद्यता नहीं माना जाता है, बल्कि उस तंत्र में जिसके द्वारा एक बाहरी व्यक्ति मनमाने ढंग से पर्यावरण चर में खिला सकता है।

हालाँकि CVE-2014-6271 अलग है।

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

एक उदाहरण जो CVE-2014-6271 के संदर्भ में सामने रखा गया है, लॉग्सइल को पार्स करने के लिए उपयोग की जाने वाली स्क्रिप्ट है। पर्यावरण चर में आस-पास अविश्वसनीय डेटा पारित करने के लिए उन लोगों की बहुत वैध आवश्यकता हो सकती है। बेशक इस तरह के पर्यावरण चर का नाम इस तरह चुना जाता है कि इसका कोई प्रतिकूल प्रभाव न हो।

लेकिन यहां इस बैश भेद्यता के बारे में क्या बुरा है। किसी भी चर नाम से इसका फायदा उठाया जा सकता है। यदि आप नामक एक पर्यावरण चर बनाते हैं GET_REQUEST_TO_BE_PROCESSED_BY_MY_SCRIPT, तो आप उस पर्यावरण चर की सामग्री की व्याख्या करने के लिए अपनी स्क्रिप्ट के अलावा किसी अन्य कार्यक्रम की अपेक्षा नहीं करेंगे। लेकिन इस बैश बग का दोहन करने से, हर एक पर्यावरण चर हमला वेक्टर बन जाता है।

ध्यान दें कि इसका मतलब यह नहीं है कि पर्यावरण चर के नाम गुप्त होने की उम्मीद है। इसमें शामिल पर्यावरण चर के नामों को जानना किसी हमले को आसान नहीं बनाता है।

यदि program1कॉल program2जो बदले में कॉल करते हैं program3, तो पर्यावरण चर के माध्यम से program1डेटा पास कर सकते हैं program3। प्रत्येक प्रोग्राम में पर्यावरण चर की एक विशिष्ट सूची होती है जिसे वह सेट करता है और एक विशिष्ट सूची जिसे वह कार्य करता है। आप नहीं द्वारा मान्यता प्राप्त एक नाम का चयन करते हैं program2, तो आप से डेटा पारित कर सकते हैं program1करने के लिए program3यह किसी भी प्रतिकूल पर प्रभावित करता है के बारे में चिंता किए बिना program2

एक हमलावर जो निर्यात किए गए चर के सटीक नामों program1और व्याख्या किए गए चर के नामों को program2जानता है, इस ज्ञान का उपयोग 'प्रोग्राम 2` के व्यवहार को संशोधित करने के लिए नहीं कर सकता है अगर नामों के सेट के बीच कोई ओवरलैप नहीं है।

लेकिन यह program2एक bashस्क्रिप्ट के अनुसार टूट गया , क्योंकि इस बग के कारण bashकोड के रूप में हर पर्यावरण चर की व्याख्या होगी।


1
"हर एक पर्यावरण चर एक हमला वेक्टर बन जाता है" - यह वह हिस्सा है जो मुझे याद आ रहा था। धन्यवाद।
wrschneider

9

यह आपके द्वारा जुड़े लेख में समझाया गया है ...

आप बैश शेल को कॉल करने से पहले विशेष रूप से तैयार किए गए मानों के साथ पर्यावरण चर बना सकते हैं। इन चरों में कोड हो सकता है, जो शेल के लागू होते ही निष्पादित हो जाता है।

जिसका अर्थ यह है कि बैश -c "echo this is a test"को कोड में निष्पादित करने के बाद एकल उद्धरण में कोड के साथ बुलाया जाता है।

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

इसका मतलब है कि आपके द्वारा पोस्ट किया गया कोड उदाहरण इस तथ्य का शोषण करता है कि असाइन किए गए बैश असाइनमेंट करने के बाद इस स्ट्रिंग का मूल्यांकन करना बंद नहीं करते हैं। इस मामले में एक फ़ंक्शन असाइनमेंट।

आपके द्वारा पोस्ट किए गए कोड स्निपेट के बारे में वास्तव में विशेष बात, जैसा कि मैं इसे समझता हूं, वह यह है कि जिस कोड को हम निष्पादित करना चाहते हैं, उससे पहले फ़ंक्शन परिभाषा का उपयोग करके, कुछ सुरक्षा तंत्रों को दरकिनार किया जा सकता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.