Introduction to the rootkit development

A rootkit is an application with high privileges that is able to manipulate the execution of other processes, intercept network traffic or a keystroke, conceal itself or etc. Some of the rootkit features are inherent capabilities of drivers. Thus we write a driver in this article and then add other functionalities of rootkits in the next articles. The basics of writing a driver, compiling it, loading and unloading rootkit and starting or stopping the rootkit may not be discussed in future articles.

A driver normally is developed using c++ language but its code structure is different than a normal c++ program. In a normal c++ application the start point of the application is the Main function while the start point in a driver (and rootkit) is the DriverEntry function. Also a driver is compiled with Driver Development Kit not just a c compiler. Moreover the execution of a driver is different than a normal .exe application. A driver needs to be loaded by Service Control Manager although here we write a piece of code to load the driver automatically. Also to kill or stop the driver (or rootkit) a piece of code is written which is the unloader. Unloading the driver will call the OnUnload function of the driver (or rootkit).

To compile the source codes you see in this and future articles you need a C compiler and Microsoft Software Development Kit which both are integrated in Visual Studio. You can download the Express version for free. At the time of writing this article Visual Studio 2013 is stable and I use that version. In addition you need the Windows Driver Development kit for your platform. Use windows XP sp3 (2011 edition) to run the compiled code. I personally installed that version on a VmWare and compile and run the codes on a VM.

Talking is enough, let’s delve into the codes. Here is a simple driver code that just prints some debug statement (to see the debug statements use Debug View):

#ifndef _GHOST_H_

#define _GHOST_H_

 

typedef BOOLEAN BOOL;

typedef unsigned long DWORD;

typedef DWORD * PDWORD;

typedef unsigned long ULONG;

typedef unsigned short WORD;

typedef unsigned char BYTE;

 

typedef struct _DRIVER_DATA

{

   LIST_ENTRY listEntry;

   DWORD  unknown1;

   DWORD  unknown2;

   DWORD  unknown3;

   DWORD  unknown4;

   DWORD  unknown5;

   DWORD  unknown6;

   DWORD  unknown7;

   UNICODE_STRING path;

   UNICODE_STRING name;

} DRIVER_DATA;

 

#endif

#include "ntddk.h"

 

// Global version data

ULONG majorVersion;

ULONG minorVersion;

 

// Comment out in free build to avoid detection

VOID OnUnload( IN PDRIVER_OBJECT pDriverObject )

{

                DbgPrint("comint32: OnUnload called.");

}

 

NTSTATUS DriverEntry( IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING theRegistryPath )

{

                DRIVER_DATA* driverData;

 

                // Get the operating system version

                PsGetVersion( &majorVersion, &minorVersion, NULL, NULL );

 

                // Major = 4: Windows NT 4.0, Windows Me, Windows 98 or Windows 95

                // Major = 5: Windows Server 2003, Windows XP or Windows 2000

                // Minor = 0: Windows 2000, Windows NT 4.0 or Windows 95

                // Minor = 1: Windows XP

                // Minor = 2: Windows Server 2003

 

                if ( majorVersion == 5 && minorVersion == 2 )

                {

                                DbgPrint("comint32: Running on Windows 2003");

                }

                else if ( majorVersion == 5 && minorVersion == 1 )

                {

                                DbgPrint("comint32: Running on Windows XP");

                }

                else if ( majorVersion == 5 && minorVersion == 0 )

                {

                                DbgPrint("comint32: Running on Windows 2000");

                }

                else if ( majorVersion == 4 && minorVersion == 0 )

                {

                                DbgPrint("comint32: Running on Windows NT 4.0");

                }

                else

                {

                                DbgPrint("comint32: Running on unknown system");

                }

 

                // Allow the driver to be unloaded

                pDriverObject->DriverUnload = OnUnload;

 

                return STATUS_SUCCESS;

}

 

To compile the code you need a SOURCES and MAKEFILE. TARGETNAME is the name of output driver file. The contents of these files should be:

// SOURCES

TARGETNAME=comint32

TARGETPATH=OBJ

TARGETTYPE=DRIVER

SOURCES=Rootkit.c\

// MAKEFILE

!INCLUDE $(NTMAKEENV)\makefile.def

 

To compile this code open the checked DDK, navigate to the directory containing the source code (using cd command) and enter the build command.

Here is the code to load the driver:

// This program will load c:\comint32.sys

//SCMLoader.c

#include <windows.h>

#include <stdio.h>

#include <process.h>

 

 

void main( int argc, char *argv[ ] )

{

                SC_HANDLE sh1;

                SC_HANDLE sh2;

               

                sh1 = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

                if ( !sh1 )

                {

                                printf( "OpenSCManager Failed!\n" );

                                return;

                }

                sh2 = CreateService(      sh1,

                                                                                                                "MyDeviceDriver",

                                                                                                                "MyDeviceDriver",

                                                                                                                SERVICE_ALL_ACCESS,

                                                                                                                SERVICE_KERNEL_DRIVER,

                                                                                                                SERVICE_DEMAND_START,

                                                                                                                SERVICE_ERROR_NORMAL,

                                                                                                                "c:\\comint32.sys",

                                                                                                                NULL,

                                                                                                                NULL,

                                                                                                                NULL,

                                                                                                                NULL,

                                                                                                                NULL );

                if ( !sh2 )

                {

                                if ( GetLastError() == ERROR_SERVICE_EXISTS )

                                                printf("DeviceDriver already loaded!\n");

                                else

                                                printf("CreateService Failed!\n");

                }

                else

                {

                                printf("\nDriver loaded!\n");

                }

}

 

Remember that after compiling the driver you need to copy the comint32 file to the C:\ destination because the SCMLoader.exe (previous compiled file) looks in C:\ for the driver (or rootkit). To compile the SCMLoader use visual studio (installed on your target environment).

For a real rootkit(Malware) the OnUnload function of the driver and an unloader is not needed but here for training purposes you need an unloader:

// This program will unload c:\comint32.sys

//SCMUnloader.c

 

#include <windows.h>

#include <stdio.h>

#include <process.h>

 

 

void main( int argc, char *argv[ ] )

{

                SC_HANDLE sh1;

                SC_HANDLE sh2;

                SERVICE_STATUS ss;

               

                sh1 = OpenSCManager( NULL, NULL, SC_MANAGER_ALL_ACCESS );

                if ( !sh1 )

                {

                                printf( "OpenSCManager Failed!\n" );

                                return;

                }

                sh2 = OpenService(         sh1,

                                                                                                "MyDeviceDriver",

                                                                                                SERVICE_ALL_ACCESS );

                if ( !sh2 )

                {

                                                printf("OpenService Failed!\n");

                                                CloseServiceHandle( sh1 );

                                                exit(1);

                }

                ControlService( sh2, SERVICE_CONTROL_STOP, &ss );

                if ( !DeleteService( sh2 ) )

                                printf("Could not unload MyDeviceDriver!\n");

                else

                                printf("Unloaded MyDeviceDriver.\n");

                CloseServiceHandle( sh2 );

                CloseServiceHandle( sh1 );

}

 

To load the driver (rootkit) just click the SCMLoader.exe and then to start the rootkit open command prompt and run:

net start MyDeviceDriver

To Unload the rootkit run:

net stop MyDeviceDriver

and then click the SCMUnloader.exe.

Read 1312 times Last modified on Tuesday, 02 June 2015 06:22
Rate this item
5
(1 Vote)
About Author
Leave a comment

Make sure you enter the (*) required information where indicated. HTML code is not allowed.

Advanced Programming Concepts
News Letter

Subscribe our Email News Letter to get Instant Update at anytime