csegmentation-faultbuffer-overflow

Why getting "segmentation fault" when sending 127 characters to a buffer with capacity of 128


I have the following code taken from a binary exploitation exercises:

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

#define BANNER \
  "Welcome to " LEVELNAME ", brought to you by https://exploit.education"

char *gets(char *);

void start_level() {
  char buffer[128];
  gets(buffer);
}

int main(int argc, char **argv) {
  printf("%s\n", BANNER);
  start_level();
}

My question is regarding the way the buffer stores the information.
Our buffer has storage for 128 characters.

When I send 127 characters I am getting segmentation fault:

user@phoenix-amd64:/opt/phoenix/amd64$ python -c 'print("A"*127)'  | ./stack-five 
Welcome to phoenix/stack-five, brought to you by https://exploit.education
Segmentation fault

But if I send 126 characters, there is not error:

user@phoenix-amd64:/opt/phoenix/amd64$ python -c 'print("A"*126)'  | ./stack-five 
Welcome to phoenix/stack-five, brought to you by https://exploit.education
user@phoenix-amd64:

If the buffer has capacity of 128, and I sent it 127 characters, why it failed? It should have at least one more place no?

One thing I though is maybe after sending 127 characters, it adds the NULL terminator (\x00) but even if that happens, we have exactly 128 characters, so why it crash?


Solution

  • You have a buffer overflow between the '\n' that Python print() adds and the '\0' you need for the string that c adds:

    [python3 -c 'print("A"*126)' | wc -c
    127
    

    I would fix that in Python with:

    python3 -c "print('A'*126, end='')" | wc -c
    126
    

    gets() is unsafe so use fgets() instead.