v1.0
Project PLATINUMPICK is a C++20 framework for building Windows x64 kernel-mode shellcode.
It derives from project SILVERPICK and, as such, leverages:
Visual Studio Codeas the code editorMinGW-w64as the compiler toolchainGNU Makeas the build system
Please note that this project is using MSYS2.
While writing PIC in C/C++ using the PLATINUMPICK framework, you have to take into consideration the following rules:
-
Treat the
payloadfunction as the (pseudo) entry point. -
All string literals must be declared as stack strings.
a. You may use the
STACK_STRING(Name, String)macro for this purpose. -
Global variables may not be used anywhere in the code.
-
Native APIfunctions may be used only via run-time dynamic linking after ensuring that the function prototype is available in the corresponding header file.a. You may use the
GET_NTOSKRNL_BASE()macro to get the image base address of the kernel image viaIDTscandown.b. You may use the
INITIALIZE_FUNCTION_POINTER(Function)macro to declare and initialize an exported symbol pointer.c. You may use the
RESOLVE_FUNCTION_POINTER(ModuleBase, Function)macro to resolve said symbol's address via manualPEparsing. -
The
payloadfunction must be called atIRQL 0orPASSIVE_LEVELto ensure payload safety.a. You may use work items or passive-level
DPCsfor this purpose.
/// @brief PIC start function
/// @param None
/// @return None
EXTERN_C NO_INLINE VOID __stdcall payload(
VOID
) {
// Init local variables
PVOID pNtoskrnl = nullptr;
INITIALIZE_FUNCTION_POINTER(DbgPrint);
STACK_STRING(sstrFormat, "%ws\n");
STACK_STRING(sstrText, L"hello world from kernel-mode shellcode!");
// Get the image base address of ntoskrnl.exe
pNtoskrnl = GET_NTOSKRNL_BASE();
if (pNtoskrnl == nullptr)
goto cleanup;
// Resolve nt!DbgPrint
RESOLVE_FUNCTION_POINTER(pNtoskrnl, DbgPrint);
if (DbgPrint == nullptr)
goto cleanup;
// Print to attached debugger
DbgPrint(sstrFormat.data(), sstrText.data());
// Cleanup
cleanup:
return;
}code .
Ctrl+` OR Ctrl+Shift+B
make clean
make picYou may wish to use the FLARE kernel shellcode loader to test the generated code on a test VM created and configured using the CodeMachine System setup for kernel development and debugging guide.
Windows 11 25H2 Build 26200 Revision 8655 64-bit
-
Enable HVCI. It leverages hardware virtualization capabilities such as
Intel EPT+Intel MBEC(or its software equivalent,RUM) to provide strong code guarantees, i.e., only properly signed kernel pages can become executable. -
If that is not an option, use WDAC to block known bad drivers that enable dynamic kernel-mode code execution (e.g., the
Capcomdriver). Ideally, you should use an allowlist consisting of known good drivers.
- IDT Scandown
- kernel-shellcode.cpp
- DynamicKernelShellcode
- ksc4cpp
- KernelRuntimeImport
- kli
- scfw
- Meltdown Reloaded: Breaking Windows KASLR by Leaking KVA Shadow Mappings
- GuestAgent.c
- multi_arch_kernel_queue_apc.asm
- eternalblue_kshellcode_x64.asm
- Windows-Kernel-Shellcode
- Remote Windows Kernel Exploitation: Step Into the Ring 0
- Finding the Base of the Windows Kernel
- TransitionalPeriod: Multi Ring Kernel To UserMode Payload
