# function overwrite

## Challenge

Story telling class 2/2 You can point to all kinds of things in C. Checkout our function pointers demo [program](https://github.com/HHousen/PicoCTF-2022/blob/master/Binary%20Exploitation/function%20overwrite/vuln/README.md). You can view source [here](https://github.com/HHousen/PicoCTF-2022/blob/master/Binary%20Exploitation/function%20overwrite/vuln.c). And connect with it using `nc saturn.picoctf.net 55620`

## Solution

The program lets us input a string/story and then asks us for two numbers. The first number specifies the index of an array and the second number specifies the value to add at that array index. Crucially, only the upper bound of the array index is checked, which means we can go out of bounds and specify a negative number, thus allowing us to write to arbitrary memory locations. This is exactly what we did in [PicoCTF 2019's L1im1tL355 challenge](https://github.com/HHousen/PicoCTF-2019/blob/master/Binary%20Exploitation/L1im1tL355/README.md).

We are able to write to the array `fun`:

```
void (*check)(char*, size_t) = hard_checker;
int fun[10] = {0};
```

Notice that the `check` pointer is right above the `fun` array. Therefore, that pointer will be the first thing we encounter when tracing backwards through memory with negative array indices. This is important because we will be able to set the `check` pointer to `easy_checker` instead of `hard_checker`. `easy_checker` calls the `calculate_story_score` function and checks if the output is `1337` before printing the flag while `hard_checker` checks for the value `1337` which is not obtainable because the program does not let us input enough characters.

The score is calculated by converting each character to an integer using ascii encoding and then taking the sum. With a little trial and error we see that `aaaaaaaaaaaaa` will get a score of `1261`. So, we just need `1337-1261=76` more points. Looking at an ascii table, `76` corresponds to `L`. So, we can use the string `aaaaaaaaaaaaaL` to get a score of `1337`.

Now, we need to replace the `check` pointer with `easy_checker`'s address. It currently points to `hard_checker`'s address and the value we specify will **added** to the current value. Therefore, we need to add the difference like so `exe.symbols["easy_checker"] - exe.symbols["hard_checker"]`. This will subtract from `hard_checker` the difference between `easy_checker` and `hard_checker`, thus making `check` point to `easy_checker`.

Finally, we just need to brute force the offset. Basically, we will trying writing the address delta to `fun[-1]` and then to `fun[-2]` etc until the flag is printed.

Fun the solution [script.py](https://github.com/HHousen/PicoCTF-2022/blob/master/Binary%20Exploitation/function%20overwrite/script.py) to get the flag.

### Flag

`picoCTF{0v3rwrit1ng_P01nt3rs_529bfb38}`
