Genesys 0.1
Last time
I made a brief incursion in
rootkit
universe making a little modification to the
FU rootkit.
This time instead of modifying a publicly available rootkit, I'll cover a step that most rootkits that include a kernel component usually have: a kernel mode driver. Building a kernel driver skeleton (like the one we will cover here) doesn't require any dark-foo-ninja-skill but certainly makes for an interesting experience.
The code I'll display here is almost completely taken from Bill Blunden's masterpiece
The Rootkit Arsenal.
In a nutshell, today I'll show how to build a mock driver that simply performs a hello-world-like test operation, which will server as launch platform for kernel mode ramblings in the future. In a sudden enlightenment attack I thought I'd name my little baby
Genesys
(Note the play
Genesis
and the
.sys
driver file extension). It's divided in two components: a user-mode .exe and a kernel-mode .sys driver. Since similar code and concepts can be found all over the internet, I won't delve into great details for each component.
The user-mode component is a command-line tool that interacts with the kernel mode component. If given the argument "op" it calls the driver object with the proper IOCTL to perform a test operation that populates a couple of buffers and dumps them into the prompt. Beside that, most of the code in the source files takes care of proper argument/parameter checking and error checking.
The kernel-mode component creates a device name named
msnetdiag
that can be reached through user space using
CreateFile()
for example. The driver only sets the
Unload()
function to perform it's shutdown process and also sets the different dispatch functions for each requests. At this point where only interested in handling IRP_MJ_DEVICE_CONTROL type functions, therefore we will set a IOCTL dispatch routine for this kind of requests and a default dispatch routine that simply terminates the request,
defaultDispatch(),
for the rest.
I successfully performed tests in Windows XP and Windows 7 VM's. Interesting bit in this matter is that in Windows releases prior to Vista, kernel code developers could make use of the
DbgPrint()
function to trace execution in kernel lands. Since Windows Vista however,
DbgPrint()
flows to
DbgPrintEx(),
which allows for the filtering of certain debug messages as stated in
msdn.
Gracefully, I came across a post that explained the matter and offered a solution to the matter
here.
Also, another interesting point where I had issues was when calling
CreateFile()
to open a HANDLE to the device driver the name chosen kept failing until I noticed that the first argument to this API call was asking for a LPCWSTR which is a pointer to a WCHAR array or in common language, a UNICODE string.
The building process is quite trivial for the user mode component. Simply open the Visual C++ project contained inside the
/genesys
folder and build it inside the IDE (
Visual
C++ 2008 Express Edition here). The kernel mode component build process isn't complicated either although isn't all that trivial at a first glance. All we need is to place a file named SOURCES in the same folder as the source file and define in it the files we want to build. To perform the build process I used WDK's (Windows Driver Kit) last version which at the time of this writing is 7.0.0. Open the desired version of the command prompt from within WDK and go to the
/sys
folder where invoking "bld" should to the rest.
Source code:
Genesys 0.1