This was an entirely self-directed project, where we could choose any security-based topic we liked and work on that for the whole term as a major project. We had to do our best to document our work consistently and methodically throughtout the term, and show what we learnt even if unable to finish everything we hoped to. The idea was to push yourself and learn something new.
I decided to write a kernel-level rootkit in C for the FreeBSD operating system. I wanted to do this because of its inherent difficulty and challenge, and because I had never worked on something even remotely similar to this before. See here for my initial proposal.
Below is the write-up I did at the end of the project, summarising the entire process, notes I took, difficulties I had and reflections I made.
I designed a Rootkit for the FreeBSD system, whose purpose was to sit invisibly when loaded into the kernel and hide a fake “virus” file. This was a super technically challenging project, but I enjoyed it immensely and I’m really proud to show off what I did.
Firstly, I wrote up comprehensive notes for everything I did, plus a little extra (syscall) so I was comfortable working with the system. This made sure that a) if I had any troubles, I could have an easy set of notes to refer to, b) proved that I did research, and c) gave me something to show for my effort even if I couldn’t complete a section. See: KLD Notes | Syscall Notes | Function Hooking Notes | DKOM Kernel Hiding Notes | HIDS Notes.
- Sometimes I did research beyond what my project called for. However, this extra research actually made future sections much easier to understand - see note near end of this post, for example: FH Reflections 1
What I’m most proud of are my write-ups that I wrote as I worked through each deliverable. Originally, I would just do a weekly reflection on my progress. However, as the coding got more technically complex, these ended up becoming highly detailed documentation of what I did to turn the knowledge I had from my notes into an actual working piece of software. This included bugs and issues I ran into, how I solved them, etc. If you have to choose any to read with more care, please choose the one marked with a (*) below. (Be warned, it’s like 13 pages - I had a lot that I tried and failed on in that section. :
- Week 3 Reflection | Week 4 Reflection | Week 5 General Reflection | Week 5 Syscall Reflections | Function Hooking Reflections 1 | Function Hooking Reflections 2(*) | DKOM Hiding Reflections | HIDS Hiding Reflections
The HIDS Hiding section was the only deliverable I couldn’t fully complete, but I was nonetheless very proud of it. I acknowledged that I did not have the time to finish it and still made an effort to write up what I would have done (See HIDS Hiding reflections above).
As I discuss in Function Hooking Reflection 2, I spent a huge amount of time trying to hook the system call responsible for displaying the file system before realising there was a section discussing File Hiding in the Designing Rootkits for FreeBSD book. What this means is that there is a lot of work I did here which did not end up being applied to the final product, but which I think reflects a couple of things:
-
An engineering mindset in my willingness to try things knowing that they may not work - see all the effort I put into things like stat() and mkdir, even though it didn’t come to anything. This also showed an ability to accept when a solution likely wouldn’t work and move on to something else, regardless of how much time I’d already spent on that first solution.
-
Good analytical process - working through an issue methodically, narrowing down problems and trying different approaches until I found one which works. In particular, my debugging approach in the "Weird Bug" section. This one was particularly interesting, because the bug existed in the code the FreeBSD book gave me, so there was no other help I could use.
I’m also particularly proud of the general improvement in knowledge I can show. I think this is already clear in part through the detail I put in my write ups, but for a particular example:
- In the first write-up, I had the following question: how is moduledata name different to DECLARE_MODULE name when you load a user-written module into kernel (see the Week 3 Reflection here).
- Thanks to my research over the term, I now know. Basically, the name variable in struct moduledata is a string that gets loaded into the linker_file data, as I learnt from my DKOM Hiding Reflections (see my strcmp in the linker_file FOREACH loop code). The other name argument - the one in DECLARE_MODULE - isn’t actually a variable at all - it’s a C Precompiler thing, where anything with ##name in their code will get replaced with the name I type (see the DECLARE SYSCALL macro here.
For all my deliverables, I said I would write comprehensive notes, as well as weekly write ups. As linked above, I think I have shown more than sufficient evidence for this. Here’s the marking criteria I set (see here).
As for each point:
Pass: Definitely completed (here).
Credit: Definitely completed (here | here).
Distinction: Definitely completed (here).
HD: Got half-completion. I managed to hide it from most of the HIDS, but it still picked up that I had made some modification to the /sbin folder (with my dummy virus file), it just didn’t know what I’d modified. I reflected on this and still summarised what I would have done if I had time to solve this problem. (Here).
I think the first thing that is really evident is that throughout the term, I got much better at documenting my own progress, both the successes and failures. This also includes being detailed about the process and my reasons for doing things. I think this is a good skill to have developed for when I have to work in corporate teams, etc. At the very least, communication skills are improved.
I also discussed this a bit in the 2nd function hooking write-up, but I think I’ve improved a lot in terms of just being willing to try something, with no guarantee that something will come from it. I think this is a really important thing for my professional life, and it’s definitely something I was a lot worse at before this assignment. I’m sure I’ll have plenty of times in the future where there is little help available for a particular problem, and I need to figure something out for myself through a process of trial-and-error. Knowing that failure is an inherent part of this process is a real help to me.
Finally, I just want to reflect on how happy I am with this project. I know I’ve said it a lot, but it was a super challenging task and it really pushed me. But you know what? I’d do it all again. I think part of the reason it was so good was because it was so difficult. I’ve never worked in OS before, and so I learnt a heap with it (as I think the sheet amount of reflection write ups I have show).
Thanks for coming on the journey with me.