We're going to create a really basic authentication module that allows you to read the flag if you input the correct password. Here is the relevant code:
If we attempt to read()
from the device, it checks the authenticated
flag to see if it can return us the flag. If not, it sends back FAIL: Not Authenticated!
.
In order to update authenticated
, we have to write()
to the kernel module. What we attempt to write it compared to p4ssw0rd
. If it's not equal, nothing happens. If it is, authenticated
is updated and the next time we read()
it'll return the flag!
Let's first try and interact with the kernel by reading from it.
Make sure you sudo chmod 666 /dev/authentication
!
We'll start by opening the device and reading from it.
Note that in the module source code, the length of read()
is completely disregarded, so we could make it any number at all! Try switching it to 1
and you'll see.
After compiling, we get that we are not authenticated:
Epic! Let's write the correct password to the device then try again. It's really important to send the null byte here! That's because copy_from_user()
does not automatically add it, so the strcmp
will fail otherwise!
It works!
Amazing! Now for something really important:
The state is preserved between connections! Because the kernel module remains on, you will be authenticated until the module is reloaded (either via rmmod
then insmod
, or a system restart).
So, here's your challenge! Write the same kernel module, but using ioctl
instead. Then write a program to interact with it and perform the same operations. ZIP file including both below, but no cheating! This is really good practise.