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:
parent
e7162dda2c
commit
936fa267b4
Binary file not shown.
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user