This challenge was a nice pwning task against a kernel module. Clearly, the final goal is to exploit it to become root. The first step is to recognize that a device /dev/supershm is present and that comes from the supershm.ko module. In the home directory of the user there is a bash script that interacts with the module, basically it allows us to create a new memory area with a certain label, assign/update a value to it and read its content.
After getting the module I started reversing it and I found some interesting things:
The memory areas are in the data section of the kernel module (called bin)
We can add up to 32 areas
The bin array is 320 words long (i.e.: 1280 bytes)
Each entry of the array is composed as follows:
1 word: address of the stored data
1 word: set to 0 when this entry is not used, 1 (or something else) otherwise.
32 bytes: name of the entry
We can overflow the name: this allows to create fake entries with the address we want! The only restriction is that we cannot put nullbytes in there as strcpy() is used.
If we have a fake entry we can read from abritrary addresses and write whatever we’d like in there (except from nullbytes). This little Python script generates commands to read from any address.
So my plan was as to overwrite one entry of the syscall table with a custom function that calls commit_creds and _prepare_kernel_cred_ (luckily /proc/kallsyms was available so we knew the addresses of those things).
Here is my final exploit, the only tricky part was to get it compiled and transferred to the machine. I used dietlibc, statically cross-compiled the exploit for ARM and copied it to the machine using base64 encoding/decoding.