मैं स्पष्ट रूप से और सुरक्षित रूप से बैश में अंतर्निहित कमांड के उपयोग को कैसे मजबूर कर सकता हूं


19

एक समान प्रश्न है जो 'रैपिंग' परिदृश्य से संबंधित है, जहां आप उदाहरण cdके लिए एक कमांड के साथ बदलना चाहते हैं जो बिलिन को कॉल करता है cd

हालाँकि, शेलशॉक एट अल के प्रकाश में और यह जानते हुए कि पर्यावरण से कार्यों को आयात करता है, मैंने कुछ परीक्षण किए हैं और मैं cdअपनी स्क्रिप्ट से बेसिन को सुरक्षित रूप से कॉल करने का कोई तरीका नहीं खोज सकता ।

इस पर विचार करो

cd() { echo "muahaha"; }
export -f cd

इस वातावरण में उपयोग की जाने वाली कोई भी स्क्रिप्ट cdटूट जाएगी (किसी चीज़ के प्रभाव पर विचार करें cd dir && rm -rf .)।

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

builtin() { "$@"; }
command() { "$@"; }
type() { echo "$1 is a shell builtin"; }

निम्नलिखित प्राप्त करेंगे:

$ type cd
cd is a shell builtin
$ cd x
muahaha
$ builtin cd x
muahaha
$ command cd x
muahaha

क्या बेसिन कमांड का उपयोग करने के लिए सुरक्षित रूप से बैश करने का कोई तरीका है, या कम से कम यह पता लगाने के लिए कि कमांड पूरे वातावरण को साफ किए बिना, एक बेसिन नहीं है?

मुझे एहसास है कि अगर कोई आपके पर्यावरण को नियंत्रित करता है, तो आप वैसे भी खराब कर सकते हैं, लेकिन कम से कम उपनामों के लिए आपको उपनाम डालने \से पहले कॉल न करने का विकल्प मिला है।


आप envइस तरह से पहले कमांड का उपयोग करके अपनी स्क्रिप्ट चला सकते हैं :env -i <SCRIPT.sh>
अर्कादिअस ड्रेबज़ीक

केवल अगर envएक फ़ंक्शन के रूप में भी पुनर्परिभाषित नहीं किया जाता है। यह भयानक है। मैंने पहले सोचा था कि विशेष वर्ण मदद करेंगे - पूर्ण पथ के साथ कॉल करना /, जिसमें .स्रोत का उपयोग करना शामिल है , और इसी तरह। लेकिन उन का उपयोग फ़ंक्शन नामों के लिए भी किया जा सकता है! आप अपने इच्छित किसी भी फ़ंक्शन को फिर से परिभाषित कर सकते हैं, लेकिन मूल कमांड को कॉल करने के लिए इसे वापस पाना मुश्किल है।
ओरियन

1
सच है, लेकिन अगर आप किसी भी मशीन पर कोई स्क्रिप्ट चलाने जा रहे हैं, तो आप वैसे भी खराब हो जाएंगे। वैकल्पिक रूप से, अपनी स्क्रिप्ट लिखें #/bin/shयदि यह डिफ़ॉल्ट इंटरैक्टिव शेल नहीं है।
अर्कादियुस ड्राज्स्की

जवाबों:


16

ओलिवियर डी लगभग सही है, लेकिन आपको POSIXLY_CORRECT=1चलने से पहले सेट करना होगा unset। POSIX में विशेष अंतर्निहित इन्स की धारणा है , और बैश इसका समर्थन करता हैunsetऐसा ही एक बिलिन है। के लिए खोज SPECIAL_BUILTINमें builtins/*.cएक सूची के लिए बैश स्रोत में, यह भी शामिल है set, unset, export, evalऔर source

$ unset() { echo muahaha-unset; }
$ unset unset
muahaha-unset
$ POSIXLY_CORRECT=1
$ unset unset

दुष्ट unsetअब पर्यावरण से निकाला जा चुका है, यदि आप अनसेट command, type, builtinतो आप आगे बढ़ने के लिए सक्षम होना चाहिए, लेकिन unset POSIXLY_CORRECTआप गैर POSIX व्यवहार या उन्नत बैश सुविधाओं पर निर्भर कर रहे हैं।

हालांकि यह उपनामों को संबोधित नहीं करता है , इसलिए आपको \unsetयह सुनिश्चित करने के लिए उपयोग करना चाहिए कि यह इंटरैक्टिव शेल में काम करता है (या हमेशा, मामले expand_aliasesमें प्रभाव में है)।

पागल के लिए, यह सब कुछ ठीक करना चाहिए , मुझे लगता है:

POSIXLY_CORRECT=1
\unset -f help read unset
\unset POSIXLY_CORRECT
re='^([a-z:.\[]+):' # =~ is troublesome to escape
while \read cmd; do 
    [[ "$cmd" =~ $re ]] && \unset -f ${BASH_REMATCH[1]}; 
done < <( \help -s "*" )

( while, do, doneऔर [[शब्द आरक्षित हैं और सावधानियों की जरूरत नहीं है।) नोट हम प्रयोग कर रहे हैं unset -fको सेट किए बिना कार्यों के लिए सुनिश्चित करने के लिए, चर और कार्यों में एक ही नाम स्थान का हिस्सा हालांकि यह संभव है दोनों का अस्तित्व के लिए एक साथ जिस स्थिति में (Etan Reisner करने के लिए धन्यवाद) दो बार अनसेट-इंग भी कर देगा। आप किसी फ़ंक्शन को आसानी से चिह्नित कर सकते हैं , बैश आपको रीड-ऑन फ़ंक्शन को परेशान करने से नहीं रोकता है और बैश-4.2 सहित, बैश-4.3 आपको रोकता है लेकिन यह तब POSIXLY_CORRECTभी सेट किए गए विशेष बिल्डरों का सम्मान करता है।

एक रीडोनॉली POSIXLY_CORRECTएक वास्तविक समस्या नहीं है, यह बूलियन नहीं है या इसकी उपस्थिति को चिह्नित नहीं करता है, इसलिए पॉसिक्स मोड को सक्षम करता है, इसलिए यदि यह आसानी से मौजूद है तो आप पोसिक्स सुविधाओं पर भरोसा कर सकते हैं, भले ही मूल्य खाली हो या 0. आपको बस आवश्यकता होगी परेशान समस्याग्रस्त कार्य ऊपर की तुलना में एक अलग तरीका है, शायद कुछ कट-एंड-पेस्ट के साथ:

\help -s "*" | while IFS=": " read cmd junk; do echo \\unset -f $cmd; done

(और किसी भी त्रुटि को अनदेखा करें) या कुछ अन्य स्क्रिप्टोबैटिक्स में संलग्न हैं ।


अन्य नोट:

  • functionएक आरक्षित शब्द है, इसे अलियास किया जा सकता है लेकिन एक फ़ंक्शन के साथ ओवरराइड नहीं किया जा सकता है। (अलियासिंग functionहल्के से तकलीफदेह है क्योंकि इसे दरकिनार करने के तरीके के रूप में स्वीकार्य \function नहीं है)
  • [[, ]]आरक्षित शब्द हैं, उन्हें अलियास किया जा सकता है (जिसे अनदेखा किया जाएगा) लेकिन एक फ़ंक्शन के साथ ओवरराइड नहीं किया जाता है (हालांकि कार्यों को नाम दिया जा सकता है)
  • (( किसी फ़ंक्शन के लिए मान्य नाम नहीं है, और न ही एक उपनाम

दिलचस्प है, धन्यवाद! मुझे अजीब लगता है कि बैश एट अल को ओवरराइट होने से बचाने के लिए डिफ़ॉल्ट नहीं होगा unset
बाजीगर

यह -fतर्क की जरूरत है unsetयह नहीं है? अन्यथा यदि एक वैरिएबल और फंक्शन दोनों को एक ही नाम दिया गया है जो कि एक बेसिन के रूप में परिभाषित किया गया है तो unsetपहले वेरिएबल को अनसेट करने के लिए चुना जाएगा। यह भी विफल रहता है अगर कोई भी अस्पष्ट कार्य सेट readonlyहै तो क्या यह नहीं है? (हालांकि यह पता लगाने योग्य है और इसे एक घातक त्रुटि बनाया जा सकता है।) इसके अलावा यह बनी हुई याद आती [है।
इटन रिस्नर 18

1
मुझे नहीं लगता कि \unset -f unsetइससे कोई मतलब नहीं है, यह देखते हुए इसे लूप में किया जाएगा। यदि unsetकोई ऐसा कार्य है जो आपके \unsetसामान्य रूप से बिलिन के बजाय इसका समाधान करेगा, लेकिन आप \unsetसुरक्षित रूप से इतने लंबे समय तक उपयोग कर सकते हैं जब तक कि POSIX मोड प्रभावी हो। स्पष्ट रूप से बुला रहा \unset -fहै [, .और :एक अच्छा विचार हो सकता है, क्योंकि आपका regex उन्हें बाहर निकालता है। मैं भी जोड़ना होगा -fकरने के लिए \unsetलूप में, और होगा \unset POSIXLY_CORRECTपाश के बाद, इससे पहले के बजाय। \unalias -a(बाद में \unset -f unalias) एक को बाद के आदेशों पर सुरक्षित रूप से भागने की अनुमति देता है।
एड्रियन गुंटर

1
@ AdrianGünter आज़माएँ: [[ ${POSIXLY_CORRECT?non-POSIX mode shell is untrusted}x ]]यह एक गैर-संवादात्मक स्क्रिप्ट के कारण संकेतित त्रुटि से बाहर निकलने का कारण बनेगा यदि चर सेट नहीं किया गया है, या इसे सेट (खाली, या कोई मान) जारी रखें।
mr.spuratic

1
"आप का उपयोग करना चाहिए \unset" ... यह ध्यान दिया जाना चाहिए कि किसी भी चरित्र का उद्धरण उपनामों के विस्तार से बचने के लिए काम करेगा, न कि पहले। un"se"tबस के रूप में अच्छी तरह से काम करते हैं, कम पठनीय होना चाहिए। "प्रत्येक साधारण कमांड का पहला शब्द, यदि अयोग्य घोषित किया गया है, तो यह देखने के लिए जाँच की जाती है कि उसमें एक उपनाम है या नहीं।" - बैश रेफ
रॉबिन ए। मीड

6

मुझे एहसास है कि अगर कोई आपके पर्यावरण को नियंत्रित करता है तो आप वैसे भी खराब हो सकते हैं

हाँ कि। यदि आप किसी अज्ञात वातावरण में स्क्रिप्ट चलाते हैं, तो सभी तरह की चीजें गलत हो सकती हैं, जिसके LD_PRELOADकारण शेल प्रक्रिया को मनमाने ढंग से कोड निष्पादित करने से पहले शुरू किया जाता है, यहां तक ​​कि आपकी स्क्रिप्ट को पढ़ने से पहले। स्क्रिप्ट के अंदर से शत्रुतापूर्ण वातावरण से बचाने की कोशिश करना निरर्थक है।

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

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


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

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

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

@DejayClayton जाहिर तौर पर पर्यावरण को साफ करने से पर्यावरण को असंबंधित अटैक वैक्टर से मदद नहीं मिलती है। (उदाहरण के लिए एक स्क्रिप्ट जो चेरोट /bin/catमें कॉल करता है , वह कुछ भी कह सकता है।) पर्यावरण को साफ करने से आपको एक समझ मिलती है PATH(यह मानते हुए कि आप इसे सही तरीके से कर रहे हैं)। मैं अभी भी आपकी बात नहीं देख रहा हूं।
गिल्स एसओ- बुराई को रोकना '

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

1

आप unset -fकार्यों के निर्माण, कमांड और प्रकार को हटाने के लिए उपयोग कर सकते हैं ।


2
क्षमा करें, unset() { true; }यह ध्यान रखता है।
बाजीगर 12

1
अरे नहीं! और परिभाषित कार्य सूचीबद्ध करना भी एक बेसिन पर निर्भर करता है। मैं हार मानता हूं!
odc
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.