Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PLATINUMPICK

VERSION

  • v1.0

BRIEF

Project PLATINUMPICK is a C++20 framework for building Windows x64 kernel-mode shellcode.

It derives from project SILVERPICK and, as such, leverages:

  1. Visual Studio Code as the code editor
  2. MinGW-w64 as the compiler toolchain
  3. GNU Make as the build system

Please note that this project is using MSYS2.

USAGE

While writing PIC in C/C++ using the PLATINUMPICK framework, you have to take into consideration the following rules:

  1. Treat the payload function as the (pseudo) entry point.

  2. All string literals must be declared as stack strings.

    a. You may use the STACK_STRING(Name, String) macro for this purpose.

  3. Global variables may not be used anywhere in the code.

  4. Native API functions 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 via IDT scandown.

    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 manual PE parsing.

  5. The payload function must be called at IRQL 0 or PASSIVE_LEVEL to ensure payload safety.

    a. You may use work items or passive-level DPCs for 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;
}

BUILDING

code .
Ctrl+` OR Ctrl+Shift+B
make clean
make pic

TESTING

You 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.

kscldr-plpi

TESTED OS VERSIONS

  • Windows 11 25H2 Build 26200 Revision 8655 64-bit

MITIGATIONS

  1. 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.

  2. If that is not an option, use WDAC to block known bad drivers that enable dynamic kernel-mode code execution (e.g., the Capcom driver). Ideally, you should use an allowlist consisting of known good drivers.

REFERENCES

  1. IDT Scandown
  2. kernel-shellcode.cpp
  3. DynamicKernelShellcode
  4. ksc4cpp
  5. KernelRuntimeImport
  6. kli
  7. scfw
  8. Meltdown Reloaded: Breaking Windows KASLR by Leaking KVA Shadow Mappings
  9. GuestAgent.c
  10. multi_arch_kernel_queue_apc.asm
  11. eternalblue_kshellcode_x64.asm
  12. Windows-Kernel-Shellcode
  13. Remote Windows Kernel Exploitation: Step Into the Ring 0
  14. Finding the Base of the Windows Kernel
  15. TransitionalPeriod: Multi Ring Kernel To UserMode Payload

About

Windows Kernel-Mode Shellcode Development Framework (WKMSDF)

Resources

Stars

70 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages