Lately I have been doing a lot of Rootkit related research. While conducting this research, I spent a bit of time targeting the kmem system on BSD. The most direct way to read and write to running kernel memory on BSD is via libkvm. This library is provided to ease the burden of reading and writing kernel memory in places where it is legitimate. However this allows us, as potentially nefarious individuals, to abuse kernel memory to modify the operating system in ways of our choosing. Joseph Kong wrote about this exact technique in the book Designing BSD Rootkits and in Phrack Magazine issue 63 article 0x07. Actually, this code is based on his articles with only a slight tweak to make it a bit more "fun".
swapper.c:
/*
* Takes four arguments: Name of syscall one and corresponding number
* followed by the name of syscall two followed by its number.
*
* Code then uses libkvm to swap the two syscalls
*
* Example: ./swapper mkdir 136 rmdir 137
*
* Derived from Phrack63-0x07 by Jason Kong
* Based off of Stephanie Wehner's checkcall.c,v 1.1.1.1
*
Swapper locates the sysenter call and from there is able to determine the memory location for the syscall numbers you pass on the command line. These sysent structures contain the pointers to the syscall code itself. Then, using kvm_write, the code swaps the pointers within the sysent structures. Be careful which syscalls you swap or you will blow your system completely out of the water. A good and fun example is mkdir 136 and rmdir 137 (FreeBSD7.0).
Update 11/3/08: I had to convert this over to Solaris for something specific. The differences included a slightly modified #include list as well as a different offset passed into the kvm_write. This was due to the sysent structures being slightly different between BSD and Solaris.


