From 73f7b20935cc738702317079cb6bd7a9d4bd2e3d Mon Sep 17 00:00:00 2001 From: Stephen Fewer Date: Thu, 19 Aug 2010 11:34:23 +0000 Subject: [PATCH] Add meterpreter server side support for cleaning up loaded extensions upon server termination by calling the loaded extensions DeinisServerExtension() functions. git-svn-id: file:///home/svn/framework3/trunk@10053 4d416f70-5f16-0410-b530-b9f4589650da --- .../source/meterpreter/source/server/metsrv.h | 6 +++ .../source/server/remote_dispatch.h | 2 +- .../source/server/remote_dispatch_common.c | 33 ++++++++---- .../meterpreter/source/server/server_setup.c | 2 +- .../source/server/win/remote_dispatch.c | 51 +++++++++++++------ 5 files changed, 67 insertions(+), 27 deletions(-) diff --git a/external/source/meterpreter/source/server/metsrv.h b/external/source/meterpreter/source/server/metsrv.h index 4f0b38c74c..8ad13a7d1d 100644 --- a/external/source/meterpreter/source/server/metsrv.h +++ b/external/source/meterpreter/source/server/metsrv.h @@ -27,5 +27,11 @@ DWORD server_setup(SOCKET fd); +typedef struct _EXTENSION +{ + HMODULE library; + DWORD (*init)(Remote *remote); + DWORD (*deinit)(Remote *remote); +} EXTENSION; #endif diff --git a/external/source/meterpreter/source/server/remote_dispatch.h b/external/source/meterpreter/source/server/remote_dispatch.h index ef1522553c..798f7a8d1e 100644 --- a/external/source/meterpreter/source/server/remote_dispatch.h +++ b/external/source/meterpreter/source/server/remote_dispatch.h @@ -23,6 +23,6 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet); VOID register_dispatch_routines(); -VOID deregister_dispatch_routines(); +VOID deregister_dispatch_routines( Remote * remote ); #endif diff --git a/external/source/meterpreter/source/server/remote_dispatch_common.c b/external/source/meterpreter/source/server/remote_dispatch_common.c index d2d4f71d8e..da8a8034a0 100644 --- a/external/source/meterpreter/source/server/remote_dispatch_common.c +++ b/external/source/meterpreter/source/server/remote_dispatch_common.c @@ -9,6 +9,8 @@ extern HINSTANCE hAppInstance; * Core dispatch routines * **************************/ +LIST * extension_list = NULL; + // Dispatch table Command custom_commands[] = { @@ -32,21 +34,32 @@ VOID register_dispatch_routines() { DWORD index; - for (index = 0; - custom_commands[index].method; - index++) - command_register(&custom_commands[index]); + extension_list = list_create(); + + for( index=0 ; custom_commands[index].method ; index++ ) + command_register( &custom_commands[index] ); } /* - * Deregisters previously registered custom commands + * Deregisters previously registered custom commands and loaded extensions. */ -VOID deregister_dispatch_routines() +VOID deregister_dispatch_routines( Remote * remote ) { DWORD index; - for (index = 0; - custom_commands[index].method; - index++) - command_deregister(&custom_commands[index]); + while( TRUE ) + { + EXTENSION * extension = list_pop( extension_list ); + if( !extension ) + break; + + extension->deinit( remote ); + + free( extension ); + } + + for( index=0 ; custom_commands[index].method ; index++ ) + command_deregister( &custom_commands[index] ); + + list_destroy( extension_list ); } diff --git a/external/source/meterpreter/source/server/server_setup.c b/external/source/meterpreter/source/server/server_setup.c index 87b818b5db..439e52adbf 100644 --- a/external/source/meterpreter/source/server/server_setup.c +++ b/external/source/meterpreter/source/server/server_setup.c @@ -470,7 +470,7 @@ DWORD server_setup( SOCKET fd ) server_dispatch( remote ); dprintf("[SERVER] Deregistering dispatch routines..."); - deregister_dispatch_routines(); + deregister_dispatch_routines( remote ); } while (0); diff --git a/external/source/meterpreter/source/server/win/remote_dispatch.c b/external/source/meterpreter/source/server/win/remote_dispatch.c index 547fba85ef..e61c8a4c3e 100644 --- a/external/source/meterpreter/source/server/win/remote_dispatch.c +++ b/external/source/meterpreter/source/server/win/remote_dispatch.c @@ -3,6 +3,9 @@ // see ReflectiveLoader.c... extern HINSTANCE hAppInstance; +// see remote_dispatch_common.c +extern LIST * extension_list; + DWORD request_core_loadlib(Remote *remote, Packet *packet) { Packet *response = packet_create_response(packet); @@ -86,24 +89,42 @@ DWORD request_core_loadlib(Remote *remote, Packet *packet) // call its Init routine if ((flags & LOAD_LIBRARY_FLAG_EXTENSION) && (library)) { - DWORD (*init)(Remote *remote); + EXTENSION * exension = (EXTENSION *)malloc( sizeof(EXTENSION) ); + if( exension ) + { + exension->library = library; - // if the library was loaded via its reflective loader we must use GetProcAddressR() - if( bLibLoadedReflectivly ) - (LPVOID)init = (LPVOID)GetProcAddressR( library, "InitServerExtension" ); - else - (LPVOID)init = (LPVOID)GetProcAddress( library, "InitServerExtension" ); + // if the library was loaded via its reflective loader we must use GetProcAddressR() + if( bLibLoadedReflectivly ) + { + exension->init = (LPVOID)GetProcAddressR( exension->library, "InitServerExtension" ); + exension->deinit = (LPVOID)GetProcAddressR( exension->library, "DeinitServerExtension" ); + } + else + { + exension->init = (LPVOID)GetProcAddress( exension->library, "InitServerExtension" ); + exension->deinit = (LPVOID)GetProcAddress( exension->library, "DeinitServerExtension" ); + } - // patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading - // functions from the metsrv.dll library. We need to do it this way as LoadLibrary/GetProcAddress - // wont work if we have used Reflective DLL Injection as metsrv.dll will be 'invisible' to these functions. - remote->hMetSrv = hAppInstance; + // patch in the metsrv.dll's HMODULE handle, used by the server extensions for delay loading + // functions from the metsrv.dll library. We need to do it this way as LoadLibrary/GetProcAddress + // wont work if we have used Reflective DLL Injection as metsrv.dll will be 'invisible' to these functions. + remote->hMetSrv = hAppInstance; - dprintf("[SERVER] Calling init()..."); - // Call the init routine in the library - if( init ) - res = init(remote); - dprintf("[SERVER] Called init()..."); + // Call the init routine in the library + if( exension->init ) + { + dprintf("[SERVER] Calling init()..."); + + res = exension->init( remote ); + + if( res == ERROR_SUCCESS ) + list_push( extension_list, exension ); + else + free( exension ); + } + dprintf("[SERVER] Called init()..."); + } } } while (0);