1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

609 lines
15 KiB
C
Raw Normal View History

#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
{
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
dprintf( "[CHANNEL] Opening new channel for packet %p", packet );
// If the channel open request had a specific channel type
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
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);
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
dprintf( "[CHANNEL] Opening %s %u", channelType, flags );
// Allocate a response
response = packet_create_response(packet);
// Did the response allocation fail?
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
if ((!response) || (!(newChannel = channel_create(0, flags))))
{
res = ERROR_NOT_ENOUGH_MEMORY;
break;
}
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
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);
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
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
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
dprintf( "[CHANNEL] Sending response for %s", channelType );
2017-07-06 15:40:32 +10:00
res = packet_transmit(remote, response, NULL);
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
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;
2016-05-03 12:09:46 +10:00
dprintf("[CHANNEL] unable to find channel of id %d", channelId);
break;
}
// Destroy the channel
2016-05-03 12:09:46 +10:00
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
* -----------------
*/
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
DWORD remote_request_core_shutdown( Remote *remote, Packet *packet, DWORD* pResult )
{
Channel *channel = NULL;
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
Packet *response = packet_create_response( packet );
DWORD result = ERROR_SUCCESS;
// Acknowledge the shutdown request
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
packet_add_tlv_bool( response, TLV_TYPE_BOOL, TRUE );
// Transmit the response
dprintf("[DISPATCH] Ack shutdown request");
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
packet_transmit_response( result, remote, response );
Command refactor for clean shutdown + inline calls This work contains a bunch of changes around command dispatching. The goals for this bit of work were to: * Provide the ability for commands to be executed on the same thread as the server rather than always creating new threads and executing them on those threads. * Have the means for _special_ commands, such as `exit` and `migrate` to shut down the server cleanly without having to rely on signalling across threads or by doing brutal thread termination via shared global handles. This should not only fix the dirty shutdown problem on Windows which leaves tasks dangling (or based on the prior attempt at fixing, crashing stuff as well), it should also help clean up the shutdown process in POSIX. These changes hit a very important part of Meterpreter and so should be reviewed with intense scrutnity. I expect this PR to garner a log of critique and most likely a number of changes before being included in the main line. The `PacketDispatcher` was modified to include a new function pointer called an `inline_handler`. This new member indicates that there's a handler which should be invoked inline. While this sits alongside the existing `handler`, they are actually mutually exclusive. If an `inline_handler` is specified then the `handler` is ignored and it is assumed that the command is intended to be handled inline. The signature of the inline handler is different to the standard handler, and this is why a new function pointer was added rather than a simple flag. Addition of this parameter meant that the basic command structure changed, and that obviously affects all of the extensions and their respective commands. This changeset therefore updates each of those command declarations so that they use the new macros that hide this detail. Other things to be mindful of: * This version of the code reads the command's `method` prior to invoking any other function, and after that the command itself is passed around to the threaded or non-threaded routes for invocation. An extra thread parameter was included as as result, and an overload for the `thread_create` function was added which supported this new parameter. This was named `thread_create3` because `thread_create_with_another_paramter` sounded a bit crap. * The migration code, which originally had a `thread_kill` and an event wait once the new meterpreter session had been created, has been modified to not do any waiting at all. Instead it finishes execution as fast as possible and returns control to the server which should respond by shutting down in a clean way. * Originally the code always attempted to call a command handler in the base command list and then, if found, would also call an "overload" in the extension commands list. From the investigation that I did, it appears that the overloaded methods did nothing in the base (they'd early out during invocation). As a result, the new way of doing things acts like a 'true' overload in that the extension commands are searched first, and if one is found this is the command that is executed. Any base commands with the same method name will not get executed. In the case where there is no extension command found, the base command list is then queried. If a command is found that command is instead invoked. * The POSIX version still compiles cleanly, but I've never been able to build a version that runs on my machines. I'm not sure if there's a trick to getting POSIX builds to run, and if there is I don't know it. Whoever scrutinises this build should make sure that the POSIX version that they build can still run and (hopefully) exit cleanly. I've added lots of documentation, but there's always room for improvement. Hopefully this will fix the `*_tcp` side of Redmine 8438. Bring on the feedback!
2013-10-17 12:34:55 +10:00
*pResult = result;
dprintf("[DISPATCH] Telling dispatch loop to finish");
// We always return FALSE here to tell the server to terminate.
return FALSE;
}