1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-01-02 11:36:22 +01:00

Fix up URI switching for stageless

This prevents horrible crashes when migrating from a stageless HTTP/S session.
This commit is contained in:
OJ 2015-06-27 21:19:04 +10:00
parent 701d30197e
commit c2f141679e
3 changed files with 50 additions and 18 deletions

View File

@ -68,6 +68,7 @@ typedef struct _HttpTransportContext
CSTRTYPE url; ///! Pointer to the URL stored with the transport.
STRTYPE ua; ///! User agent string.
STRTYPE uri; ///! UUID encoded as a URI.
STRTYPE new_uri; ///! New URI for stageless URI switches
STRTYPE proxy; ///! Proxy details.
STRTYPE proxy_user; ///! Proxy username.
STRTYPE proxy_pass; ///! Proxy password.

View File

@ -67,18 +67,13 @@ BOOL request_core_patch_url(Remote* remote, Packet* packet, DWORD* result)
{
// This shouldn't happen.
*result = ERROR_INVALID_STATE;
return TRUE;
}
HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
SAFE_FREE(ctx->uri);
// yes, we are reusing the URL in this case
ctx->uri = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL);
dprintf("[DISPATCH] Recieved hot-patcheched URL for stageless: %S", ctx->uri);
*result = ERROR_SUCCESS;
else
{
HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
ctx->new_uri = packet_get_tlv_value_wstring(packet, TLV_TYPE_TRANS_URL);
*result = ERROR_SUCCESS;
}
return TRUE;
}
#endif

View File

@ -644,6 +644,7 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread)
DWORD ecount = 0;
DWORD delay = 0;
Transport* transport = remote->transport;
HttpTransportContext* ctx = (HttpTransportContext*)transport->ctx;
while (running)
{
@ -697,18 +698,53 @@ static DWORD server_dispatch_http(Remote* remote, THREAD* dispatchThread)
dprintf("[DISPATCH] no pending packets, sleeping for %dms...", min(10000, delay));
Sleep(min(10000, delay));
continue;
}
else
{
transport->comms_last_packet = current_unix_timestamp();
transport->comms_last_packet = current_unix_timestamp();
// Reset the empty count when we receive a packet
ecount = 0;
// Reset the empty count when we receive a packet
ecount = 0;
dprintf("[DISPATCH] Returned result: %d", result);
dprintf("[DISPATCH] Returned result: %d", result);
running = command_handle(remote, packet);
dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop"));
running = command_handle(remote, packet);
dprintf("[DISPATCH] command_process result: %s", (running ? "continue" : "stop"));
if (ctx->new_uri != NULL)
{
dprintf("[DISPATCH] Recieved hot-patched URL for stageless: %S", ctx->new_uri);
dprintf("[DISPATCH] Old URI is: %S", ctx->uri);
dprintf("[DISPATCH] Old URL is: %S", transport->url);
// if the new URI needs more space, let's realloc space for the new URL now
int diff = wcslen(ctx->new_uri) - wcslen(ctx->uri);
if (diff > 0)
{
dprintf("[DISPATCH] New URI is bigger by %d", diff);
transport->url = (wchar_t*)realloc(transport->url, (wcslen(transport->url) + diff + 1) * sizeof(wchar_t));
}
// we also need to patch the new URI into the original transport URL, not just the currently
// active URI for comms. If we don't, then migration behaves badly.
// Start by locating the start of the URI in the current URL, by finding the third slash
wchar_t* csr = transport->url + wcslen(transport->url) - 2;
while (*csr != L'/')
{
--csr;
}
dprintf("[DISPATCH] Pointer is at: %p -> %S", csr, csr);
// patch in the new URI
wcscpy_s(csr, wcslen(diff > 0 ? ctx->new_uri : ctx->uri) + 1, ctx->new_uri);
dprintf("[DISPATCH] New URL is: %S", transport->url);
// clean up
SAFE_FREE(ctx->uri);
ctx->uri = ctx->new_uri;
ctx->new_uri = NULL;
}
}
}
return result;