2012-01-26 12 views
6

में सेट-यूआईडी और इंटरप (डायनामिक लिंकर) के लिए एक सापेक्ष पथ के साथ सुरक्षा समस्या ईएलएफ बाइनरी के इंटरप अनुभाग में सेट-यूआईडी और रिश्तेदार पथ का संयोजन बहुत खतरनाक है।ईएलएफ

मैं काफी यकीन है कि कैसे और कहाँ इस समस्या को सूचित किया जाना चाहिए नहीं कर रहा हूँ, लेकिन यह linux/glibc कार्यों में कैसे गतिशील जोड़ने के विषय में एक सामान्य सुरक्षा समस्या की तरह मुझे लगता है, तो मुझे समझाने कि यह क्या है करते हैं:

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

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

./issue 

या बस की तरह सेट uid द्विआधारी पर अमल तो

#include <stdio.h> 

// 
// build with: 
// gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c 
// sudo chown root issue 
// sudo chmod u+s issue 
// now build some code to be executed with root permissions (we use the same issue.c): 
// mkdir -p .lib64/ 
// gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c 
// 

int main(int argc, char* argv[]) 
{ 
    printf("(%s) euid:%d\n", NAME, geteuid()); 
} 

:

इस का प्रदर्शन करने के लिए निम्न सी कोड (issue.c) पर एक नज़र जैसे इस

ldd issue 

कर के बजाय आप क्या उम्मीद कर सकते हैं हो रही,:

(vulnarable) euid:0 

आपको मिलेगा:

(rootkit) euid:0 

अब बात आप ld-linux-x86-64.so.6 द्विआधारी जो कुछ के साथ आप की तरह बदल सकते है।

इसी तरह के मुद्दों को RPATH में $ ORIGIN को हल करने या सेट-यूआईडी ध्वज सेट होने पर LD_LIBRARY_PATH को अनदेखा करके संबोधित किया गया है।

तो मुझे आश्चर्य है कि ईएलएफ में इंटरप को अनदेखा किया जाना चाहिए, जब भी सेट-यूआईडी ध्वज सेट किया जाता है (यानी डिफ़ॉल्ट गतिशील लिंकर - /lib32/ld-linux.so.2 या/lib64/ld- लिनक्स x86-64.so.2)?

तो आप क्या सोचते हैं, यह कहां तय किया जाना चाहिए या रिपोर्ट किया जाना चाहिए - glibc या कर्नेल में?

+0

आप रूट पहुंच प्राप्त करने का एक तरीका सुझा रहे हैं, जिसमें 'सुडो' का उपयोग करना शामिल है। जिसका मतलब है कि आपको इसे करने के लिए रूट पहुंच की आवश्यकता है। – ugoren

+0

आपने किस कर्नेल और डिस्ट्रो को परीक्षण किया था? मुझे उबंटू 10.04 पर कर्नेल 2.6.32-38-जेनेरिक के साथ इस मुद्दे को पुन: उत्पन्न करने में समस्या हो रही है: मुझे जो कुछ मिलता है वह '(./issue) euid: 0' है, जो एक सेट्यूड प्रोग्राम के लिए अपेक्षित है। –

+0

@ugoren: वास्तव में नहीं। भेद्यता मानना ​​वास्तविक है, एक हमलावर को एक कमजोर सेटुइड प्रोग्राम खोजने की आवश्यकता होगी। निर्देशों में 'सुडो' आदेश केवल एक बनाने के लिए हैं, ताकि समस्या का प्रदर्शन किया जा सके। –

उत्तर

5

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

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

+0

सहमत हुए। यह एक सेट्यूड प्रोग्राम में 'system()' को कॉल करने जैसा है जो एक पूर्ण पथ नहीं है। मुझे यह जोड़ना चाहिए, अगर कोई प्रोग्राम में libc के कस्टम संस्करण का उपयोग करना चाहता है, तो ऐसा करने के लिए एक सापेक्ष INTERP का उपयोग न करें; इसके बजाए इसे स्थिर रूप से लिंक करें। एलजीपीएल आम तौर पर इसे अनुमति देता है। – Dolda2000

+0

@ एफएक्स: अच्छा जवाब, मैं सेट-यूआईडी ध्वज कहां रखता हूं, इस पर सावधान रहने पर सहमत हूं, हालांकि आपका तर्क ईएलएफ या एलडी_LIBRARY_PATH env var में RPATH/RUNPATH पर भी लागू होगा - इस मामले में (सेट-यूआईडी ध्वज), RPATH/RUNPATH और LD_LIBRARY_PATH सभी को एक साथ अनदेखा किया जाता है। तो इंटरप को अनदेखा क्यों नहीं कर रहे हैं? – siddhadev

+2

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

संबंधित मुद्दे