Simple Buffer Overflow Exploit

2019-06-13 17:44发布

问题:

I am trying to write a very simple program that highlights how a buffer overflow exploit can be used to bypass a password protected system. The code is given below:

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buff[15];
    char tempbuff[15];
    int pass = 0;

    printf("\n Enter a password of length between 1 and 15 characters : \n");
    gets(buff);
    //strcpy("%s",buff);

    printf("\n Enter your password : \n");
    gets(tempbuff);
    //strcpy("%s",tempbuff);

    if(strcmp(tempbuff, buff))
    {
        printf ("\n Wrong Password \n");

    }
    else
    {
        printf ("\n Correct Password \n");
        pass = 1;
    }

    if(pass)
    {
       /* Now Give root or admin rights to user*/
        printf ("\n Root privileges given to the user \n");
    }

    return 0;
}

Essentially, I am trying to alter the value of the pass variable from 0 to 1 by inputting a string that is greater than 15 characters when asked to input my password the second time around. However, I haven't been able to do so as of yet. Any help will be very appreciated!

回答1:

I was able to exploit your program in OS X with one change to your code. That was to define pass before tempbuff. Declaring pass before tempbuff means that pass is placed after tempbuff on the stack and therefore overflowing tempbuff will overwrite pass. I was able to check the addresses of pass and tempbuff in lldb (or gdb).

I also compiled it with the -fno-stack-protector option.

#include <stdio.h>
#include <string.h>

int main(void)
{
    char buff[15];
    int pass = 0;
    char tempbuff[15];

    printf("\n Enter a password of length between 1 and 15 characters : \n");
    gets(buff);

    printf("\n Enter your password : \n");
    gets(tempbuff);

    if(strcmp(tempbuff, buff))
    {
        printf ("\n Wrong Password \n");
    }
    else
    {
        printf ("\n Correct Password \n");
        pass = 1;
    }

    if(pass)
        printf ("\n Root privileges given to the user \n");

    return 0;
}

Compiled with: gcc -Wall -Wextra -O0 -g -fno-stack-protector buf.c -o buf

Here is the input sequence:

safepassword
1234567890123456

Here is the output:

$ ./buf < over

 Enter a password of length between 1 and 15 characters :
warning: this program uses gets(), which is unsafe.

 Enter your password :

 Wrong Password

 Root privileges given to the user


回答2:

There is no guarantee on the order in which the memory will be allocated for the local variables, and there is no guarantee that they will be in consecutive locations. The following modified code should work in most systems. It uses the fact that structure elements are allocated consecutive memory locations (also note that the array sizes have been changed to avoid padding.)

#include <stdio.h>
#include <string.h>

struct app {
    char buff[16];
    char tempbuff[16];
    int pass;
};

int main(void)
{
   struct app app;
   app.pass = 0;

    printf("\n Enter a password of length between 1 and 15 characters : \n");
    gets(app.buff);
    //strcpy("%s",buff);

    printf("\n Enter your password : \n");
    gets(app.tempbuff);
    //strcpy("%s",tempbuff);

    if(strcmp(app.tempbuff, app.buff))
    {
        printf ("\n Wrong Password \n");

    }
    else
    {
        printf ("\n Correct Password \n");
        app.pass = 1;
    }

    if(app.pass)
    {
       /* Now Give root or admin rights to user*/
        printf ("\n Root privileges given to the user \n");
    }

    return 0;
}