Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Генерация SYN пакетов (Linux)  (Прочитано 15562 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« : 06-10-2008 12:21 » 

Необходимо генерировать tcp пакеты с установленным флагом SYN.
Создаю RAW-сокет и через него посылаю 'tcp'-пакет с установленным <SYN>. Но столкнулся с неприятной проблемой, когда удаленная машина в ответ отправляет пакет <SYN,ACK>, моя почему то в ответ шлет пакет <RST>, что приводит к сбросу данного соединения на удаленной машине.
Подскажите, как побороть данную проблему?
Код:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <stdarg.h>
#include <errno.h>
#include <inttypes.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <netinet/ip_icmp.h>

static const char ip_src[] = "192.168.20.220";
static const char ip_dst[] = "192.168.20.236";

static const char *progname;

struct tcphdr tcp;

struct {
struct ip ip;
struct icmp icmp;
} msg;

struct {
struct {
struct in_addr ip_src, ip_dst;
uint16_t ptcl;
uint16_t len;
} ptcp;
struct tcphdr tcp;
} pack;

static void errprint(const char *fmt, ...)
{
va_list args;

if (progname != NULL)
fprintf(stderr,"%s: ",progname);
va_start(args,fmt);
vfprintf(stderr,fmt,args);
va_end(args);

exit(1);
}

static uint16_t ip_sum_calc(const uint8_t *buff, int len)
{
const uint16_t *p = (const uint16_t *)buff;
uint32_t sum = 0;
int i;

for (i = 0; i < len / 2; i++) {
sum += p[i];
if (sum > 0xffff)
sum = (sum & 0xffff) + 1;
}

sum = ~sum;
return sum;
}

static void print_hex(const uint8_t *buff, int len)
{
int i = 0;

while (i < len) {
printf("0x%02x ",buff[i++]);
if ((i % 4) == 0)
putchar('\n');
}
}

static void create_msg(void)
{
char ch;
int i;

/* prepare 'icmp' */
msg.icmp.icmp_type = ICMP_ECHO;
msg.icmp.icmp_code = 0;
msg.icmp.icmp_cksum = 0;
msg.icmp.icmp_id = rand();
msg.icmp.icmp_seq = 0;
ch = 'a';
for (i = 0; i < sizeof(struct icmp) - sizeof(struct icmphdr); i++, ch++)
((char *)&msg.icmp.icmp_dun.id_data[0])[i] = ch;
msg.icmp.icmp_cksum = ip_sum_calc((uint8_t *)&msg.icmp,sizeof(msg.icmp));

/* prepare 'ip' */
msg.ip.ip_v = 4;
msg.ip.ip_hl = 5;
msg.ip.ip_tos = 0;
msg.ip.ip_len = htons(sizeof(msg));
msg.ip.ip_id = htons(rand());
msg.ip.ip_off = htons(IP_DF);
msg.ip.ip_ttl = 64;
msg.ip.ip_p = IPPROTO_ICMP;
msg.ip.ip_sum = 0;
msg.ip.ip_src.s_addr = inet_addr(ip_src);
msg.ip.ip_dst.s_addr = inet_addr(ip_dst);
msg.ip.ip_sum = htons(ip_sum_calc((void *)&msg.ip,sizeof(msg.ip)));
}

void create_tcp(void)
{
memset(&pack,0,sizeof(pack));

pack.ptcp.ip_src.s_addr = inet_addr(ip_src);
pack.ptcp.ip_dst.s_addr = inet_addr(ip_dst);
pack.ptcp.ptcl = htons(IPPROTO_TCP);
pack.ptcp.len = htons(sizeof(pack.tcp));

pack.tcp.source = htons(1000);
pack.tcp.dest = htons(448);
pack.tcp.seq = htonl(101);
pack.tcp.doff = 5;
pack.tcp.syn = 1;
pack.tcp.window = 1024;
pack.tcp.check = ip_sum_calc((void *)&pack,sizeof(pack));
}

int main(int argc, char **argv)
{
char buff[1024];
struct sockaddr_in addr;
int raw_socket;
int res,tmp;

progname = argv[0];
srand(time(NULL));

create_msg();
create_tcp();

raw_socket = socket(PF_INET,SOCK_RAW,IPPROTO_TCP);
if (raw_socket < 0)
errprint("Failed execute 'socket': %s\n",strerror(errno));
tmp = 1;
// res = setsockopt(raw_socket,IPPROTO_IP,IP_HDRINCL,&tmp,sizeof(tmp));
// if (res < 0)
// errprint("Failed execute 'setsockopt': %s\n",strerror(errno));

printf("to:\n");
print_hex((uint8_t *)&pack,sizeof(pack));

memset(&addr,0,sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = 448;
addr.sin_addr.s_addr = inet_addr(ip_dst);
// res = sendto(raw_socket,&msg,sizeof(msg),0,
// (struct sockaddr *)&addr,sizeof(addr));
res = sendto(raw_socket,&pack.tcp,sizeof(pack.tcp),0,
(struct sockaddr *)&addr,sizeof(addr));
if (res < 0)
errprint("Failed execute 'sendto': %s\n",strerror(errno));

addr.sin_family = AF_INET;
addr.sin_port = IPPROTO_TCP;
addr.sin_addr.s_addr = inet_addr(ip_dst);
tmp = sizeof(addr);
res = recvfrom(raw_socket,buff,sizeof(buff),0,
(struct sockaddr *)&addr,&tmp);
if (res < 0)
errprint("Failed execute 'recvfrom': %s\n",strerror(errno));

printf("from:\n");
print_hex(buff,res);

sleep(10);

close(raw_socket);

return 0;
}
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #1 : 07-10-2008 10:56 » 

Система поступает логично.

Наверно нужно с цели задачи начать. Какая цель?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #2 : 07-10-2008 11:18 » 

Необходимо обеспечить защиту "connection tracker" от переполнения. Впринципе уже основная часть реализована и построена на основе библиотеки "libnetfilter_conntrack".
Осталось за малым, провести комплексное тестирование, т.е. имитация разных атак на систему. Вот и пишу сейчас маленькие утилиты для этого.

Проблему посылки ответного <RST> пакета решил с помошью подстановки фиктивного IP-адресса, атакуемая машина шлет в ответ <SYN,ACK>, а в ответ тишина Улыбаюсь. И соединение в состоянии 'SYN_RECV'.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 07-10-2008 11:43 » 

Думаю, что все это можно реализовать в рамках iptables и настроек ядра без стороннего софта.

1. Фильтровать все ненужное еще в таблице mangle - DROP их к черту.
2. Лимитировать к-во SYN в единицу времени.
3. Подкрутить параметры касательно TCP - уменьшить таймауты.

Использование netfilter серьезно замедлит работу с сетью, т.к. вносятся приличные накладные расходы переключения контекста при каждом пакете.
« Последнее редактирование: 07-10-2008 11:46 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 07-10-2008 12:03 » 

Думаю, что все это можно реализовать в рамках iptables и настроек ядра без стороннего софта.
Тоже так думали в свое время Улыбаюсь

Дело в том что "connection tracker" используется модулем 'iptables' и внем отражаются все текушие соединения проходящие через машину, а также NAT, SNAT и подобное сохраняет свои сеансы в нем. Вот только размер "connection tracker" составляет всего 65536 записей ("unsignet short int"). И на очень оживленных магистралях, "connection tracker" переполняется очень быстро, и машина уходит в аут.

Все что Ты предложил RXL, уже используем и это позволило держать "connection tracker" на приемлемом уровне, порядка 35000 записей. Но это все, когда трафик бежит нормальный. Но если начать закидывать машину <SYN> пакетами или устанавливать соединение и удерживать их то это все автоматом начнет попадать в "connection tracker" и вот тут он и может переполнится.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 07-10-2008 12:10 » 

Хм. На таких нагрузках логично было бы использовать соответствующее оборудование - ту же Циску. Я так думаю. Итаче слишком легко завалить будет.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 07-10-2008 12:19 » 

Такие Циски больших денег стоят Улыбаюсь, я бы сказал что очень больших денег. У нас их HP145 нормально справляются. Улыбаюсь
Да и задачи у нас другие, нам не надо трафик маршрутищировать.
Записан
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #7 : 07-10-2008 12:22 » 

А если подумать о модуле ядра? Улыбаюсь Существенно быстрее будет.

Собственно, можно модифицировать модуль net/ipv4/netfilter/ip_conntrack_proto_tcp.c - он всего 8.5 кБ размером.
« Последнее редактирование: 07-10-2008 19:30 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #8 : 07-10-2008 13:31 » 

RXL, циски на самом деле не панацея, Чего толь стоят их SPAN порты.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
RXL
Технический
Администратор

Offline Offline
Пол: Мужской

WWW
« Ответ #9 : 07-10-2008 14:04 » new

Зато они заточены под это - специализация помогает.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines