Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #define DEBUG_EXCSERV 1
- #define BUFFLEN 1024
- #define ADAPTER_NAME "ExCServTUNAdapter"
- #define ADAPTER_NAMEW L"ExCServTUNAdapter"
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <iphlpapi.h>
- #include <iostream>
- #include <map>
- #include <string>
- #include <thread>
- #include <vector>
- #include "md5.h"
- #include "wintun.h"
- static WINTUN_CREATE_ADAPTER_FUNC* WintunCreateAdapter;
- static WINTUN_CLOSE_ADAPTER_FUNC* WintunCloseAdapter;
- static WINTUN_OPEN_ADAPTER_FUNC* WintunOpenAdapter;
- static WINTUN_GET_ADAPTER_LUID_FUNC* WintunGetAdapterLUID;
- static WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC* WintunGetRunningDriverVersion;
- static WINTUN_DELETE_DRIVER_FUNC* WintunDeleteDriver;
- static WINTUN_SET_LOGGER_FUNC* WintunSetLogger;
- static WINTUN_START_SESSION_FUNC* WintunStartSession;
- static WINTUN_END_SESSION_FUNC* WintunEndSession;
- static WINTUN_GET_READ_WAIT_EVENT_FUNC* WintunGetReadWaitEvent;
- static WINTUN_RECEIVE_PACKET_FUNC* WintunReceivePacket;
- static WINTUN_RELEASE_RECEIVE_PACKET_FUNC* WintunReleaseReceivePacket;
- static WINTUN_ALLOCATE_SEND_PACKET_FUNC* WintunAllocateSendPacket;
- static WINTUN_SEND_PACKET_FUNC* WintunSendPacket;
- #pragma comment(lib, "Ws2_32.lib")
- #pragma comment(lib, "iphlpapi.lib")
- #pragma warning(disable : 4996)
- using std::cout, std::map, std::string, std::to_string, std::vector;
- HMODULE
- InitializeWintun(void)
- {
- HMODULE Wintun =
- LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
- if (!Wintun)
- return NULL;
- #define X(Name) ((*(FARPROC *)&Name = GetProcAddress(Wintun, #Name)) == NULL)
- if (X(WintunCreateAdapter) || X(WintunCloseAdapter) || X(WintunOpenAdapter) || X(WintunGetAdapterLUID) ||
- X(WintunGetRunningDriverVersion) || X(WintunDeleteDriver) || X(WintunSetLogger) || X(WintunStartSession) ||
- X(WintunEndSession) || X(WintunGetReadWaitEvent) || X(WintunReceivePacket) || X(WintunReleaseReceivePacket) ||
- X(WintunAllocateSendPacket) || X(WintunSendPacket))
- #undef X
- {
- DWORD LastError = GetLastError();
- FreeLibrary(Wintun);
- SetLastError(LastError);
- return NULL;
- }
- return Wintun;
- }
- HMODULE Wintun;
- WINTUN_ADAPTER_HANDLE adapter;
- WINTUN_SESSION_HANDLE session;
- SOCKET sock;
- string curr_seckey;
- inline bool cstrcmp(char* s1, char* s2, size_t len) {
- for (size_t i = 0; i < len; i++) if (s1[i] != s2[i]) return false;
- return true;
- }
- template<typename S>
- inline void addstr(S dest, S src, size_t len, size_t offset = 0) {
- if (!dest || !src || len == 0) return;
- for (size_t i = 0; i < len; i++) {
- dest[i + offset] = src[i];
- }
- }
- template<typename I>
- I strtoint(char* data, size_t len, bool u = false) {
- using uI = typename std::make_unsigned<I>::type;
- uI output = 0;
- bool fbit = data[len - 1] == 1;
- for (size_t i = 0; i < len - (u ? 0 : 1); i++) {
- output |= ((uI)(BYTE)(data[i])) << (i * 8);
- }
- if (!u && fbit) return 0-((I)output);
- return (I)output;
- }
- template<typename I>
- char* inttostr(I data, size_t len, bool u = false) {
- using uI = typename std::make_unsigned<I>::type;
- uI d = (data < 0) ? 0 - ((uI)data) : data;
- bool fbit = data < 0;
- BYTE* str = new BYTE[len];
- for (size_t c = 0; c < len - (u ? 0 : 1); c++) {
- str[c] = (BYTE)(d % 256);
- d = (d - str[c]) / 256;
- }
- if (!u) str[len - 1] = fbit;
- return (char*)str;
- }
- int recv_all(SOCKET sock, char** buff, size_t len) {
- size_t c = len;
- char* buf = new char[BUFFLEN];
- *buff = new char[len];
- while (c > 0) {
- int res = recv(sock, buf, min(BUFFLEN, c), 0);
- if (res == SOCKET_ERROR) return WSAGetLastError();
- if (res == 0) return -1;
- addstr(*buff, buf, res, len - c);
- c -= res;
- }
- delete[] buf;
- return 0;
- }
- int recv_wrapper(SOCKET sock, char** buff, size_t* len) {
- char* buf;
- int res = recv_all(sock, &buf, 8);
- if (res != 0) return res;
- size_t c = strtoint<size_t>(buf, 8, true);
- res = recv_all(sock, &buf, c);
- if (res != 0) return res;
- *buff = buf;
- *len = c;
- return 0;
- }
- int send_wrapper(SOCKET sock, char* buff, size_t len) {
- char* packetlen = inttostr(len, 8, true);
- char* buf = new char[len + 8];
- addstr(buf, packetlen, 8);
- addstr(buf, buff, len, 8);
- size_t sent = 0;
- while (sent < len + 8) {
- int n = send(sock, buf + sent, len + 8 - sent, 0);
- if (n == SOCKET_ERROR) return WSAGetLastError();
- sent += n;
- }
- delete[] packetlen;
- delete[] buf;
- return 0;
- }
- typedef struct IPPort {
- char* ip;
- USHORT port;
- uint32_t rip;
- SOCKET sock;
- bool operator==(const IPPort& o) const {
- return ip == o.ip && port == o.port && rip == o.rip && sock == o.sock;
- }
- } *PIPP, IPP;
- class IPMap {
- public:
- vector<PIPP> clients;
- void add(PIPP o) {
- clients.push_back(o);
- }
- PIPP find(uint32_t o, size_t* pos = NULL) {
- size_t i = 0;
- for (auto& p : clients) {
- if (p->rip == o) {
- if (pos != NULL) *pos = i;
- return p;
- }
- i++;
- }
- return NULL;
- }
- PIPP find(char* o, size_t* pos = NULL) {
- size_t i = 0;
- for (auto& p : clients) {
- if (p->ip == o) {
- if (pos != NULL) *pos = i;
- return p;
- }
- i++;
- }
- return NULL;
- }
- PIPP find(USHORT o, size_t* pos = NULL) {
- size_t i = 0;
- for (auto& p : clients) {
- if (p->rip == o) {
- if (pos != NULL) *pos = i;
- return p;
- }
- i++;
- }
- return NULL;
- }
- PIPP find(SOCKET o, size_t* pos = NULL) {
- size_t i = 0;
- for (auto& p : clients) {
- if (p->sock == o) {
- if (pos != NULL) *pos = i;
- return p;
- }
- i++;
- }
- return NULL;
- }
- size_t find(IPP o) {
- size_t i = 0;
- for (auto& p : clients) {
- if (*p == o) return i;
- i++;
- }
- return -1;
- }
- size_t find(PIPP o) {
- size_t i = 0;
- for (auto& p : clients) {
- if (*p == *o) return i;
- i++;
- }
- return -1;
- }
- bool remove(uint32_t o) {
- size_t pos;
- if (find(o, &pos) == NULL) return false;
- clients.erase(clients.begin() + pos);
- return true;
- }
- bool remove(char* o) {
- size_t pos;
- if (find(o, &pos) == NULL) return false;
- clients.erase(clients.begin() + pos);
- return true;
- }
- bool remove(USHORT o) {
- size_t pos;
- if (find(o, &pos) == NULL) return false;
- clients.erase(clients.begin() + pos);
- return true;
- }
- bool remove(SOCKET o) {
- size_t pos;
- if (find(o, &pos) == NULL) return false;
- clients.erase(clients.begin() + pos);
- return true;
- }
- bool remove(IPP o) {
- size_t pos;
- if ((pos = find(o)) == -1) return false;
- clients.erase(clients.begin() + pos);
- return true;
- }
- bool remove(PIPP o) {
- size_t pos;
- if ((pos = find(o)) == -1) return false;
- clients.erase(clients.begin() + pos);
- return true;
- }
- };
- IPMap clients;
- bool w = true, s = true;
- inline bool waitForThreads() {
- if (w) return false;
- while (!clients.clients.empty() && !s) Sleep(50);
- return true;
- }
- size_t encrypt(BYTE* i, BYTE** o, size_t len) {
- *o = i;
- return len;
- }
- size_t decrypt(BYTE* i, BYTE** o, size_t len) {
- *o = i;
- return len;
- }
- void recv_thread(PIPP client) {
- while (w) {
- char* buff;
- size_t len;
- int res = recv_wrapper(client->sock, &buff, &len);
- if(res == -1) {
- cout << "F: Recv thread error (" << client->ip << ":" << client->port << "): connection closed\n";
- break;
- }
- if (res > 0) {
- cout << "F: Recv thread error (" << client->ip << ":" << client->port << "): " << res << "\n";
- break;
- }
- if (len > 0) {
- BYTE* p = WintunAllocateSendPacket(session, (DWORD)len);
- if (p) {
- BYTE* data = (BYTE*)buff;
- len = decrypt(data, &data, len);
- addstr(p, data, len);
- delete[] data;
- WintunSendPacket(session, p);
- cout << "I: Recv " << len << "bytes\n";
- }
- }
- }
- closesocket(client->sock);
- clients.remove(client);
- }
- void send_thread() {
- HANDLE ev = WintunGetReadWaitEvent(session);
- while (w) {
- DWORD psize;
- BYTE* p = WintunReceivePacket(session, &psize);
- if (p) {
- // IP находится по смещению 16 в IPv4 пакете
- if (psize >= 20) {
- uint32_t ip = *(uint32_t*)(p + 16);
- PIPP client;
- if ((client = clients.find(ip)) != NULL) {
- BYTE* data1 = new BYTE[psize];
- addstr(data1, p, psize);
- psize = encrypt(data1, &data1, psize);
- int res = send_wrapper(client->sock, (char*)data1, psize);
- delete[] data1;
- WintunReleaseReceivePacket(session, p);
- if (res == -1) {
- cout << "F: Send thread error: connection closed\n";
- break;
- }
- if (res > 0) {
- cout << "F: Send thread error: " << res << "\n";
- break;
- }
- cout << "I: Send " << psize << "bytes\n";
- }
- #if DEBUG_EXCSERV == 1
- else {
- in_addr d;
- d.S_un.S_addr = ip;
- cout << "W: No route to " << inet_ntoa(d) << "\n";
- }
- #endif
- }
- WintunReleaseReceivePacket(session, p);
- }
- else {
- WaitForSingleObject(ev, INFINITE);
- }
- }
- w = false;
- s = false;
- }
- static BOOL WINAPI
- CtrlHandler(_In_ DWORD CtrlType)
- {
- switch (CtrlType)
- {
- case CTRL_C_EVENT:
- case CTRL_BREAK_EVENT:
- case CTRL_CLOSE_EVENT:
- case CTRL_LOGOFF_EVENT:
- case CTRL_SHUTDOWN_EVENT:
- w = false;
- cout << "I: Stopping...\n";
- waitForThreads();
- return TRUE;
- }
- return FALSE;
- }
- const string secalphabet = "1234567890-qwertyuiopasdfghjklzxcvbnm_QWERTYUIOPASDFGHJKLZXCVBNM";
- const size_t salen = secalphabet.size();
- #define SECURE_KEY_LEN 32
- inline void freep(USHORT stage = 5) {
- if (stage > 4) {
- WintunEndSession(session);
- }
- if (stage > 3) {
- closesocket(sock);
- }
- if (stage > 2) {
- WSACleanup();
- }
- if (stage > 1) {
- WintunCloseAdapter(adapter);
- }
- if (stage > 0) {
- FreeLibrary(Wintun);
- }
- SetConsoleCtrlHandler(CtrlHandler, FALSE);
- }
- int main(int argc, char* argv[])
- {
- int res;
- SetConsoleCtrlHandler(CtrlHandler, TRUE);
- map<string, string> args;
- for (unsigned i = 1; i < argc; i++) {
- string x = argv[i];
- size_t pos = x.find_first_of("=");
- if (pos == string::npos) {
- args.insert(std::pair(x, ""));
- }
- args.insert(std::pair(x.substr(0, pos), x.substr(pos + 1, x.size() - pos - 1)));
- }
- #if DEBUG_EXCSERV == 1
- args.insert(std::pair("--seckey", "OlwCTg9KQa5Fbu1PzeVYh0LWs6Gni2Ax"));
- #endif
- cout << "ExC Server\nArgs:\n";
- if (args.empty())
- cout << " - No args\n";
- else for (auto& p : args) {
- cout << " - \"" << p.first << "\"=\"" << p.second << "\"\n";
- }
- if (!args.contains("--seckey")) {
- cout << "F: no secure key. Copy new secure key and add it in config\nKey: ";
- time_t stmp = time(NULL);
- string data = "";
- size_t i = 0;
- time_t tmp = 0;
- while (data.size() < SECURE_KEY_LEN) {
- tmp = stmp * i + i - 1;
- while (tmp > 0) {
- if (data.size() > SECURE_KEY_LEN) break;
- data += secalphabet[tmp % salen];
- tmp = (tmp % salen) / salen;
- }
- i++;
- }
- cout << data << "\n";
- freep(0);
- return 1;
- }
- cout << "I: On first launch, run this command in PowerShell:\nSet-NetIPInterface -Forwarding Enabled\nIf packets stop being sent, please re-run the command, replacing \"Enabled\" with \"Disabled\"\n";
- curr_seckey = MD5::hash(args["--seckey"]);
- if ((Wintun = InitializeWintun()) == NULL) {
- cout << "F: wintun can't be loaded. Check wintun.dll or it is corrupted: " << GetLastError() << "\n";
- freep(0);
- return 1;
- }
- int port = 80;
- if (!args.contains("--port")) {
- cout << "W: no port, using 80\n";
- }
- else {
- try {
- port = std::stoi(args["--port"]);
- if (port < 1 && port > 1024 * 64) {
- cout << "W: invalid port (clamp), using 80\n";
- port = 80;
- }
- }
- catch (...) {
- cout << "W: invalid port (stoi), using 80\n";
- port = 80;
- }
- }
- GUID AdapterGuid = { 0xDEADDEAD, 0xFF12, 0xFF7F, { 0xA1, 0xB2, 0xC3, 0xD4, 0xF5, 0x6A, 0x7B, 0x8C } };
- adapter = WintunCreateAdapter(ADAPTER_NAMEW, L"TUN", &AdapterGuid);
- if (!adapter)
- {
- res = GetLastError();
- if (res != ERROR_ALREADY_EXISTS) {
- cout << "F: failed to create TUN adapter: " << res << "\n";
- freep(1);
- return 1;
- }
- adapter = WintunOpenAdapter(ADAPTER_NAMEW);
- if (!adapter) {
- cout << "F: failed to open TUN adapter: " << GetLastError() << "\n";
- freep(1);
- return 1;
- }
- }
- cout << "I: TUN adapter:\nName=" << ADAPTER_NAME << "\nType=TUN\nGUID={" << std::hex << AdapterGuid.Data1 << "-"
- << AdapterGuid.Data2 << "-" << AdapterGuid.Data3 << "-" << (short)AdapterGuid.Data4[0] << (short)AdapterGuid.Data4[1] << "-"
- << (short)AdapterGuid.Data4[2] << (short)AdapterGuid.Data4[3] << (short)AdapterGuid.Data4[4] << (short)AdapterGuid.Data4[5]
- << (short)AdapterGuid.Data4[6] << (short)AdapterGuid.Data4[7] << std::dec << "}\n";
- MIB_UNICASTIPADDRESS_ROW AddressRow;
- InitializeUnicastIpAddressEntry(&AddressRow);
- WintunGetAdapterLUID(adapter, &AddressRow.InterfaceLuid);
- AddressRow.Address.Ipv4.sin_family = AF_INET;
- AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((192 << 24) | (168 << 16) | (0x12 << 8) | (0x7F << 0));
- AddressRow.OnLinkPrefixLength = 24;
- AddressRow.DadState = IpDadStatePreferred;
- res = CreateUnicastIpAddressEntry(&AddressRow);
- if (res != ERROR_SUCCESS && res != ERROR_OBJECT_ALREADY_EXISTS)
- {
- cout << "F: failed to set IP address: " << res << "\n";
- freep(2);
- return 1;
- }
- cout << "I: local IP address: 192.168.18.127\n";
- WSADATA wsad;
- res = WSAStartup(MAKEWORD(2, 2), &wsad);
- if (res != 0) {
- cout << "F: WSAStartup failed: " << to_string(res) << "\n";
- freep(2);
- return 1;
- }
- addrinfo* result = NULL, hints;
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = AI_PASSIVE;
- res = getaddrinfo(NULL, to_string(port).c_str(), &hints, &result);
- if (res != 0) {
- cout << "F: Getaddrinfo failed: " << to_string(res) << "\n";
- freep(3);
- return 1;
- }
- sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
- if (sock == INVALID_SOCKET) {
- cout << "F: error at socket(): " << to_string(WSAGetLastError()) << "\n";
- freeaddrinfo(result);
- freep(3);
- return 1;
- }
- if (bind(sock, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
- cout << "F: bind failed with error: " << to_string(WSAGetLastError()) << "\n";
- freeaddrinfo(result);
- freep(4);
- return 1;
- }
- cout << "I: bind on 127.0.0.1:" << to_string(port) << "\n";
- freeaddrinfo(result);
- session = WintunStartSession(adapter, 0x400000);
- if (!session)
- {
- cout << "F: failed to start adapter session";
- freep(4);
- return 1;
- }
- std::thread sth{ send_thread };
- sth.detach();
- while (w) {
- if (listen(sock, SOMAXCONN) == SOCKET_ERROR) {
- cout << "F: listen failed with error: " << to_string(WSAGetLastError()) << "\n";
- w = false;
- waitForThreads();
- freep();
- return 1;
- }
- sockaddr_in saddr;
- socklen_t csaddr = sizeof(saddr);
- SOCKET csock = accept(sock, (sockaddr*)&saddr, &csaddr);
- if (csock == INVALID_SOCKET) {
- cout << "E: accept failed: " << to_string(WSAGetLastError()) << "\n";
- continue;
- }
- char* addr = inet_ntoa(saddr.sin_addr);
- USHORT port = saddr.sin_port;
- PIPP c = new IPP;
- c->ip = _strdup(addr);
- c->port = port;
- c->rip = saddr.sin_addr.S_un.S_addr;
- c->sock = csock;
- cout << "I: New connection thread (" << addr << ":" << to_string(port) << ")\n";
- char* buff;
- size_t len;
- int res = recv_wrapper(csock, &buff, &len);
- if (res == -1) {
- cout << "I: Connection closed (" << addr << ":" << to_string(port) << "): secure key\n";
- continue;
- }
- else if (res > 0) {
- cout << "E: Connection error (" << addr << ":" << to_string(port) << "): secure key recv " << res << "\n";
- continue;
- }
- if (len != curr_seckey.size()) {
- cout << "E: Connection error (" << addr << ":" << to_string(port) << "): secure key lenght" << curr_seckey.size() - len << "\n";
- char* skresp = new char;
- skresp[0] = 1;
- send_wrapper(csock, skresp, 1);
- closesocket(csock);
- continue;
- }
- if (!cstrcmp(curr_seckey.data(), buff, len)) {
- cout << "E: Connection error (" << addr << ":" << to_string(port) << "): secure key data\n";
- char* skresp = new char;
- skresp[0] = 2;
- send_wrapper(csock, skresp, 1);
- closesocket(csock);
- continue;
- }
- cout << "I: Secure key is ok (" << addr << ":" << to_string(port) << ")\n";
- char* skresp = new char;
- skresp[0] = 0;
- send_wrapper(csock, skresp, 1);
- clients.add(c);
- std::thread rth{ recv_thread, c };
- rth.detach();
- }
- w = false;
- waitForThreads();
- freep();
- }
Advertisement
Add Comment
Please, Sign In to add comment