Inspiration
I wanted to be able to make a hidden locking mechanism for my computer so i could leave my laptop in public unlocked and have others confused how it does not work.
What it does
Keyvan provides silent authentication checks and access control verdicts for resources (currently executing program, and later network actions and much more). The goal is to allow a machine to appear unlocked to an unauthorized user while restricting their access in order to confuse them.
The two authentication mechanism currently Implemented are:
- execve pathname as password:
User will be authenticated when attempt to execute a file (doesn't even need to exist), and de-authenticated when the file is attempted to be executed again. - USB device serial as password:
User will be authenticated when a USB device with matching serial is inserted, and de-authenticated when the device is removed.
How we built it
I was going to make a Capture the Flag that needed the players to reverse engineer the program, only to realize that the password is the filename. then it hit me "how about syscalls as password?!" it was indeed an interesting idea, and I couldn't stand interesting ideas being kept in my head, so I started coding. After implementing the base program, I realized that I can look at kernel function calls as password! The idea of keyvan kept expanding as I developed it. You can see the final vision of the developed keyvan here.
We have two types of bpf programs we load into the kernel
- Verdicts:
check if the user is authenticated, if so, allow the current procedure - Authenticate checkers:
check if the conditions to authenticate the user is met, if so, change the flag which verdicts will refer to when making decisions.
Challenges we ran into
- Automated build system:
cmake doesn't support building bpf programs by default, or at least I didn't find the appropriate command to. I needed to make the build sequence inside cmake by manually building them using add_custom_commands()'s and add_custom_target()'s. - Using nested map types:
I just couldn't find a beginner friendly document to teach me how to use nested map types via libbpf.
What we learned
- To find the appropriate functions to attach bpf programs to, i needed to monitor the kernel using bpftrace and dive into the source code for the drivers in interest.
- using vmlinux.h for anything other than small project seems to be a mistake, specially when you need to share some headers between bpf and userspace side.
What's next for Keyvan
- Keyvan's own config parser
- Work along PAM (Pluggable Authentication Module)
- Expose an API for other programs
- Kernel module to hide keyvan's presence if requested by the user
- Keyvan's background service to provide logging and observability over unauthorized attempts
- (Hopefully) Implement crypto for both user and bpf side to securely store credentials on disk
Built With
- bpftool
- c
- cmake
- libbpf

Log in or sign up for Devpost to join the conversation.