2
votes

I'm studying buffer overflow, and I'm trying to jump to the function 'confused' and then print out "done" at the end of main by performing buffer overflow.

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

int i, n;
void confused(int i) {
  printf("**Who called me? Why am I here?? *** %x\n ", i);
  ;
}

void shell_call(char *c) {
  printf(" ***Now calling \"%s\" shell command *** \n", c);
  system(c);
}

void victim_func(){
  int a[4];
  printf("\nEnter n:  ");  scanf("%d",&n);
  printf("~~~~~~~~~~~~~ values and address of n locations ~~~~~~~~~~");
  for (i = 0;i <n ;i++)
    printf ("\n a[%d] = %x, address = %x", i, a[i], &a[i]);
  printf("\nEnter %d HEX Values \n", n);

  // Buffer Overflow vulnerability HERE!

  for (i=0;i<n;i++)  scanf("%x",&a[i]);
    printf("Done reading junk numbers\n")
}

int main() {
  printf("\n ~~~~~~~~~~~~~~~~~ Info Menu ~~~~~~~~~~~~");
  printf("\n addrss of main %x", main);
  printf("\n addrss of shell_cal %x", shell_call);
  printf("\n addrss of confused %x", confused);
  victim_func();
  printf("\n done");
  return 0;
}

What I did is I put 7 for n, and for 6th hex value I inserted the address of confused and for 7th the address of printf in main. It successfully prints out "done" after the confused function, but the program goes back to the start of main. I thought the program would terminate after printing out "done".

I just wonder if I did something wrong, or it is the way it should do.

1
You should investigate the generated assembly code, and maybe use a stand-alone assembler to get a full Listing with the assembly and the machine code.luser droog
your code clobbered the stack when it wrote to any a[x] where x is greater than 3. Function return address(s) are stored on the stack. Your code stepped on the return address (and other things) that are stored on the stack.user3629249
what do you mean by the stack is 'clobbered'? does it mean the code overwrite the stack including the return address so it cannot return cleanly?ShiShKebab

1 Answers

0
votes

You can always call exit() in your shell code to terminate the program. However, you can't do it using system(), because system() will create a child process which always ultimately return to it parent. You need to directly call exit() using assembly.