# Vi deteriorated
A classic C++-based exploitation chal, with a mild twist of C++ exceptions.
## Bugs
1. Horizontal & vertical offsets at Vim structure not updated during string replace command   - OOB access at Vim structure vector of strings & strings inside it, but all accesses are done with `.at()`   - Triggers C++ exception, where handler dumps backtrace & restarts binary   - Binary & libc base leak1. Improper use of iterators and `std::vector::insert()` for multi-line replacements at `Vim::replace()`   - Return value of `std::vector::insert()` not used => huge red flag   - Iterator may fetch a malformed std::string located at `.end()` of vector inside Vim structure     - UAF possible, but fetching malformed std::string at `.end()` already sufficient for exploitation
## Exploitation
1. Trigger C++ exception to leak libc base2. Allocate chunks of size 0x210, write `&__free_hook - 3` at last 8 bytes   - This will later be fetched as `char *pChar` of fake `std::string`   - Easily done by `Vim::doCommand()` where input gets split up and processed, leaving several (about 3) chunks freed into tcache   - ex) `'%s/' + 'A'*0x200 + addr + '/' + '/g\n'`3. Trigger C++ exception to get a new vector inside Vim structure, allocated at our previously freed 0x210-size chunks4. Run `Vim::doCommand()` to fetch our fake std::string, replace it with `"sh;" + p64(&system)` and trigger free() to get shell   - These are all done in a single replace command   - std::string fetch succeeds since its structure is shaped as following:     ```     8 bytes | 8 bytes     pChar   | size     // pChar = &__free_hook - 3, size = (size | flag) of next malloc chunk > 0x10     ??????? | ???????     ```   - `str_replace()` inside `Vim::replace()` writes `__free_hook = system`   - Replaced string pointing to `"sh;" + p64(&system)` is soon freed, triggering `system("sh;" + p64(&system))`
## Exploit Code
See [solver.py](https://github.com/leesh3288/CTF/blob/master/2020/TWCTF_2020/vid/solver.py)