Skip to content

fzxcp3/GhostMapperUM

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 

Repository files navigation

GhostMapperUM

manual map your unsigned driver over signed memory

inspired by the initial research and PoC (https://github.com/Oliver-1-1/GhostMapper) made by @Oliver-1-1 :)

since the original PoC intended to mainly demonstrate the concept , Oliver chose to use a driver to map another unsigned driver GhostMapperUM intends to provide a more realistic / "ready to use" version of GhostMapper , implementing it entirely from usermode

generally speaking , we do that by exploiting the iqvw64e.sys vulnerable intel driver (thanks to kdmapper's utilities - https://github.com/TheCruZ/kdmapper)

Usage

set the path to your target driver in 'config.h' and compile

just run GhostMapperUM.exe

note your driver should not touch the DriverObject / RegistryPath entry args as we pass them as null when calling the DriverEntry

dump drivers tl;dr

You should read the detailed readme description in the original GhostMapper repo , in short :

when a crash happens , crash related data needs to be saved to disk. drivers responsible to save data to disk on a crash are cloned with the prefix of 'dump_'

the idea behind this is that on a crash the system is is considered to be in an unknwon state , a driver responsible to save data to disk might be the one that caused the crash... to solve that , the kernel asks the clones to step in and write the data instead

that's why - by design , after initialization dump drivers are kept in a suspended state and are not in use (to minimize the chance they will be corrupted by the time of a crash)

this gives us the opportuinty to leverage the signed memory range held by those 'ghost' drivers and map our own driver over it : )

the mapping procedure

  • read the specefied driver in 'config.h' from disk , that is the unsigned driver to map
  • Find the base address of a ghost driver (we target dump_stronvme.sys)
  • apply relocations to our local target driver image & fix imports
  • mark the entire ghost driver range as rwx by directly manipulating ptes through iqvw64e.sys's read/write primitive (saving the original ptes in a vector)
  • read the original ghost driver image
  • write our target driver over the ghost driver using a standard write primitive (no need for write to readonly...)
  • to avoid rwx pages we unset the 'rw' bit from executable sections pages ptes , and set the 'nx' bit for others
  • finally , we call the entry point of the mapped driver by patching ZwAddAtom to jump to it , and calling NtAddAtom to trigger the syscall
  • when your driver is done (sync this somehow...) call the RestoreOriginalDriver function to restore the original ghost driver image and ptes like we never patched it (currently , it is being called after returning from DriverEntry since the example driver we map does nothing afterwards, oviously change that according to your needs )
  • cleaning of traces taken from kdmapper

trivial detection vectors and things to consider

  • whilst the mapped driver is active , the ghost driver's text section on disk differs from the one in memory
  • whilst the mapped driver is active , section's memory protections differ between disk and memory
  • saying that , the image path of dump drivers is not a valid path on disk , some anti cheats (and perhaps AVs) tend to skip them during integrity checks, some arent , check it for your specific use-case

About

manual map unsigned driver over signed memory

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 99.8%
  • C 0.2%