0

I'm trying to get the following C program to execute the win function by making use of a buffer overflow, however, I'm completely stuck as I cannot figure out the correct input. In this challenge, I was given a compiled executable and the below code was analyzed and extracted with Ghidra.

main function:

undefined8 main(void)

{
  char *local_28;
  char local_1a [9];
  char local_11;
  code *local_10;
  
  local_11 = '\x01';
  local_1a[0] = -0x11;
  printf("Enter number: ");
  fgets(local_1a,10,stdin);
  local_10 = (code *)strtol(local_1a,&local_28,10);
  printf("Parsed to %ld\n",local_10);
  if (local_11 == '\0') {
    (*local_10)();
  }
  return 0;
}

win function:

void win(void)

{
  puts("FLAG{it worked");
  return;
}

So far I've tried to use gdb to figure out the offset and pass the address of the win function, but no matter what I try I get a segmentation fault.

goatw
  • 55
  • 7
  • 1
    Why? If you want to execute the function win, just do `win();` ;) – pmg Jan 18 '22 at 09:25
  • It's an exploit or capture the flag, where the goal is to get the flag only with your input to the running program. – goatw Jan 18 '22 at 09:27
  • Doesn't look to me you want to exploit an overflow to call `win`.. you are just trying to pass an address of a function that later you are going to call. Where is your intended overflow? Also note that `&local_28` will lead to undefined behavior as `local_28` is uninitialized – Jack Jan 18 '22 at 09:29
  • 1
    Calling a function by exploiting an overflow typically requires you to input data that doesn't fit into the local stack, so that it will overflow allocated memory and will rewrite the returning instruction pointer: that is on successful overflow, `win` should be called after `return` statement. – Jack Jan 18 '22 at 09:32
  • @Jabberwocky `scanf` stores data into the memory pointed by `&foo` which is allocated to the stack when you type `int foo`.. but I guess you are right, my fault. After `strtol()`, `local_28` will point to the first unconverted char. – Jack Jan 18 '22 at 09:34
  • 1
    @Jack damn, now I delted my comment which I thought was wrong, but actually it was correct... – Jabberwocky Jan 18 '22 at 09:35
  • Ok to I need to pass the function address to `fgets()` but how do I set `local_11` to 0 to get it executed? – goatw Jan 18 '22 at 09:44
  • What is `code`? What input did you try? Post a [mcve]. Posted code does not compile. – chux - Reinstate Monica Jan 18 '22 at 10:16
  • Step 1 is to give the program some input that causes `local_11` to be overwritten with the value `'\0'`. In principle that should be fairly easy... just give the program a 9++ long input. However, this will only work if `local_11` is located immediately after `local_1a`. Have you checked that? Could you enter the if statement? – Support Ukraine Jan 18 '22 at 10:35
  • I've given it more than 9 bytes of input, but the program then just exits with a segmentation fault. I'm not sure how to check the location of both variables in gdb. – goatw Jan 18 '22 at 11:07

1 Answers1

0

I don't see any buffer overflow here; you are just trying to pass the address of a function (which you know in advance) as input, convert the input into a valid address, and call such address like a normal function.. it should work, but it has nothing to do with buffer overflow attack technique.

For an overflow attack to be successful you may want to overflow the memory allocated into the function stack so that the returning instruction pointer (which on some architecture is placed after the stack allocation) is rewritten with an address of your choice. With the returning instruction pointer rewritten, once you call return the next instruction that will be executed will be the one existing at the rewritten address.

In code:

char buf[0];
fgets(buf, 100, stdin);
return;

With this code, it's up to you to pass as stdin a string that will contain the address properly coded (bytes concatenation) at the proper offset.

If, like I see in your code, you want your program to convert the user input into a valid address, then you have to work a bit with the offset yourself.

Also note that many compilers nowadays add a mechanism to prevent stack memory overflow, and the execution may stop with en exception.

Jack
  • 1,488
  • 11
  • 21
  • 3
    But there _is_ a buffer overflow. Check the `fgets` size limit vs buffer size. It's also required to exploit that to make `local_11` be 0. – hyde Jan 18 '22 at 10:01
  • Yes and that's what I can't figure out so far. – goatw Jan 18 '22 at 10:06
  • So by overflow you just mean that you store a pointer (which by the way it's likely to be 8-bytes long) into a 9-bytes memory cell, by inserting a 10-bytes string.. which stores the last byte into the following variable.. Understood. That's ok; it has nothing to do with buffer overflow technique, it's just a.. normal overflow? Ok, i was mislead by the title – Jack Jan 18 '22 at 10:09
  • Sorry if the title was misleading, I'm new to this topic. – goatw Jan 18 '22 at 10:14
  • This answer is just wrong. There is buffer overflow when given correct input – Support Ukraine Jan 18 '22 at 10:23
  • @4386427 I agree; there is a buffer overflow which is not related with the fact of calling a function my inputting its address, that's why I got confused; I'll leave the answer for reference – Jack Jan 18 '22 at 11:40