# Challenge Name

## Problem

> Exploit the function pointers in this program. It is also found in /problems/pointy\_4\_3b3533bd4e08119669feda53e8cb0502 on the shell server. Source.

* [Program](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Binary%20Exploitation/pointy/vuln/README.md)
* [Source](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Binary%20Exploitation/pointy/vuln.c)

## Solution

1. The provided program allows us to enter students and professors. Students can then rate the professors.
2. The bug in the program is that we can select professors as students and students as professors. We can write the `lastScore` of a `Professor` and then treat it as a `Student` to control the `scoreProfessor` field.
3. The `Student` and `Professor` `struct`s are as follows:

   ```cpp
    struct Professor {
        char name[NAME_SIZE];
        int lastScore;
    };

    struct Student {
        char name[NAME_SIZE];
        void (*scoreProfessor)(struct Professor*, int);
    };
   ```

   `scoreProfessor` is a function pointer that is in the same position relative to the `struct` as `lastScore` is in `Professor`. We can create a `Professor` and set the `lastScore` variable to the address of `win()`. Then, we can convert that professor to a student, which will override the `scoreProfessor` pointer and point it to the `win()` function. (`scoreProfessor` is pointed to `giveScoreToProfessor()` on line 79: `student->scoreProfessor=&giveScoreToProfessor;`.) Thus, when the `scoreProfessor` pointer is called (close to the end of the file: `student->scoreProfessor(professor, value);`), the `win()` function will be executed and we will get the flag.
4. Script ([script.py](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Binary%20Exploitation/pointy/script.py)) Walkthrough:
   1. Allocate a student `s1`
   2. Allocate a professor `p1`
   3. Use student `s1` to give the score
   4. Give the score to professor `p1`
   5. Set the `lastScore` attribute of professor `p1` to the address of `win()`
   6. The loop in [vuln.c](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Binary%20Exploitation/pointy/vuln.c) restarts
   7. Allocate another student `s2` (only necessary to proceed to next inputs in program)
   8. Allocate another professor `p2` (only necessary to proceed to next inputs in program)
   9. Use professor `p1` (which has the address of `win()`) to give a score. This converts professor `p1` to a student, thus overwriting the `scoreProfessor` function pointer to `win()`.
   10. Give the score to professor `p1`. This does not matter since we only care about the last line (`student->scoreProfessor(professor, value);`) where `scoreProfessor` (aka `win()`) is called. You could use `p2` here as well since it is the extra professor we created earlier.
   11. Give a score of `0` to professor `p1`, but not really since the `scoreProfessor` function pointer points to `win()` and not `giveScoreToProfessor()` since we changed it by converting a `Professor` to a `Student`.
5. Run the [script.py](https://github.com/HHousen/PicoCTF-2019/tree/24b0981c72638c12f9a8572f81e1abbcf8de306d/Binary%20Exploitation/pointy/script.py) `python script.py USER=<username> PASSWORD=<password>`:

   ```
    [*] '/home/<username>/Documents/PicoCTF/Binary Exploitation/pointy/vuln'
        Arch:     i386-32-little
        RELRO:    Partial RELRO
        Stack:    Canary found
        NX:       NX enabled
        PIE:      No PIE (0x8048000)
    [+] Connecting to 2019shell1.picoctf.com on port 22: Done
    [*] <username>@2019shell1.picoctf.com:
        Distro    Ubuntu 18.04
        OS:       linux
        Arch:     amd64
        Version:  4.15.0
        ASLR:     Enabled
    [+] Opening new channel: 'pwd': Done
    [+] Receiving all data: Done (14B)
    [*] Closed SSH channel with 2019shell1.picoctf.com
    [*] Working directory: '/tmp/tmp.klHpIRVO8i'
    [+] Opening new channel: 'ln -s /home/<username>/* .': Done
    [+] Receiving all data: Done (0B)
    [*] Closed SSH channel with 2019shell1.picoctf.com
    [*] win address: 0x8048696
    [+] Starting remote process b'/problems/pointy_4_3b3533bd4e08119669feda53e8cb0502/vuln' on 2019shell1.picoctf.com: pid 1203280
    [+] picoCTF{g1v1ng_d1R3Ct10n5_c7465fbf}
   ```

### Flag

`picoCTF{g1v1ng_d1R3Ct10n5_c7465fbf}`
