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

Begin to enable DWORD xor out of the box

This commit is contained in:
OJ 2015-12-02 13:30:22 +10:00
parent 3a7dc24a10
commit 5ca5fe89f0
11 changed files with 162 additions and 31 deletions

@ -323,6 +323,7 @@ BOOL command_process_inline(Command *baseCommand, Command *extensionCommand, Rem
// lengths are sane.
if (command_validate_arguments(command, packet) != ERROR_SUCCESS)
{
dprintf("[COMMAND] Command arguments failed to validate");
continue;
}
@ -660,7 +661,10 @@ DWORD command_validate_arguments(Command *command, Packet *packet)
{
case TLV_META_TYPE_STRING:
if (packet_is_tlv_null_terminated(&current) != ERROR_SUCCESS)
{
dprintf("[COMMAND] string is not null terminated");
res = ERROR_INVALID_PARAMETER;
}
break;
default:
break;

13
c/meterpreter/source/common/common.c Normal file → Executable file

@ -107,3 +107,16 @@ void enable_debugging()
}
#endif
VOID xor_bytes(DWORD xorKey, LPBYTE buffer, DWORD bufferSize)
{
dprintf("[OJ] Key : %x", xorKey);
dprintf("[OJ] Length : %x", bufferSize);
LPBYTE xor = (LPBYTE)&xorKey;
for (DWORD i = 0; i < bufferSize; ++i)
{
buffer[i] ^= xor[i % sizeof(DWORD)];
}
}

@ -12,7 +12,8 @@
#include <stdio.h>
#include <time.h>
#define SAFE_FREE(x) {free(x); x = NULL;}
#define SAFE_FREE(x) {free(x); x = NULL;}
#define rand_xor_key() ((((rand() % 254) + 1) << 0) | (((rand() % 254) + 1) << 8) | (((rand() % 254) + 1) << 16) | (((rand() % 254) + 1) << 24))
#ifdef _WIN32
#include <winsock2.h>
@ -232,3 +233,4 @@ static _inline void real_dprintf(char *format, ...)
#endif
int current_unix_timestamp(void);
VOID xor_bytes(DWORD xorKey, LPBYTE buffer, DWORD bufferSize);

@ -155,6 +155,7 @@ Packet *packet_create(PacketTlvType type, LPCSTR method)
{
if (!(packet = (Packet *)malloc(sizeof(Packet))))
{
dprintf("[OJ] Packet create failed to malloc");
break;
}
@ -171,6 +172,7 @@ Packet *packet_create(PacketTlvType type, LPCSTR method)
// Add the method TLV if provided
if (method && packet_add_tlv_string(packet, TLV_TYPE_METHOD, method) != ERROR_SUCCESS)
{
dprintf("[OJ] packet create failed to add string for method");
break;
}
@ -258,10 +260,12 @@ Packet *packet_create_response(Packet *request)
if (packet_get_type(request) == PACKET_TLV_TYPE_PLAIN_REQUEST)
{
dprintf("[OJ] packet is a request");
responseType = PACKET_TLV_TYPE_PLAIN_RESPONSE;
}
else
{
dprintf("[OJ] packet is a response");
responseType = PACKET_TLV_TYPE_RESPONSE;
}
@ -270,18 +274,21 @@ Packet *packet_create_response(Packet *request)
// Get the request TLV's method
if (packet_get_tlv_string(request, TLV_TYPE_METHOD, &method) != ERROR_SUCCESS)
{
dprintf("[OJ] couldn't get method");
break;
}
// Try to allocate a response packet
if (!(response = packet_create(responseType, (PCHAR)method.buffer)))
{
dprintf("[OJ] failed to create the packet");
break;
}
// Get the request TLV's request identifier
if (packet_get_tlv_string(request, TLV_TYPE_REQUEST_ID, &requestId) != ERROR_SUCCESS)
{
dprintf("[OJ] Failed to get the request ID");
break;
}

@ -194,10 +194,17 @@ typedef struct
PUCHAR buffer;
} Tlv;
typedef struct
{
DWORD xor_key;
DWORD length;
DWORD type;
} PacketHeader;
/*! @brief Packet definition. */
typedef struct _Packet
{
TlvHeader header;
PacketHeader header;
PUCHAR payload;
ULONG payloadLength;

@ -22,8 +22,8 @@ static PyObject* binding_invoke(PyObject* self, PyObject* args)
dprintf("[PYTHON] packet %p is %u bytes and is %s", packetBytes, packetLength, isLocal ? "local" : "not local");
Packet packet = { 0 };
packet.header = *(TlvHeader*)packetBytes;
packet.payload = (PUCHAR)(packetBytes + sizeof(TlvHeader));
packet.header = *(PacketHeader*)packetBytes;
packet.payload = (PUCHAR)(packetBytes + sizeof(PacketHeader));
packet.payloadLength = (ULONG)packetLength - sizeof(TlvHeader);
// If the functionality doesn't require interaction with MSF, then

@ -320,6 +320,23 @@ DWORD server_setup(MetsrvConfig* config)
srand((unsigned int)time(NULL));
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
dprintf("[OJ] Key: %x", rand_xor_key());
__try
{
do

@ -257,7 +257,9 @@ DWORD request_core_uuid(Remote* remote, Packet* packet)
DWORD request_core_machine_id(Remote* pRemote, Packet* pPacket)
{
DWORD res = ERROR_SUCCESS;
dprintf("[CORE] Running request_core_machine_id");
Packet* pResponse = packet_create_response(pPacket);
dprintf("[CORE] pResponse is %p", pResponse);
if (pResponse)
{

81
c/meterpreter/source/server/win/server_transport_tcp.c Normal file → Executable file

@ -572,7 +572,7 @@ static DWORD packet_receive_via_ssl(Remote *remote, Packet **packet)
DWORD headerBytes = 0, payloadBytesLeft = 0, res;
CryptoContext *crypto = NULL;
Packet *localPacket = NULL;
TlvHeader header;
PacketHeader header;
LONG bytesRead;
BOOL inHeader = TRUE;
PUCHAR payload = NULL;
@ -586,7 +586,8 @@ static DWORD packet_receive_via_ssl(Remote *remote, Packet **packet)
// Read the packet length
while (inHeader)
{
if ((bytesRead = SSL_read(ctx->ssl, ((PUCHAR)&header + headerBytes), sizeof(TlvHeader)-headerBytes)) <= 0)
dprintf("[OJ] trying to read header (%u so far)", headerBytes);
if ((bytesRead = SSL_read(ctx->ssl, ((PUCHAR)&header + headerBytes), sizeof(PacketHeader)-headerBytes)) <= 0)
{
if (!bytesRead)
{
@ -597,31 +598,58 @@ static DWORD packet_receive_via_ssl(Remote *remote, Packet **packet)
{
dprintf("[PACKET] receive header failed with error code %d. SSLerror=%d, WSALastError=%d\n", bytesRead, SSL_get_error(ctx->ssl, bytesRead), WSAGetLastError());
SetLastError(ERROR_NOT_FOUND);
}
}
dprintf("[OJ] failed with %u 0x%x ", GetLastError(), GetLastError());
break;
}
headerBytes += bytesRead;
if (headerBytes != sizeof(TlvHeader))
{
if (headerBytes != sizeof(PacketHeader))
{
dprintf("[OJ] need more bytes ...");
continue;
}
inHeader = FALSE;
}
if (headerBytes != sizeof(TlvHeader))
if (headerBytes != sizeof(PacketHeader))
{
break;
}
}
header.xor_key = ntohl(header.xor_key);
// xor the header data
LPBYTE csr = (LPBYTE)&header;
dprintf("[OJ] header bytes have been read");
dprintf("[OJ] Before: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", csr[0],
csr[1], csr[2], csr[3], csr[4],
csr[5], csr[6], csr[7], csr[8],
csr[9], csr[10], csr[11], csr[12]);
xor_bytes(header.xor_key, (LPBYTE)&header.length, 8);
dprintf("[OJ] After: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", csr[0],
csr[1], csr[2], csr[3], csr[4],
csr[5], csr[6], csr[7], csr[8],
csr[9], csr[10], csr[11], csr[12]);
dprintf("[OJ] xor key address: 0x%p", &header.xor_key);
dprintf("[OJ] Length address: 0x%p", &header.length);
// Initialize the header
header.length = header.length;
header.type = header.type;
payloadLength = ntohl(header.length) - sizeof(TlvHeader);
payloadBytesLeft = payloadLength;
header.length = ntohl(header.length);
// use TlvHeader size here, because the length doesn't include the xor byte
payloadLength = header.length - sizeof(TlvHeader);
payloadBytesLeft = payloadLength;
dprintf("[OJ] total length is: %u", payloadLength);
// Allocate the payload
if (!(payload = (PUCHAR)malloc(payloadLength)))
@ -663,6 +691,26 @@ static DWORD packet_receive_via_ssl(Remote *remote, Packet **packet)
{
break;
}
dprintf("[OJ] Payload start Before: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", payload[0],
payload[1], payload[2], payload[3], payload[4],
payload[5], payload[6], payload[7], payload[8],
payload[9], payload[10], payload[11], payload[12]);
dprintf("[OJ] Payload end Before: 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", payload[payloadLength - 13 + 0],
payload[payloadLength - 13 + 1], payload[payloadLength - 13 + 2], payload[payloadLength - 13 + 3], payload[payloadLength - 13 + 4],
payload[payloadLength - 13 + 5], payload[payloadLength - 13 + 6], payload[payloadLength - 13 + 7], payload[payloadLength - 12 + 8],
payload[payloadLength - 13 + 9], payload[payloadLength - 13 + 10], payload[payloadLength - 13 + 11], payload[payloadLength - 13 + 12]);
xor_bytes(header.xor_key, payload, payloadLength);
dprintf("[OJ] Payload start After : 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", payload[0],
payload[1], payload[2], payload[3], payload[4],
payload[5], payload[6], payload[7], payload[8],
payload[9], payload[10], payload[11], payload[12]);
dprintf("[OJ] Payload end After : 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x", payload[payloadLength - 13 + 0],
payload[payloadLength - 13 + 1], payload[payloadLength - 13 + 2], payload[payloadLength - 13 + 3], payload[payloadLength - 13 + 4],
payload[payloadLength - 13 + 5], payload[payloadLength - 13 + 6], payload[payloadLength - 13 + 7], payload[payloadLength - 12 + 8],
payload[payloadLength - 13 + 9], payload[payloadLength - 13 + 10], payload[payloadLength - 13 + 11], payload[payloadLength - 13 + 12]);
// Allocate a packet structure
if (!(localPacket = (Packet *)malloc(sizeof(Packet))))
@ -1065,6 +1113,15 @@ DWORD packet_transmit_via_ssl(Remote* remote, Packet* packet, PacketRequestCompl
// Update the header length
packet->header.length = htonl(packet->payloadLength + sizeof(TlvHeader));
}
dprintf("[PACKET] New xor key for sending");
packet->header.xor_key = rand_xor_key();
// before transmission, xor the whole lot, starting with the body
xor_bytes(packet->header.xor_key, (LPBYTE)packet->payload, packet->payloadLength);
// then the header
xor_bytes(packet->header.xor_key, (LPBYTE)&packet->header.length, 8);
// be sure to switch the xor header before writing
packet->header.xor_key = htonl(packet->header.xor_key);
idx = 0;
while (idx < sizeof(packet->header))
@ -1089,6 +1146,8 @@ DWORD packet_transmit_via_ssl(Remote* remote, Packet* packet, PacketRequestCompl
break;
}
dprintf("[OJ] packet header sent");
idx = 0;
while (idx < packet->payloadLength)
{

@ -278,15 +278,17 @@ static DWORD packet_transmit_http(Remote *remote, Packet *packet, PacketRequestC
HttpTransportContext* ctx = (HttpTransportContext*)remote->transport->ctx;
unsigned char *buffer;
buffer = malloc(packet->payloadLength + sizeof(TlvHeader));
DWORD totalLength = packet->payloadLength + sizeof(PacketHeader);
buffer = malloc(totalLength);
if (!buffer)
{
SetLastError(ERROR_NOT_FOUND);
return 0;
}
memcpy(buffer, &packet->header, sizeof(TlvHeader));
memcpy(buffer + sizeof(TlvHeader), packet->payload, packet->payloadLength);
memcpy(buffer, &packet->header, sizeof(PacketHeader));
memcpy(buffer + sizeof(PacketHeader), packet->payload, packet->payloadLength);
do
{
@ -296,7 +298,7 @@ static DWORD packet_transmit_http(Remote *remote, Packet *packet, PacketRequestC
break;
}
result = ctx->send_req(hReq, buffer, packet->payloadLength + sizeof(TlvHeader));
result = ctx->send_req(hReq, buffer, totalLength);
if (!result)
{
@ -308,7 +310,7 @@ static DWORD packet_transmit_http(Remote *remote, Packet *packet, PacketRequestC
dprintf("[PACKET TRANSMIT] request sent.. apparently");
} while(0);
memset(buffer, 0, packet->payloadLength + sizeof(TlvHeader));
memset(buffer, 0, totalLength);
ctx->close_req(hReq);
return res;
}
@ -380,6 +382,17 @@ static DWORD packet_transmit_via_http(Remote *remote, Packet *packet, PacketRequ
// Update the header length
packet->header.length = htonl(packet->payloadLength + sizeof(TlvHeader));
}
dprintf("[PACKET] New xor key for sending");
packet->header.xor_key = rand_xor_key();
dprintf("[PACKET] XOR Encoding payload");
// before transmission, xor the whole lot, starting with the body
xor_bytes(packet->header.xor_key, (LPBYTE)packet->payload, packet->payloadLength);
dprintf("[PACKET] XOR Encoding header");
// then the header
xor_bytes(packet->header.xor_key, (LPBYTE)&packet->header.length, 8);
// be sure to switch the xor header before writing
packet->header.xor_key = htonl(packet->header.xor_key);
dprintf("[PACKET] Transmitting packet of length %d to remote", packet->payloadLength);
res = packet_transmit_http(remote, packet, completion);
@ -414,7 +427,7 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet)
DWORD headerBytes = 0, payloadBytesLeft = 0, res;
CryptoContext *crypto = NULL;
Packet *localPacket = NULL;
TlvHeader header;
PacketHeader header;
LONG bytesRead;
BOOL inHeader = TRUE;
PUCHAR payload = NULL;
@ -469,7 +482,7 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet)
while (inHeader && retries > 0)
{
retries--;
if (!ctx->read_response(hReq, (PUCHAR)&header + headerBytes, sizeof(TlvHeader)-headerBytes, &bytesRead))
if (!ctx->read_response(hReq, (PUCHAR)&header + headerBytes, sizeof(PacketHeader)-headerBytes, &bytesRead))
{
dprintf("[PACKET RECEIVE HTTP] Failed HEADER read_response: %d", GetLastError());
SetLastError(ERROR_NOT_FOUND);
@ -489,7 +502,7 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet)
headerBytes += bytesRead;
if (headerBytes != sizeof(TlvHeader))
if (headerBytes != sizeof(PacketHeader))
{
continue;
}
@ -502,18 +515,22 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet)
break;
}
if (headerBytes != sizeof(TlvHeader))
if (headerBytes != sizeof(PacketHeader))
{
dprintf("[PACKET RECEIVE HTTP] headerBytes no valid");
SetLastError(ERROR_NOT_FOUND);
break;
}
dprintf("[PACKET RECEIVE HTTP] decoding header");
header.xor_key = ntohl(header.xor_key);
xor_bytes(header.xor_key, (LPBYTE)&header.length, 8);
header.length = ntohl(header.length);
// Initialize the header
vdprintf("[PACKET RECEIVE HTTP] initialising header");
header.length = header.length;
header.type = header.type;
payloadLength = ntohl(header.length) - sizeof(TlvHeader);
// use TlvHeader size here, because the length doesn't include the xor byte
payloadLength = header.length - sizeof(TlvHeader);
payloadBytesLeft = payloadLength;
// Allocate the payload
@ -552,7 +569,10 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet)
{
break;
}
dprintf("[PACKET RECEIVE HTTP] decoding payload");
xor_bytes(header.xor_key, payload, payloadLength);
// Allocate a packet structure
if (!(localPacket = (Packet *)malloc(sizeof(Packet))))
{
@ -560,7 +580,7 @@ static DWORD packet_receive_http(Remote *remote, Packet **packet)
break;
}
memset(localPacket, 0, sizeof(Packet));
memset(localPacket, 0, sizeof(Packet));
// If the connection has an established cipher and this packet is not
// plaintext, decrypt