0

I'm trying to learn binary exploitation, and thought of using online samples to train myself. Here's one that I've found, and I can't see to figure out how to exploit it.

int main(int argc, char** argv[])
{
  uint32_t number = 0;
  uint32_t guess = 0;
  char input[8] = {0};

  FILE* devRand = fopen("/dev/urandom", "rb");
  if(devRand == NULL)
  {
    printf("I can't think of a number");
    return EXIT_FAILURE;
  }

  fread(&number, 1, 4, devRand);
  fclose(devRand);

  printf("What number am I thinking of?\n");
  fflush(stdout);

  bool correct = false;
  do
  {
    fgets(&input[0], 28, stdin);
    guess = strtol(&input[0], NULL, 16);

    if (number == guess)
    {
      correct = true;
      printf("Yes!\n");
      fflush(stdout);
      system("/bin/sh");
    }
    else
    {
      printf("No\n");
      fflush(stdout);
    }

  }
  while(!correct);

  return EXIT_SUCCESS;
}

It would be appreciated if someone can give me a detailed explanation of the exploit, how it works, and how it can be mitigated.

Thanks!

rashidx
  • 1
  • 1
  • 1
  • 1
    Because fgets reads 28 chars onto an 8 char buffer... – AstroDan Nov 04 '16 at 14:50
  • You won't get any meaningful feedback if you don't show you did some research yourself. Just asking the community to tell you the solution won't help. The problem with this code is pretty obvious and if you don't see it you should maybe do some research on common coding errors in C related to security... – kaidentity Nov 04 '16 at 14:50
  • @kaidentity thanks for pointing that out. I'm aware that it's a buffer overflow exploit, but I was hoping someone could explain it in detail in beginner terms. – rashidx Nov 04 '16 at 15:02
  • The book "the art of exploitation" covers stuff like this in detail. – kaidentity Nov 04 '16 at 15:10
  • Side note: the input is expected to be in base 16, which seems unusual. Given the fact that the program only prints a yes/no answer (as opposed to lesser/greater), finding the number could take a while... – Clockwork-Muse Nov 04 '16 at 23:15

1 Answers1

3

fgets can read in up to 28 bytes into an 8 byte array.

char input[8];

...

fgets(&input[0], 28, stdin);

Type in 28 bytes of data when prompted, and you'll overflow the input variable. This means that the both guess and number will be overwritten with the first 8 bytes of data past the 8 bytes the array can hold. Any more data provided will continue to overwrite stack protections, and eventually the return address of the function (and beyond).

You can learn more about buffer overflows in this question.

This can be mitigated by making sure you don't read in more bytes than your buffer is allocated.

RoraΖ
  • 12,317
  • 4
  • 51
  • 83