### Baby KernelThis was a simple kernel exploitation challenge. We were given a kernel andinitrd. Booting it, a menu appeared that allowed calling an arbitrary kernelfunction (from ring 0) with a single argument. (For that, it loaded a customkernel 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 bootmenu. (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 rightcommand to pack a new initrd: `find . | cpio -o -c > ../sh_initrd.cpio`) Withthis root shell, it was quickly clear that we were supposed to escalateprivileges 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 wouldrandomize the kernel addresses. (I checked this by attaching with GDB to theqemu 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 itcould 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). Aftera bit of trial and error, I ended up calling the function `commit_creds` (whichchanges the credentials of the current process to those specified in a `structcred *` it receives as only param). As a parameter, I gave it a reference to theglobal 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 python3import sysfrom time import sleep
init_creds = 0xffffffff81a3c4e0commit_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()```