2012-07-13 6 views
5

मैं अपने सर्वर पर मनमाने ढंग से (संभावित रूप से खतरनाक) बाइनरी निष्पादित करना चाहता हूं। इसलिए, मैंने "अन्य" मैनेम "मुख्य" प्रतीक का नाम बदलने के लिए objcopy का उपयोग किया है ताकि मैं अपने छोटे मुख्य फ़ंक्शन में लिंक कर सकूं जो RLIMIT_CPU के लिए उपयुक्त मान सेट करता है और 0_ध्वज को अन्य_मेन से कॉल करने से पहले ध्वजांकित करता है। मैं अब तक इस समाधान से काफी खुश हूं।SECCOMP: मॉलोक, रीलॉक और मुफ्त का अनुकरण कैसे करें?

समस्या अब यह है कि तीसरे पक्ष के प्रोग्राम कोड में मॉलोक को कुछ कॉल हो सकती हैं जो प्रोग्राम को तुरंत मार सकती हैं (एसआरबीके की अनुमति नहीं है)। इसलिए मैं SECCOMP को सेट करने से पहले कुछ उचित आकार के सरणी (उदा। 20 एमबी) को पूर्व-आवंटित करना चाहता हूं जिसका उपयोग मॉलोक/रीलोक/कॉलोक/फ्री द्वारा किया जाना चाहिए। दुर्भाग्यवश, मुझे नहीं पता कि आखिरी चरण को कैसे संग्रहित किया जाए। क्या मुझे अपने सभी 4 कार्यों को अपने आप लागू करना है? मैं अपने स्वयं के कार्यों को stdlib में कैसे इंजेक्ट कर सकता हूं (उदाहरण के लिए, क्या होता है जब printf आंतरिक रूप से malloc कॉल करता है?)।

+0

नाम बदलना वास्तविक काम है? मुझे आश्चर्य है कि ओएस एक छीन वाली बाइनरी के साथ क्या करता है। –

+0

प्रतीकों का नामकरण ठीक काम करता है। objcopy वास्तव में शक्तिशाली लगता है। आपको स्पष्ट रूप से द्विआधारी को पट्टी करने की अनुमति नहीं है, लेकिन यह मेरे लिए कोई मुद्दा नहीं है, क्योंकि मैं अपने आप को द्विआधारी संकलित करता हूं। यह सिर्फ सी कोड है जो अविश्वसनीय है। – tux21b

+0

क्या आप अपने ओएस की लाइब्रेरी की तुलना में अपने उपयोगकर्ताओं को एक अलग सी लाइब्रेरी (उदाहरण के लिए न्यूलिब) प्रदान कर सकते हैं? यदि ऐसा है, तो अपने स्वयं के 'sbrk' (जो आपके सैंडबॉक्स से बाहर नहीं निकल सकता है) लिखना बहुत आसान होगा और फिर malloc/realloc/calloc/free और दोस्तों सभी काम करेंगे। –

उत्तर

3

सभी malloc कार्यान्वयन sbrk() पर आधारित नहीं हैं, उदाहरण के लिए GNU mmalloc है। कस्टम कार्यान्वयन की आवश्यकता होने पर This doc भी उपयोगी हो सकता है।

+ दो सरल malloc कार्यान्वयन here

+0

एकमात्र सिस्टम कॉल जिन्हें अनुमति है, पढ़ा, लिखना, सिगरेट करना और बाहर निकलना है। इसलिए मैं एमएमएपी का उपयोग नहीं कर सकता, जब तक कि मैं प्रोग्राम की शुरुआत में पर्याप्त स्मृति आवंटित नहीं करता (एक उचित आकार की स्थिर सरणी मेरे उपयोग के मामले के लिए ठीक लगती है)। लिंक हालांकि उपयोगी लगता है, यह मानते हुए कि मुझे वास्तव में अपने स्वयं के मॉलोक को लागू करना है। लेकिन मुझे अभी भी पता नहीं है कि मैं printf और stdlib में अन्य स्थानों में उपयोग की जाने वाली आंतरिक मॉलोक कॉल को कैसे प्रतिस्थापित कर सकता हूं। – tux21b

+0

मैंने उत्तर को सही किया है: dlmalloc वास्तव में sbrk() का उपयोग करता है। हालांकि, वहां मुझे जीएनयू mmaloc मिला जो mmap() पर आधारित है। आपके मामले में आप ढेर के स्थान पर स्थिर पूल [] का उपयोग करने पर विचार कर सकते हैं + इसके आधार पर सरल हैंडलिंग कार्यक्षमता। उदाहरण के लिए, आप स्थिर संदर्भ में एन संदर्भ भी रख सकते हैं। यह निश्चित रूप से छद्म गतिशील स्मृति होगी। – pmod

1

seccompsandbox:

  • एक धागा है, जो आरपीसी प्रदर्शन में seccomp सक्षम बनाता है (से अधिक read/write के माध्यम से एक पूर्व आवंटित socketpair) एक और (गैर seccomp) करने के लिए उसी प्रक्रिया में थ्रेड जो mmap
  • पैचिंग फ़ंक्शन जैसे malloc (इन-मेमोरी, रनटाइम पर) को रीडायरेक्ट करने के लिए विशेषाधिकृत संचालन करने में सक्षम है। ir seccomp-safe wrappers

Chromium's seccomp Sandbox में यह कैसे काम करता है इसके बारे में कुछ और विवरण हैं।

2

मॉलोक और फ्री के लिए, आपके प्रोग्राम को केवल अपने संस्करणों को परिभाषित करने की आवश्यकता है। मैंने देखा है कि अधिकांश libc कार्यान्वयन (glibc, klibc, और dietlibc सहित) खुशी से आपकी स्मृति आवंटन routines का उपयोग करेंगे। तो, seccomp मोड में प्रवेश करने से पहले, mmap या sbrk का उपयोग करके स्मृति का एक बड़ा हिस्सा आवंटित करें और फिर अपने मॉलोक/मुक्त इस खंड से आवंटित करें। memmgr एक साधारण ढेर आवंटक है जिसे निश्चित बफर से आवंटन के लिए आसानी से अनुकूलित किया जा सकता है।

seccomp के साथ वास्तविक समस्या यह है कि सिस्टम कॉल का सेट यह अनुमति देता है (पढ़ना, लिखना, निकालना, और सिगरेट) कम या कम किसी भी libc के खिलाफ जुड़े प्रोग्राम चलाने के लिए पर्याप्त नहीं है। उदाहरण के लिए:

    glibc में
  • , बाहर निकलें और _exit exit_group
  • glibc में फोन, printf mmap dietlibc में
  • कॉल कर सकते हैं, scanf ioctl कॉल कर सकते हैं
  • आदि, आदि

आमतौर पर अच्छे कारण हैं कि ये कॉल आवश्यक क्यों हैं। उदाहरण के लिए, stdout flush करने के लिए, stdin से इनपुट पढ़ा जाता है, यह जांचने के लिए dietlibc ioctl का उपयोग करता है कि stdin एक tty है या नहीं। यह सुनिश्चित करने के लिए मानक व्यवहार है कि आउटपुट लाइन बफर किए जाने पर इंटरैक्टिव इनपुट पढ़ने से पहले संकेत दिखाई दे रहे हैं।

तो, मैं इस निष्कर्ष पर आया हूं कि मूल गुप्त मोड कम या ज्यादा बेकार है। मोड 2 (ए.के.ए. "फ़िल्टर मोड"), हालांकि, अधिक उपयोगी है क्योंकि यह आपको विशिष्ट सिस्टम कॉल को श्वेतसूची में रखने की अनुमति देता है। मेरे पास मेरे जीथब पेज पर proof of concept है जो सीकॉम्प मोड 2 में प्रोग्राम चलाता है, लेकिन उन्हें प्रिंटफ और स्कैनफ़ का उपयोग करने की अनुमति देता है, साथ ही मॉलोक/फ्री का उपयोग करके स्मृति आवंटित करता है।

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