# \*CTF 2019 - oob-v8

{% hint style="info" %}
Most of what is written from here is courtesy of [Faith](https://twitter.com/farazsth98) and their [fantastic writeup for this challenge](https://faraz.faith/2019-12-13-starctf-oob-v8-indepth/). Please go check them out!
{% endhint %}

Ok so first off, we're gonna need an old VM. Why? It's an old challenge with an old version of v8. Back then, the v8 version compilation steps required the `python` command to point at `python2` instead of `python3` like on my ParrotOS VM, and there is the odd number of other steps. Long story short, there is a *very* real possibility for needing to jerry-rig a bunch of stuff, and I don't want to break a VM I actually use. Whoops.

So, we're gonna use a [Ubuntu 18.04 VM](https://releases.ubuntu.com/18.04/). You can get the ISO file directly from [here](https://releases.ubuntu.com/18.04/ubuntu-18.04.6-desktop-amd64.iso) (amd64 version), and then set up a VM in VMware Workstation or your preferred virtualisation program.

Now we want to set up the system we're actually attacking. Instead of building v8 itself, we're going to build d8, the REPL (*read–eval–print loop*) for v8. It's essentially the command-line of v8, meaning we can compile less.

First off, install useful stuff.

```bash
$ sudo apt update
$ sudo apt install git vim
```

Now let's grab the `depot_tools`, which is needed for building v8, then add it to our `PATH`:

```bash
$ git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
$ echo "export PATH=/tools/depot_tools:$PATH" >> ~/.bashrc
```

Restart terminal for `PATH` to update. Then in folder of choice (I am in `~/Desktop/oob-v8`), we fetch v8 and install all the dependencies needed to build it:

<pre class="language-bash"><code class="lang-bash">$ fetch v8
$ cd v8
<strong>v8$ ./build/install-build-deps.sh
</strong></code></pre>

The next step is to `checkout` the commit that the challenge is based on, then sync the local files to that:

```bash
v8$ git checkout 6dc88c191f5ecc5389dc26efa3ca0907faef3598
v8$ gclient sync
```

Now we want to apply the `diff` file we get given. The challenge archive can be found [here](https://github.com/Changochen/CTF/raw/master/2019/*ctf/Chrome.tar.gz), and we'll extract it. The `oob.diff` file defines the changes made to the source code since the commit we checked out, which includes the vulnerability.

```bash
$ 7z x Chrome.tar.gz
$ tar -xvf Chrome.tar
$ cp Chrome/oob.diff .
```

Now let's apply it then prepare and build the release version:

```bash
v8$ git apply ../oob.diff
v8$ ./tools/dev/v8gen.py x64.release
v8$ ninja -C ./out.gn/x64.release
```

But there is small problem when it gets run:

```python
Traceback (most recent call last):
  File "/tools/depot_tools/ninja.py", line 14, in <module>
    import gclient_paths
  File "/tools/depot_tools/gclient_paths.py", line 24, in <module>
    def FindGclientRoot(from_dir, filename='.gclient'):
  File "/usr/lib/python3.6/functools.py", line 477, in lru_cache
    raise TypeError('Expected maxsize to be an integer or None')
TypeError: Expected maxsize to be an integer or None
```

According to [this GitHub issue](https://github.com/NVIDIA/DeepLearningExamples/issues/1016) in NVIDIA, this is because in python 3.8+ `lru_cache` has gotten a `user_function` argument. We can try and update to python3.8, but the fear is that it will break something. Oh well! Let's try anyway.

```bash
$ sudo apt install python3.8
```

Now we have Python 3.8 installed in `/usr/bin/python3.8`, we can try and overwrite the symlink `/usr/bin/python3` to point here instead of the default 3.6.9 version that came with the ISO.

```bash
$ sudo ln -sf /usr/bin/python3.8 /usr/bin/python3
```

Now we hope and pray that rerunning the `ninja` command breaks nothing:

```
$ ninja --version
depot_tools/ninja.py: Could not find Ninja in the third_party of the current project, nor in your PATH.
Please take one of the following actions to install Ninja:
- If your project has DEPS, add a CIPD Ninja dependency to DEPS.
- Otherwise, add Ninja to your PATH *after* depot_tools.
```

Ok, no `ninja`.  Let's follow [this StackOverflow post](https://stackoverflow.com/questions/75695463/chromium-checkout-build-could-not-find-ninja) and install it:

```bash
$ sudo apt install ninja-build
```

Then run it again:

<pre class="language-bash"><code class="lang-bash"><strong>v8$ ninja -C ./out.gn/x64.release
</strong></code></pre>

And it starts working! The output `release` version is found in `v8/out.gn/x64.release/d8`. Now let's build debug.

```bash
v8$ ./tools/dev/v8gen.py x64.debug
v8$ ninja -C ./out.gn/x64.debug
```

And it's done. Epic!

I'm going to revert default Python to version 3.6 to minimise the possibility of something breaking.

```bash
$ sudo ln -sf /usr/bin/python3.6 /usr/bin/python3
```

I'm also going to install [`gef`](https://github.com/hugsy/gef), the GDB extension. `gef` is actively maintained, and also actually supports Ubuntu 18.04 (which `pwndbg` [does not officially](https://github.com/pwndbg/pwndbg/releases/tag/2023.07.17), although that's due to requiring Python 3.8+ which we have technically set up in a roundabout way - use at your own risk!).

```bash
$ bash -c "$(curl -fsSL https://gef.blah.cat/sh)"
```

Now we can move on to the challenge itself.
