Challenge 3: Ciphered Writes¶
Suppose you want to enforce automatic data transformation at the kernel level whenever applications write data to files. Instead of trusting each application to handle encryption correctly, you decide to implement a mechanism that transparently modifies data inside the kernel before it reaches the filesystem.
In this challenge, you will develop an eBPF program that intercepts write operations and applies a simple encryption scheme to the data being written.
Description¶
Processes normally write plain text data to files using system calls
such as write(). Your objective is to intercept these write
operations and automatically transform the data before it is committed
to disk.
Specifically, the eBPF program must apply a Caesar cipher to the data being written.
A Caesar cipher shifts each alphabetical character in the text by a fixed number of positions in the alphabet. For example, with a shift of 3, the letter ‘A’ would be transformed to ‘D’, ‘B’ to ‘E’, and so on. The cipher should wrap around the alphabet, so ‘Z’ would become ‘C’. Both uppercase and lowercase letters should be transformed accordingly. Non-alphabetical characters (such as digits, punctuation, and whitespace) should be left unchanged.
Your program should transparently modify the data buffer passed to the
write() system call so that the file ultimately contains the
ciphered version of the original text.
Setup¶
Download this challenge’s template using:
$ wget --no-check-certificate https://people.montefiore.uliege.be/~gain/courses/info0940/asset/ciphered.tar.gz
$ tar -xzvf ciphered.tar.gz
The program that will be used for testing is located in echo_test.
This will simply write the string “Hello123” to a file named
output.txt. You can compile it using the Makefile provided (simply
run make within the echo_test directory). Then you can run it
using:
$ ./echo_test
After running the echo_test program, the content of output.txt
should be “Hello123” if your eBPF program is not loaded.
Inside ciphered/src, you will find the same template as in tutorial
3. Use it to implement the eBPF program that applies the Caesar cipher
to the data being written to files.
What you need to do¶
Your task is to develop an eBPF program that applies a Caesar cipher to data
written via the write() system call. However, the cipher should only be
active when two conditions are met: the process issuing the write is named
“echo_test”, and it is writing to a file rather than the standard output or
standard error.
Important
Not filtering the process that you want to target (“echo_test”) could lead to unintended consequences on the system.
You must only consider alphabetic characters: both uppercase (A-Z) and
lowercase (a-z). Other characters (such as digits, punctuation, etc.)
should be left unchanged.
The shift value for the Caesar cipher should be configurable when loading the eBPF program. The argument is the following:
--shift: The number of positions to shift each letter in the alphabet. Default should be 3.
The shift value should be modulo 26, meaning that a shift of 29 would be equivalent to a shift of 3.
This is what it will look like when you run the “echo_test” program with your eBPF program loaded:
# By default the shift value is 3, so the output should be:
$ ./echo_test
echo_test successfully wrote to output.txt
$ cat output.txt
Khoor123
# If the shift value of 10 was used when loading the eBPF program, the output should be:
$ ./echo_test
echo_test successfully wrote to output.txt
$ cat output.txt
Rovvy123
Tip
To add an argument
--shiftto the user-space program, you will have to modify the user-space code. You can usegetopt_longto parse user-space arguments. You will also have to use new eBPF notions in this tutorial, which you learned in tutorial 4.You won’t be able to read from and write to user-space memory from your eBPF program without using helper functions [1]. However, in the arguments passed to the
write(), there is a pointer to the user-space buffer that contains the data to be written (“Hello123” in this example).When writing a loop, remember that a verification engine will check your eBPF program before it is loaded. (See tutorial 3)