c - मैं बफर ओवरफ़्लो कैसे आ सकता हूं?




pointers stack-trace (4)

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

#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;
}

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


इसको आजमाओ:

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;
}

चूंकि यह होमवर्क है, इसलिए मैं समझने के लिए कोडडिक्ट के सुझाव को गूंजना चाहता हूं कि बफर ओवरफ्लो वास्तव में कैसे काम करता है।

मैंने बफर ओवरफ्लो भेद्यता का शोषण करने के लिए उत्कृष्ट (यदि थोड़ा दिनांकित) लेख / ट्यूटोरियल पढ़कर तकनीक सीखी और मज़ा और लाभ के लिए स्टैक को तोड़ दिया


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

निम्नलिखित कोड जीसीसी 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

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

फ़ंक्शन एपिलॉग -जैसी इनलाइन असेंबली को स्टैक पर रिटर्न पते के मान को संशोधित करने के लिए f() जोड़ा गया है ताकि f() g() माध्यम से वापस आ जाए।

#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;
}

इस कोड के काम को समझने से यह समझने में मदद मिल सकती है कि किसी विशेष आर्किटेक्चर के लिए फ़ंक्शन का स्टैक फ्रेम कैसे सेट किया जाता है जो बफर ओवरफ़्लो तकनीकों का आधार बनाता है।





fortify-source