You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
HMDM/README.md

197 lines
8.0 KiB

<div align="center">
<div>
<img src="https://githacks.org/uploads/-/system/project/avatar/300/1615640-200.png"/>
</div>
</div>
# HMDM - Highly Modular Driver Mapper
HMDM is a driver mapper which uses any method to allocate kernel memory and any method to copy kernel memory to map unsigned code into the windows kernel. This project is based off of [physmeme](https://githacks.org/_xeroxz/physmeme) and is what I intended on creating originally, but was unable to. This repo contains two examples of HMDM, one with [VDM](https://githacks.org/_xeroxz/vdm) (Vulnerable Driver Manipulation of drivers exposing arbitrary physical memory read and write), and the other example using [MSREXEC](https://githacks.org/_xeroxz/msrexec) which uses any driver that can write to arbitrary MSR's to elevate to kernel execution. Besides [VDM](https://githacks.org/_xeroxz/vdm) and [MSREXEC](https://githacks.org/_xeroxz/msrexec), one could use any other method of executable kernel memory allocation and arbitrary kernel writes to interface with `drv::hmdm_ctx`.
***WARNING:*** Neither demos (VDM or MSREXEC) will work under HVCI systems. Both demos require you to run as admin in order to load the vulnerable driver.
##### Related Work
* [VDM](https://githacks.org/_xeroxz/vdm) - Vulnerable Driver Manipulation
* [MSREXEC](https://githacks.org/_xeroxz/msrexec) - Elevate Arbitrary MSR Writes To Kernel Execution
* [physmeme](https://githacks.org/_xeroxz/physmeme) - systematic exploitation of physical read/write to map unsigned code into the kernel.
* [PSKDM](https://githacks.org/_xeroxz/PSKDM) - Process-Context Specific Kernel Driver Mapper
* [kdmapper](https://github.com/z175/kdmapper) - KDMapper is a simple tool that exploits iqvw64e.sys Intel driver to manually map non-signed drivers in memory
* [drvmap](https://github.com/not-wlan/drvmap) - Driver Mapper which uses capcom.sys
* [gdrv-loader](https://github.com/alxbrn/gdrv-loader) - Driver Loader which disables DSE using gdrv.sys
* [TDL](https://github.com/hfiref0x/TDL) - Turla Driver Loader
### Driver Requirements
Driver must be compiled with /GS- and control flow guard disabled. These settings are located in C/C++ --> Code Generation ---> Security Check/Control Flow Guard. The driver
you compile must have a custom driver entry. This means that you need to change the entry point of the module in linker settings. You can find the setting at Linker --> Advanced --> Entry Point.
Please make sure that your entry point uses the same function type that HMDM uses. If the function type is changed, please ensure that the changes are also applied to HMDM.
```cpp
// NOTE: this driver has a custom entry point (drv_entry), if you make a new project
// please change the driver entry in linker settings... You will also need to disable
// CFG in c++ --> code generations, along with GS...
auto drv_entry(uintptr_t drv_base) -> NTSTATUS
{
DbgPrint("> drv base -> 0x%p\n", drv_base);
return STATUS_SUCCESS;
}
```
### Getting Started
***
In order to create a `drv::hmdm_ctx`, one must first declare two lambdas. One lambda for allocating executable kernel memory, and another lambda for arbitrary kernel writes. Programmers can use any vulnerabilities to facilitate these requirements. Once both lambdas are defined one can create a `drv::hmdm_ctx`. Simply pass in both lambdas at the same time with a `static initializer`.
```cpp
drv::hmdm_ctx drv_mapper({ _kalloc, _kmemcpy });
// read driver off disk to be mapped...
drv::drv_buffer_t drv_buffer;
utils::open_binary_file(argv[1], drv_buffer);
// map driver into the kernel...
const auto [drv_base, drv_entry] = drv_mapper.map_module(drv_buffer);
```
***NOTE:*** `drv::hmdm_ctx` does not call the drivers entry. You must do this yourself using whatever method. This is easily done with [VDM](https://githacks.org/_xeroxz/vdm) and [MSREXEC](https://githacks.org/_xeroxz/msrexec).
```cpp
// calls driver entry point with MSREXEC...
// you can change the entry point params to fit your needs...
NTSTATUS result;
msrexec.exec([&result, drv_entry = drv_entry, drv_base = drv_base]
(void* krnl_base, get_system_routine_t get_kroutine) -> void
{
using drv_entry_t = NTSTATUS(*)(std::uintptr_t);
result = reinterpret_cast<drv_entry_t>(drv_entry)(drv_base);
});
```
```cpp
// calls driver entry point with VDM...
// you can change the entry point params to fit your needs...
const auto entry_result =
vdm.syscall<NTSTATUS(*)(std::uintptr_t)>(
reinterpret_cast<void*>(drv_entry), drv_base);
```
#### VDM Example
***
##### drv::kalloc_t - VDM Example
```cpp
vdm::vdm_ctx vdm(_read_phys, _write_phys);
drv::kalloc_t _kalloc = [&](std::size_t size) -> void*
{
using ex_alloc_pool_t =
void* (*)(std::uint32_t, std::uint32_t);
static const auto ex_alloc_pool =
reinterpret_cast<void*>(
utils::kmodule::get_export(
"ntoskrnl.exe", "ExAllocatePool"));
return vdm.syscall<ex_alloc_pool_t>(ex_alloc_pool, NULL, size);
};
```
##### drv::kmemcpy_t - VDM Example
***NOTE:*** The memcpy being called in this example is exported from ntoskrnl.exe and not in usermode.
```cpp
drv::kmemcpy_t _kmemcpy =
[&](void* dest, const void* src, std::size_t size) -> void*
{
static const auto kmemcpy =
reinterpret_cast<void*>(
utils::kmodule::get_export(
"ntoskrnl.exe", "memcpy"));
return vdm.syscall<decltype(&memcpy)>(kmemcpy, dest, src, size);
};
```
#### MSREXEC Example
***
##### drv::kalloc_t - MSREXEC Example
***NOTE***: When using MSREXEC be aware that `vdm::msrexec_ctx::exec` returns void. This requires a programmer to make a nested lambda in order to obtain a result.
```cpp
vdm::msrexec_ctx msrexec(_write_msr);
drv::kalloc_t _kalloc = [&](std::size_t size) -> void*
{
void* alloc_base;
msrexec.exec([&](void* krnl_base, get_system_routine_t get_kroutine) -> void
{
using ex_alloc_pool_t =
void* (*)(std::uint32_t, std::size_t);
const auto ex_alloc_pool =
reinterpret_cast<ex_alloc_pool_t>(
get_kroutine(krnl_base, "ExAllocatePool"));
alloc_base = ex_alloc_pool(NULL, size);
});
return alloc_base;
};
```
##### drv::kmemcpy_t - MSREXEC Example
***NOTE***: When using MSREXEC be aware that `vdm::msrexec_ctx::exec` returns void. This requires a programmer to make a nested lambda in order to obtain a result.
```cpp
drv::kmemcpy_t _kmemcpy =
[&](void* dest, const void* src, std::size_t size) -> void*
{
void* result = nullptr;
msrexec.exec([&](void* krnl_base, get_system_routine_t get_kroutine) -> void
{
const auto kmemcpy =
reinterpret_cast<decltype(&memcpy)>(
get_kroutine(krnl_base, "memcpy"));
result = kmemcpy(dest, src, size);
});
return result;
};
```
# BSD 3-Clause License
Copyright (c) 2021, _xeroxz
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.