2010-02-25 31 views
29

मैं एक होमवर्क असाइनमेंट मुझसे पूछे स्पष्ट रूप से इसे बुला, बफर अतिप्रवाह का उपयोग किए बिना एक समारोह आह्वान करने के लिए मिला है। कोड मूल रूप से यह है:मैं बफर ओवरफ़्लो कैसे आ सकता हूं?

#include <stdio.h> 
#include <stdlib.h> 

void g() 
{ 
    printf("now inside g()!\n"); 
} 


void f() 
{ 
    printf("now inside f()!\n"); 
    // can only modify this section 
    // cant call g(), maybe use g (pointer to function) 
} 

int main (int argc, char *argv[]) 
{ 
    f(); 
    return 0; 
} 

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

+9

4 upvotes! ओपी भी सवाल के साथ नहीं आया ... वाह, कुछ लोग आसानी से प्रभावित हुए हैं। – Lazarus

+0

@ लाज़र, मैंने आपकी टिप्पणी को ऊपर उठाया। उह ओह!:-) –

+15

@ लाज़र यह तथ्य है कि यह एक होमवर्क प्रश्न है, इस तथ्य से कोई लेना देना नहीं है कि मुझे यह दिलचस्प लगता है। मैंने इसे भी ऊपर उठाया क्योंकि मैं सरल होमवर्क सवालों को सरल बनाने के बजाय प्रोत्साहित करना चाहता हूं "मैंने फ़ाइल बफर बंद कर दिया और अब जब मैं फ़ाइल से पढ़ने का प्रयास करता हूं तो यह काम नहीं करता है। क्यों?" (दूसरे शब्दों में, मैं सवाल मैं करने के लिए उत्तर नहीं पता वोट दें, लेकिन करना चाहते हैं), LOL – Yacoby

उत्तर

14

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

मैं आपको सुझाव दूंगा कि वे वास्तव में समझने के बिना यहां दिए गए किसी भी कार्यक्रम को अंधाधुंध नहीं लेते हैं। यह लेख बहुत अच्छी तरह से लिखा है और आप इसे बहुत ही उपयोगी मिल जाएगा:

A step-by-step on the buffer overflow vulnerablity

3

इस एक का प्रयास करें:

void f() 
{ 
    void *x[1]; 
    printf("now inside f()!\n"); 
    // can only modify this section 
    // cant call g(), maybe use g (pointer to function) 
    x[-1]=&g; 
} 

या इस एक:

void f() 
{ 
    void *x[1]; 
    printf("now inside f()!\n"); 
    // can only modify this section 
    // cant call g(), maybe use g (pointer to function) 
    x[1]=&g; 
} 
+3

एक स्पष्टीकरण बहुत अच्छा होगा, क्योंकि यह होमवर्क है। –

+2

x एक स्थानीय चर है, इसलिए यह ढेर पर स्थित है। चूंकि x आकार 1 की सरणी है, केवल x [0] मान्य है। एक्स [-1] या एक्स [1] में जी के पते को लिखकर, एक मौका है कि हम वापसी पते को ओवरराइट करेंगे। यह उस स्टैक के संगठन पर निर्भर करता है जो संस्करण काम करता है। –

11

संकलक निर्भर है यही कारण है, इसलिए कोई भी इस सवाल का जवाब दिया जा सकता है।

निम्नलिखित कोड आप जीसीसी 4.4.1 के लिए क्या चाहते हैं कर सकते हैं। संकलित करें अनुकूलन के साथ अक्षम

#include <stdio.h> 
#include <stdlib.h> 

void g() 
{ 
    printf("now inside g()!\n"); 
} 


void f() 
{ 
    int i; 
    void * buffer[1]; 
    printf("now inside f()!\n"); 

    // can only modify this section 
    // cant call g(), maybe use g (pointer to function) 

    // place the address of g all over the stack: 
    for (i=0; i<10; i++) 
    buffer[i] = (void*) g; 

    // and goodbye.. 
} 

int main (int argc, char *argv[]) 
{ 
    f(); 
    return 0; 
} 

आउटपुट (महत्वपूर्ण!):

[email protected]:~$ gcc overflow.c 
[email protected]:~$ ./a.out 
now inside f()! 
now inside g()! 
now inside g()! 
now inside g()! 
now inside g()! 
now inside g()! 
now inside g()! 
Segmentation fault 
+0

मैं जीसीसी 4.4.1 का उपयोग कर रहा है, और यकीन नहीं कैसे अनुकूलन बंद करने के लिए: की कोशिश की जीसीसी -O0 -ओ शौकीन buff.c (कि ओह शून्य है) और भी जीसीसी -O1 -fno-आस्थगित करें पॉप - fno-धागे की कूदता -fno शाखा-संभावनाओं -fno-cprop-रजिस्टरों -fno-लगता है कि शाखा-संभावना -fno-न आना-फ्रेम सूचक -ओ शौकीन buff.c न काम किया। – sa125

+1

'जी()' के अंदर आवेदन बाहर निकलें समारोह विभाजन गलती से बचने के लिए =) – Kieveli

+0

sa125, हो सकता है जीसीसी एक अलग सीपीयू वास्तुकला के लिए अनुकूलन करने के लिए कोशिश करता है सुनिश्चित करें। जहां तक ​​मुझे पता है कि यह आपके द्वारा चलाए जा रहे सिस्टम के सीपीयू पर डिफ़ॉल्ट है। यह बदल सकता है कि f() की स्टैकफ्रेम कैसा दिखता है और ओवरफ़्लो होने से रोक सकता है। –

7

के बाद से इस होमवर्क है, मैं समझ कैसे एक बफर अतिप्रवाह वास्तव में काम करता है की प्रतिध्वनित करने के लिए codeaddict's suggestion चाहते हैं।

मैं उत्कृष्ट (यदि थोड़ा दिनांकित) लेख/ट्यूटोरियल पढ़ने पर बफर अतिप्रवाह शोषण कमजोरियों Smashing The Stack For Fun And Profit द्वारा तकनीक सीखा है।

+2

+1। –

3

इस समाधान स्टैक पर फ़ंक्शन द्वारा दिया गया पता अधिलेखित करने के लिए एक अतिप्रवाह तकनीक का उपयोग नहीं करता, यह अभी भी g() का कारण बनता है जबकि केवल f() को संशोधित करने और g() सीधे कॉल नहीं द्वारा f() वापस main() की राह पर से कहा जाता है करने के लिए।

Function epilogue तरह इनलाइन विधानसभा ढेर पर वापसी पता के मूल्य को संशोधित करने के लिए इतना है कि f()g() के माध्यम से वापस आ जाएगी f() में जोड़ा जाता है।

#include <stdio.h> 

void g() 
{ 
    printf("now inside g()!\n"); 
} 

void f() 
{ 
    printf("now inside f()!\n"); 
    // can only modify this section 
    // cant call g(), maybe use g (pointer to function) 

    /* x86 function epilogue-like inline assembly */ 
    /* Causes f() to return to g() on its way back to main() */ 
    asm(
     "mov %%ebp,%%esp;" 
     "pop %%ebp;" 
     "push %0;" 
     "ret" 
     : /* no output registers */ 
     : "r" (&g) 
     : "%ebp", "%esp" 
     ); 
} 

int main (int argc, char *argv[]) 
{ 
    f(); 
    return 0; 
}

समझना कैसे इस कोड काम करता है कि कैसे एक समारोह के ढेर फ्रेम एक विशेष वास्तुकला जो बफर अतिप्रवाह तकनीक का आधार होता है के लिए सेटअप है की एक बेहतर समझ के लिए नेतृत्व कर सकते हैं। एक होमवर्क प्रश्न के लिए

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