Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Heap Overflow Attack

I am learning about heap overflow attacks and my textbook provides the following vulnerable C code:

/* record type to allocate on heap */
typedef struct chunk {
    char inp[64];            /* vulnerable input buffer */
    void (*process)(char *); /* pointer to function to process inp */
} chunk_t;

void showlen(char *buf)
{
    int len;
    len = strlen(buf);
    printf("buffer5 read %d chars\n", len);
}

int main(int argc, char *argv[])
{
    chunk_t *next;

    setbuf(stdin, NULL);
    next = malloc(sizeof(chunk_t));
    next->process = showlen;
    printf("Enter value: ");
    gets(next->inp);
    next->process(next->inp);
    printf("buffer5 done\n");
}

However, the textbook doesn't explain how one would fix this vulnerability. If anyone could please explain the vulnerability and a way(s) to fix it that would be great. (Part of the problem is that I am coming from Java, not C)

like image 699
tam5 Avatar asked May 20 '15 18:05

tam5


3 Answers

The problem is that gets() will keep reading into the buffer until it reads a newline or reaches EOF. It doesn't know the size of the buffer, so it doesn't know that it should stop when it hits its limit. If the line is 64 bytes or longer, this will go outside the buffer, and overwrite process. If the user entering the input knows about this, he can type just the right characters at position 64 to replace the function pointer with a pointer to some other function that he wants to make the program call instead.

The fix is to use a function other than gets(), so you can specify a limit on the amount of input that will be read. Instead of

gets(next->inp);

you can use:

fgets(next->inp, sizeof(next->inp), stdin);

The second argument to fgets() tells it to write at most 64 bytes into next->inp. So it will read at most 63 bytes from stdin (it needs to allow a byte for the null string terminator).

like image 176
Barmar Avatar answered Oct 21 '22 03:10

Barmar


The code uses gets, which is infamous for its potential security problem: there's no way to specify the length of the buffer you pass to it, it'll just keep reading from stdin until it encounters \n or EOF. It may therefore overflow your buffer and write to memory outside of it, and then bad things will happen - it could crash, it could keep running, it could start playing porn.

To fix this, you should use fgets instead.

like image 5
user4520 Avatar answered Oct 21 '22 03:10

user4520


You can fill up next with more than 64 bytes you will by setting the address for process. Thereby enable one to insert whatever address one wishes. The address could be a pointer to any function.

To fix simple ensure that only 63 bytes (one for null) is read into the array inp - use fgets

like image 1
Ed Heal Avatar answered Oct 21 '22 03:10

Ed Heal