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)