mirror of
https://github.com/rapid7/metasploit-framework
synced 2024-11-12 11:52:01 +01:00
Cleanups to the socket code, its still not perfect, but much more usable now
git-svn-id: file:///home/svn/framework3/trunk@7750 4d416f70-5f16-0410-b530-b9f4589650da
This commit is contained in:
parent
0961ce3523
commit
792724c3f3
@ -1,5 +1,5 @@
|
||||
#include "common.h"
|
||||
|
||||
|
||||
extern THREAD serverThread;
|
||||
/*
|
||||
* core_migrate
|
||||
@ -254,5 +254,5 @@ DWORD remote_request_core_migrate(Remote *remote, Packet *packet)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -21,7 +21,7 @@ extern DWORD remote_response_core_console_write(Remote *remote, Packet *packet);
|
||||
|
||||
extern DWORD remote_response_core_channel_open(Remote *remote, Packet *packet);
|
||||
extern DWORD remote_response_core_channel_close(Remote *remote, Packet *packet);
|
||||
|
||||
|
||||
DWORD remote_request_core_console_write(Remote *remote, Packet *packet)
|
||||
{
|
||||
return ERROR_SUCCESS;
|
||||
@ -32,7 +32,7 @@ DWORD remote_response_core_console_write(Remote *remote, Packet *packet)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Base RPC dispatch table
|
||||
|
@ -391,6 +391,9 @@ DWORD _channel_packet_completion_routine(Remote *remote, Packet *packet,
|
||||
Channel *channel = channel_find_by_id(channelId);
|
||||
DWORD res = ERROR_NOT_FOUND;
|
||||
|
||||
|
||||
dprintf( "[CHANNEL] _channel_packet_completion_routine. channel=0x%08X method=%s", channel, method );
|
||||
|
||||
// If the channel was not found and it isn't an open request, return failure
|
||||
if (!channel && strcmp(method, "core_channel_open"))
|
||||
return ERROR_NOT_FOUND;
|
||||
@ -665,6 +668,8 @@ DWORD channel_close(Channel *channel, Remote *remote, Tlv *addend,
|
||||
realRequestCompletion = &requestCompletion;
|
||||
}
|
||||
|
||||
dprintf( "[CHANNEL] channel_close. channel=0x%08X completion=0x%.8x", channel, completionRoutine );
|
||||
|
||||
// Transmit the packet with the supplied completion routine, if any.
|
||||
res = packet_transmit(remote, request, realRequestCompletion);
|
||||
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "list.h"
|
||||
|
||||
|
||||
#ifdef DEBUGTRACE
|
||||
#define dprintf(...) real_dprintf(__VA_ARGS__)
|
||||
#else
|
||||
|
@ -86,16 +86,33 @@ static DWORD tcp_channel_client_local_notify(Remote *remote,
|
||||
FD_SET(ctx->fd, &set);
|
||||
|
||||
// Read data from the client connection
|
||||
if (((bytesRead = recv(ctx->fd, buf, sizeof(buf), 0))
|
||||
== SOCKET_ERROR) ||
|
||||
(bytesRead == 0))
|
||||
{
|
||||
channel_close(ctx->channel, ctx->remote, NULL, 0, NULL);
|
||||
bytesRead = recv(ctx->fd, buf, sizeof(buf), 0);
|
||||
|
||||
// Not sure why we get these with pending data
|
||||
if(bytesRead == SOCKET_ERROR) {
|
||||
printf( "[TCP] tcp_channel_client_local_notify. [error] channel=0x%08X read=0x%.8x (ignored)", ctx->channel, bytesRead );
|
||||
continue;
|
||||
}
|
||||
|
||||
if (bytesRead == 0) {
|
||||
dprintf( "[TCP] tcp_channel_client_local_notify. [closed] channel=0x%08X read=0x%.8x", ctx->channel, bytesRead );
|
||||
|
||||
// Set the native channel operations context to NULL
|
||||
channel_set_native_io_context(ctx->channel, NULL);
|
||||
|
||||
// Free the context
|
||||
free_tcp_client_context(ctx);
|
||||
|
||||
// Stop processing
|
||||
break;
|
||||
}
|
||||
else if (ctx->channel)
|
||||
|
||||
if (ctx->channel) {
|
||||
dprintf( "[TCP] tcp_channel_client_local_notify. [data] channel=0x%08X read=0x%.8x", ctx->channel, bytesRead );
|
||||
channel_write(ctx->channel, ctx->remote, NULL, 0, buf, bytesRead, 0);
|
||||
} else {
|
||||
dprintf( "[TCP] tcp_channel_client_local_notify. [data] channel=<invalid> read=0x%.8x", bytesRead );
|
||||
}
|
||||
|
||||
} while (select(0, &set, NULL, NULL, &tv) > 0);
|
||||
|
||||
@ -270,17 +287,23 @@ VOID free_socket_context(SocketContext *ctx)
|
||||
dprintf( "[TCP] free_socket_context. ctx=0x%08X", ctx );
|
||||
|
||||
// Close the socket and notification handle
|
||||
if (ctx->fd)
|
||||
if (ctx->fd){
|
||||
closesocket(ctx->fd);
|
||||
ctx->fd = NULL;
|
||||
}
|
||||
if (ctx->notify)
|
||||
{
|
||||
scheduler_remove_waitable(ctx->notify);
|
||||
|
||||
WSACloseEvent(ctx->notify);
|
||||
// XXX: Leaving this triggers an invalid handle in another thread?
|
||||
// WSACloseEvent(ctx->notify);
|
||||
ctx->notify = NULL;
|
||||
}
|
||||
|
||||
if (ctx->channel)
|
||||
if (ctx->channel) {
|
||||
channel_close(ctx->channel, ctx->remote, NULL, 0, NULL);
|
||||
ctx->channel = NULL;
|
||||
}
|
||||
|
||||
// Free the context
|
||||
free(ctx);
|
||||
|
@ -1,6 +1,6 @@
|
||||
#include "metsrv.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
|
||||
#include <excpt.h>
|
||||
@ -9,42 +9,42 @@
|
||||
|
||||
// include the Reflectiveloader() function
|
||||
#include "../ReflectiveDLLInjection/ReflectiveLoader.c"
|
||||
|
||||
int exceptionfilter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
|
||||
{
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
#define InitAppInstance() do { \
|
||||
if( hAppInstance == NULL ) \
|
||||
hAppInstance = GetModuleHandle( NULL ); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define InitAppInstance()
|
||||
#define exceptionfilter(a, b)
|
||||
#define SetHandleInformation(a, b, c)
|
||||
#define ExitThread(x) exit((x))
|
||||
#endif
|
||||
|
||||
int exceptionfilter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
|
||||
{
|
||||
return EXCEPTION_EXECUTE_HANDLER;
|
||||
}
|
||||
|
||||
#define InitAppInstance() do { \
|
||||
if( hAppInstance == NULL ) \
|
||||
hAppInstance = GetModuleHandle( NULL ); \
|
||||
} while (0)
|
||||
|
||||
#else
|
||||
#define InitAppInstance()
|
||||
#define exceptionfilter(a, b)
|
||||
#define SetHandleInformation(a, b, c)
|
||||
#define ExitThread(x) exit((x))
|
||||
#endif
|
||||
|
||||
#define PREPEND_ERROR "### Error: "
|
||||
#define PREPEND_INFO "### Info : "
|
||||
#define PREPEND_WARN "### Warn : "
|
||||
|
||||
/*
|
||||
* This thread is the main server thread which we use to syncronize a gracefull
|
||||
* shutdown of the server during process migration.
|
||||
*/
|
||||
THREAD serverThread = {0};
|
||||
|
||||
/*
|
||||
* This thread is the main server thread which we use to syncronize a gracefull
|
||||
* shutdown of the server during process migration.
|
||||
*/
|
||||
THREAD serverThread = {0};
|
||||
|
||||
/*
|
||||
* An array of locks for use by OpenSSL.
|
||||
*/
|
||||
static LOCK ** ssl_locks = NULL;
|
||||
|
||||
/*
|
||||
* A callback function used by OpenSSL to leverage native system locks.
|
||||
*/
|
||||
static LOCK ** ssl_locks = NULL;
|
||||
|
||||
/*
|
||||
* A callback function used by OpenSSL to leverage native system locks.
|
||||
*/
|
||||
static VOID server_locking_callback( int mode, int type, const char * file, int line )
|
||||
{
|
||||
if( mode & CRYPTO_LOCK )
|
||||
@ -53,9 +53,9 @@ static VOID server_locking_callback( int mode, int type, const char * file, int
|
||||
lock_release( ssl_locks[type] );
|
||||
}
|
||||
|
||||
/*
|
||||
* A callback function used by OpenSSL to get the current threads id.
|
||||
* While not needed on windows this must be used for posix meterpreter.
|
||||
/*
|
||||
* A callback function used by OpenSSL to get the current threads id.
|
||||
* While not needed on windows this must be used for posix meterpreter.
|
||||
*/
|
||||
static DWORD server_threadid_callback( VOID )
|
||||
{
|
||||
@ -126,8 +126,8 @@ static VOID server_socket_flush( Remote * remote )
|
||||
}
|
||||
|
||||
lock_release( remote->lock );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Poll a socket for data to recv and block when none available.
|
||||
*/
|
||||
@ -153,17 +153,17 @@ static LONG server_socket_poll( Remote * remote, long timeout )
|
||||
lock_release( remote->lock );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the OpenSSL subsystem for use in a multi threaded enviroment.
|
||||
*/
|
||||
static BOOL server_initialize_ssl( Remote * remote )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
lock_acquire( remote->lock );
|
||||
|
||||
*/
|
||||
static BOOL server_initialize_ssl( Remote * remote )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
lock_acquire( remote->lock );
|
||||
|
||||
// Begin to bring up the OpenSSL subsystem...
|
||||
CRYPTO_malloc_init();
|
||||
SSL_load_error_strings();
|
||||
@ -184,25 +184,25 @@ static BOOL server_initialize_ssl( Remote * remote )
|
||||
CRYPTO_set_locking_callback( server_locking_callback );
|
||||
CRYPTO_set_dynlock_create_callback( server_dynamiclock_create );
|
||||
CRYPTO_set_dynlock_lock_callback( server_dynamiclock_lock );
|
||||
CRYPTO_set_dynlock_destroy_callback( server_dynamiclock_destroy );
|
||||
|
||||
lock_release( remote->lock );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CRYPTO_set_dynlock_destroy_callback( server_dynamiclock_destroy );
|
||||
|
||||
lock_release( remote->lock );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bring down the OpenSSL subsystem
|
||||
*/
|
||||
static BOOL server_destroy_ssl( Remote * remote )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if( remote == NULL )
|
||||
return FALSE;
|
||||
|
||||
lock_acquire( remote->lock );
|
||||
|
||||
*/
|
||||
static BOOL server_destroy_ssl( Remote * remote )
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
if( remote == NULL )
|
||||
return FALSE;
|
||||
|
||||
lock_acquire( remote->lock );
|
||||
|
||||
SSL_free( remote->ssl );
|
||||
|
||||
SSL_CTX_free( remote->ctx );
|
||||
@ -216,12 +216,12 @@ static BOOL server_destroy_ssl( Remote * remote )
|
||||
for( i=0 ; i<CRYPTO_num_locks() ; i++ )
|
||||
lock_destroy( ssl_locks[i] );
|
||||
|
||||
free( ssl_locks );
|
||||
|
||||
lock_release( remote->lock );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
free( ssl_locks );
|
||||
|
||||
lock_release( remote->lock );
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
/*
|
||||
* Negotiate SSL on the socket.
|
||||
*/
|
||||
@ -244,20 +244,20 @@ static BOOL server_negotiate_ssl(Remote *remote)
|
||||
|
||||
remote->ssl = SSL_new(remote->ctx);
|
||||
SSL_set_verify(remote->ssl, SSL_VERIFY_NONE, NULL);
|
||||
|
||||
if( SSL_set_fd(remote->ssl, remote->fd) == 0 )
|
||||
{
|
||||
dprintf("[SERVER] set fd failed");
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if( (ret = SSL_connect(remote->ssl)) != 1 )
|
||||
{
|
||||
dprintf("[SERVER] connect failed %d\n", SSL_get_error(remote->ssl, ret));
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if( SSL_set_fd(remote->ssl, remote->fd) == 0 )
|
||||
{
|
||||
dprintf("[SERVER] set fd failed");
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
if( (ret = SSL_connect(remote->ssl)) != 1 )
|
||||
{
|
||||
dprintf("[SERVER] connect failed %d\n", SSL_get_error(remote->ssl, ret));
|
||||
success = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
dprintf("[SERVER] Sending a HTTP GET request to the remote side...");
|
||||
|
||||
@ -276,8 +276,8 @@ static BOOL server_negotiate_ssl(Remote *remote)
|
||||
success = FALSE;
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* The servers main dispatch loop for incoming requests.
|
||||
*/
|
||||
@ -331,25 +331,25 @@ static DWORD server_dispatch( Remote * remote )
|
||||
dprintf( "[DISPATCH] leaving server_dispatch." );
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup and run the server. This is called from Init via the loader.
|
||||
*/
|
||||
DWORD server_setup( SOCKET fd )
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup and run the server. This is called from Init via the loader.
|
||||
*/
|
||||
DWORD server_setup( SOCKET fd )
|
||||
{
|
||||
Remote *remote = NULL;
|
||||
DWORD res = 0;
|
||||
|
||||
#ifdef _UNIX
|
||||
int local_error = 0;
|
||||
#endif
|
||||
|
||||
DWORD res = 0;
|
||||
|
||||
#ifdef _UNIX
|
||||
int local_error = 0;
|
||||
#endif
|
||||
|
||||
// if hAppInstance is still == NULL it means that we havent been
|
||||
// reflectivly loaded so we must patch in the hAppInstance value
|
||||
// for use with loading server extensions later.
|
||||
InitAppInstance();
|
||||
|
||||
InitAppInstance();
|
||||
|
||||
srand( (unsigned int)time(NULL) );
|
||||
|
||||
__try
|
||||
@ -411,7 +411,7 @@ DWORD server_setup( SOCKET fd )
|
||||
|
||||
thread_kill( &serverThread );
|
||||
}
|
||||
|
||||
dprintf("[SERVER] Finished.");
|
||||
|
||||
dprintf("[SERVER] Finished.");
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user