1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-01-02 11:36:22 +01:00

More of the cross compilation dance!

This commit is contained in:
OJ 2020-05-22 14:09:59 +10:00
parent e7162dda2c
commit 936fa267b4
No known key found for this signature in database
GPG Key ID: 10D3B9A154E6DF61
2 changed files with 96 additions and 66 deletions

View File

@ -74,73 +74,86 @@ extern "C" {
#include "winpmem_meterpreter.h"
int WinPmem_meterpreter::extract_file_(__int64 resource_id, TCHAR *filename)
int WinPmem_meterpreter::extract_file_(__int64 resource_id, TCHAR* filename)
{
int result = -1;
HANDLE out_fd = INVALID_HANDLE_VALUE;
// Locate the driver resource in the .EXE file.
HRSRC hRes = FindResource(hAppInstance, MAKEINTRESOURCE(resource_id), L"FILE");
if (hRes == NULL) {
dprintf("[WINPMEM] Could not locate driver resource.");
goto error;
do
{
if (hRes == NULL)
{
dprintf("[WINPMEM] Could not locate driver resource.");
break;
}
HGLOBAL hResLoad = LoadResource(hAppInstance, hRes);
if (hResLoad == NULL)
{
dprintf("[WINPMEM] Could not load driver resource.");
break;
}
VOID* lpResLock = LockResource(hResLoad);
if (lpResLock == NULL)
{
dprintf("[WINPMEM] Could not lock driver resource.");
break;
}
DWORD size = SizeofResource(hAppInstance, hRes);
// Now open the filename and write the driver image on it.
HANDLE out_fd = CreateFile(filename, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (out_fd == INVALID_HANDLE_VALUE)
{
dprintf("[WINPMEM] Can not create temporary file.");
break;
};
if (!WriteFile(out_fd, lpResLock, size, &size, NULL))
{
dprintf("[WINPMEM] Can not write to temporary file.");
break;
}
result = 0;
} while (0);
if (out_fd != NULL && out_fd != INVALID_HANDLE_VALUE)
{
CloseHandle(out_fd);
}
HGLOBAL hResLoad = LoadResource(hAppInstance, hRes);
if (hResLoad == NULL) {
dprintf("[WINPMEM] Could not load driver resource.");
goto error;
}
VOID *lpResLock = LockResource(hResLoad);
if (lpResLock == NULL) {
dprintf("[WINPMEM] Could not lock driver resource.");
goto error;
}
DWORD size = SizeofResource(hAppInstance, hRes);
// Now open the filename and write the driver image on it.
HANDLE out_fd = CreateFile(filename, GENERIC_WRITE, 0, NULL,
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (out_fd == INVALID_HANDLE_VALUE) {
dprintf("[WINPMEM] Can not create temporary file.");
goto error_resource;
};
if (!WriteFile(out_fd, lpResLock, size, &size, NULL)) {
dprintf("[WINPMEM] Can not write to temporary file.");
goto error_file;
}
CloseHandle(out_fd);
return 1;
error_file:
CloseHandle(out_fd);
error_resource:
error :
return -1;
return result;
};
HANDLE WinPmem_meterpreter::get_fd() {
HANDLE WinPmem_meterpreter::get_fd()
{
return fd_;
}
uint64_t WinPmem_meterpreter::get_max_physical_memory() {
uint64_t WinPmem_meterpreter::get_max_physical_memory()
{
return max_physical_memory_;
}
int WinPmem_meterpreter64::extract_driver() {
int WinPmem_meterpreter64::extract_driver()
{
// 64 bit drivers use PTE acquisition by default.
default_mode_ = PMEM_MODE_PTE;
if (!driver_filename_) {
if (!driver_filename_)
{
TCHAR path[MAX_PATH + 1];
TCHAR filename[MAX_PATH + 1];
// Gets the temp path env string (no guarantee it's a valid path).
if (!GetTempPath(MAX_PATH, path)) {
if (!GetTempPath(MAX_PATH, path))
{
dprintf("[WINPMEM] Unable to determine temporary path.");
return -1;
}
@ -156,16 +169,19 @@ int WinPmem_meterpreter64::extract_driver() {
return extract_file_(WINPMEM_64BIT_DRIVER, driver_filename_);
}
int WinPmem_meterpreter32::extract_driver() {
int WinPmem_meterpreter32::extract_driver()
{
// 32 bit acquisition defaults to physical device.
default_mode_ = PMEM_MODE_PHYSICAL;
if (!driver_filename_) {
if (!driver_filename_)
{
TCHAR path[MAX_PATH + 1];
TCHAR filename[MAX_PATH + 1];
// Gets the temp path env string (no guarantee it's a valid path).
if (!GetTempPath(MAX_PATH, path)) {
if (!GetTempPath(MAX_PATH, path))
{
dprintf("[WINPMEM] Unable to determine temporary path.");
return -1;
}
@ -186,7 +202,8 @@ WinPmem_meterpreter *WinPmemFactory()
SYSTEM_INFO sys_info = {0};
GetNativeSystemInfo(&sys_info);
switch (sys_info.wProcessorArchitecture) {
switch (sys_info.wProcessorArchitecture)
{
case PROCESSOR_ARCHITECTURE_AMD64:
return new WinPmem_meterpreter64();
@ -214,7 +231,8 @@ DWORD dump_ram(Remote *remote, Packet *packet)
BOOL acquire_pagefile = FALSE;
status = pmem_handle->install_driver();
if (status > 0) {
if (status > 0)
{
pmem_handle->set_acquisition_mode(mode);
result = WINPMEM_ERROR_SUCCESS;
}
@ -231,7 +249,8 @@ DWORD dump_ram(Remote *remote, Packet *packet)
// Get the memory ranges.
if (!DeviceIoControl(pmem_handle->get_fd(), PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
sizeof(info), &size, NULL)) {
sizeof(info), &size, NULL))
{
dprintf("[WINPMEM] Failed to get memory geometry");
result = WINPMEM_ERROR_FAILED_MEMORY_GEOMETRY;
goto end;
@ -244,7 +263,8 @@ DWORD dump_ram(Remote *remote, Packet *packet)
WinpmemContext *ctx;
// Allocate storage for the Winpmem context
if (!(ctx = (WinpmemContext*)calloc(1, sizeof(WinpmemContext)))) {
if (!(ctx = (WinpmemContext*)calloc(1, sizeof(WinpmemContext))))
{
dprintf("[WINPMEM] Failed to allocate memory");
result = WINPMEM_ERROR_FAILED_ALLOCATE_MEMORY;
goto end;
@ -300,29 +320,34 @@ static int winpmem_meterpreter_copy_memory(uint64_t start, uint64_t end,
{
LARGE_INTEGER large_start;
if (start >= ctx->winpmem->get_max_physical_memory()) {
if (start >= ctx->winpmem->get_max_physical_memory())
{
return 0;
};
// Clamp the region to the top of physical memory.
if (end > ctx->winpmem->get_max_physical_memory()) {
if (end > ctx->winpmem->get_max_physical_memory())
{
end = ctx->winpmem->get_max_physical_memory();
};
while (start < end) {
while (start < end)
{
DWORD to_write = (DWORD)min(bufferSize - *bytesRead, end - start);
DWORD bytes_read = 0;
large_start.QuadPart = start;
if (0xFFFFFFFF == SetFilePointerEx(
ctx->winpmem->get_fd(), large_start, NULL, FILE_BEGIN)) {
ctx->winpmem->get_fd(), large_start, NULL, FILE_BEGIN))
{
dprintf("[WINPMEM] Failed to seek in the pmem device.");
return 0;
};
if (!ReadFile(ctx->winpmem->get_fd(), reinterpret_cast<char*>(buffer)+*bytesRead, to_write, &bytes_read, NULL) ||
bytes_read != to_write) {
bytes_read != to_write)
{
dprintf("[WINPMEM] Failed to Read memory.");
return 0;
};
@ -334,18 +359,20 @@ static int winpmem_meterpreter_copy_memory(uint64_t start, uint64_t end,
return 1;
};
static DWORD winpmem_channel_read(Channel *channel, Packet *request,
static DWORD winpmem_channel_read(Channel* channel, Packet* request,
LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesRead)
{
WinpmemContext *ctx = (WinpmemContext *)context;
WinpmemContext* ctx = (WinpmemContext*)context;
uint64_t offset = ctx->offset;
*bytesRead = 0;
if (ctx->index >= ctx->pmem_info.NumberOfRuns.QuadPart) {
if (ctx->index >= ctx->pmem_info.NumberOfRuns.QuadPart)
{
dprintf("[WINPMEM] Memory end reached.");
return ERROR_SUCCESS;
}
if (ctx->pmem_info.Run[ctx->index].start > ctx->offset) {
if (ctx->pmem_info.Run[ctx->index].start > ctx->offset)
{
uint64_t padding_size = ctx->pmem_info.Run[ctx->index].start - ctx->offset;
DWORD padding_size_max = (DWORD)min(padding_size, bufferSize);
ZeroMemory(buffer, padding_size_max);
@ -353,18 +380,21 @@ static DWORD winpmem_channel_read(Channel *channel, Packet *request,
offset += *bytesRead;
}
if (bufferSize - *bytesRead > 0) {
if (bufferSize - *bytesRead > 0)
{
uint64_t end = min(ctx->pmem_info.Run[ctx->index].length, bufferSize - *bytesRead);
end += offset;
DWORD status = winpmem_meterpreter_copy_memory(offset, end, ctx, buffer, bufferSize, bytesRead);
if (status == 0) {
if (status == 0)
{
dprintf("[WINPMEM] Failed in winpmem_meterpreter_copy_memory.");
}
}
ctx->offset += *bytesRead;
if (ctx->offset >= ctx->pmem_info.Run[ctx->index].start + ctx->pmem_info.Run[ctx->index].length) {
if (ctx->offset >= ctx->pmem_info.Run[ctx->index].start + ctx->pmem_info.Run[ctx->index].length)
{
ctx->index++;
}
return ERROR_SUCCESS;