Ранее уже были обсуждены средства антиспуфинга, начиная от простых и заканчивая сложными, но по-прежнему не был получен ответ на вопрос «Как на самом деле создаются системы спуфинга?». Часто ответ на этот вопрос заключается в изучении сетевого трафика, повторной реализации протокола более простым и универсальным программным способом и отправкой сетевых данных самым неожиданным для получателя способом.

Плевок против ветра: создание скелета маршрутизатора в пространстве пользователя

Для достижения полной универсальности недостаточно просто полагаться на инструментальные средства уровня командной строки. Необходима программа. Но слишком большая программа может оказаться неудобной для использования. Зачастую функциональные возможности слишком большой программы никогда не бывают использованы полностью, из-за того что в них широко используются встроенные возможности специфических компонент ядра. К тому же необходимое количество функциональных возможностей вряд ли можно элегантно реализовать из-за невозможности совместить их в рамках одного интерфейса. Особенно когда это касается универсальных, в полном смысле этого слова, сетевых решений. Искусно настроенные сетевые средства, встроенные в современные ядра систем, непригодны для целей спуфинга. Прежде всего создателей систем спуфинга интересуют системы, которые не столько строго следуют общеизвестным правилам, сколько нарушают их.

Это - ошибкоустойчивость наоборот.

Что действительно необходимо, так это простая инфраструктура, с помощью которой можно получить доступ к произвольным пакетам, возможно с использованием, но лучше без использования фильтрации пакетов на уровне ядра. Кроме того, она должна обеспечивать эффективную и достаточно легкую обработку пакетов с последующей отсылкой, если это необходимо, их обратно. Возможным решением поставленной проблемы является программа DoxRoute 0.1, которая доступна по адресу www.doxpara.com/tradecraft/doxroute вместе со своей документацией, что является первым подобным случаем.

Проектирование несуществующего: сетевая карта, которая не существовала, но возвращала код возврата

В сети маршрутизатор всегда выполняет три вещи:

• отвечает на ARP-пакеты, которые ищут определенный МАС-адрес;

• отвечает на запросы ping, которые ищут определенные IP-адреса;

• передают транзитные пакеты дальше, возможно, запрашивая информацию о промежуточных точках маршрута пакетов.

Традиционно эти функции выполняются ядрами операционных систем. В худшем случае ядра операционных систем - это большие, неповоротливые, трудно управляемые животные. В лучшем - изящные, быстро работающие черные ящики с функциями адресования и фильтрации пакетов, выполняемыми сетевыми картами самостоятельно. В специализированных системах Cisco и некоторых других производителей большинство функций маршрутизации реализованы аппаратными средствами. Максимальную производительность демонстрируют оптоволоконные специализированные системы ASIC. Но сеть не заботит вопрос о том, каким образом задание будет выполнено: будет ли оно выполнено аппаратными средствами, ядром операционной системы или, как в рассматриваемом случае, парой-сотней строк программы на языке С, переносимой с одной платформы на другую.

Программа DoxRoute является интересным решением. Это был эксперимент, который продемонстрировал возможность реализации разумных возможностей спуфинга машин сети при помощи программы, вызывающей функции библиотек libnet и libpcap. Обычно считалось, что подобные функциональные возможности могут быть реализованы сложными программами ядра операционной системы. На самом деле было показано, что их можно реализовать программой, содержащей удивительное число изящных простых решений, направленных на достижение невообразимого уровня производительности. Вероятно, необычайный уровень производительности был достигнут благодаря работе библиотек libpcap, libnet непосредственно с обрабатываемыми пакетами при их получении и передаче. Для обработки 12-мегабитного потока данных потребовалось загрузить процессор РЗ-800 приблизительно на 2 %. При этом время ожидания эха при посылке управляющих сообщений по протоколу ICMP было уменьшено до 0.23 мс. Оба показателя могут быть улучшены при помощи незначительного упрощения кода.

Примечание

Между прочим, это не первая попытка прямой передачи данных по каналу связи для реализации стека основных протоколов. Это даже не вариант наиболее «законченной» мини-сети Miniweb, который можно найти по адресу www.dunkels.com/adam/miniweb и который компилируется в программу размером в 30 байт, работающую на уровне IP. Эта программа размером в 30 байт является рабочей реализацией протокола TCP с разумными возможностями. Существуют системы, которые имитируют группу серверов на одной машине. Достоинство программы DoxRoute заключается в ее простоте, интернациональности, разумной переносимости на различные платформы и качестве написания. Программа была написана с исключительно обнадеживающей простотой.

Реализация программы DoxRoute: раздел за разделом Выполнение DoxRoute довольно тривиально:

[root@localhost effugas]# ,/doxroute -г 10.0.1.254 -с -v 10.0.1.170 ARP REQUEST: Wrote 42 bytes looking for 10.0.1.254 Router Found: 10.0.1.254 at 0:3:E3:0:4E:6B DATA: Sent 74 bytes to 171.68.10.70 DATA: Sent 62 bytes to 216.239.35.101

DATA: Sent 60 bytes to 216.239.35.101 DATA: Sent 406 bytes to 216.239.35.101 DATA: Sent 60 bytes to 216.239.35.101 DATA: Sent 60 bytes to 216.239.35.101

Поскольку рассматриваемая реализация программы неполная, то на самом деле в ней нет обработки состояний маршрутизатора (поэтому в тексте программы не следует заменять константы со значением 7200 с). Программа DoxRoute такова, что вполне возможно завершить процесс маршрутизации на одной машине и запустить его на другой, не сообщая об этом переключателю режимов работы программы. Можно найти большое количество инструментальных систем активного спуфинга. Например, инструментальное средство Ettercap (http://ettercap.sourceforge.net) является одним из наиболее интересных пакетов фальсификации для реализации атак «злоумышленник посередине» (MITM), направленных против сеансов сети. Пакет поддерживает большое количество протоколов. С помощью Ettercap можно реализовать различные специфические варианты спуфинга. Пакет DoxRoute обеспечивает инфраструктуру для ответа на вопрос: «Что произойдет, если к сети подключить машину для выполнения..?» Если можно обмануть внутренний маршрутизатор несколькими строчками кода, то фальсификация еще чего-нибудь будет ненамного сложнее.

Инструментарий и ловушки

Гибкая маршрутизация в 1Ж1Х на горизонте?

Маршрутизация операционной системы 1ЛМ1Х может быть быстрой, но она прямолинейна до абсурда. Хотите направить трафик через порт? Этого нельзя сделать. Хотите направить трафик через собственную машину? Опять нельзя. Хотите ограничить пропускную способность жестко определенным набором сетевых действий? Попробуйте, и пусть читателю повезет. Главное предназначение программы DoxRoute, которое сильно отличает ее от остальных, заключается в предоставлении хороших способов программирования действительно интересных фильтров и наборов правил для сетевого трафика. В действительности программировать на уровне ядра операционной системы очень сложно, слишком опасно и практически непереносимо с одной платформы на другую, для того чтобы большинство людей смогло этим заняться. Напротив, эти же задачи, решаемые с помощью DoxRoute, занимают всего пару листков программного кода с комментариями. Цель: «Если читатель захочет самостоятельно заняться маршрутизацией всех пакетов, которые отсылаются по кабельному модему вместо цифровой абонентской линии каждое третье воскресенье каждого месяца с нечетным числом байтов и которые содержат слово 218§уЬ°Р> т0 пусть он попробует».

Все, что для этого нужно сделать, на самом деле не очень сложно. После чтения нескольких опций пользователя инициируется программа перехвата и генерации пакетов, которая сравнивает каждый поступивший пакет с коротким списком правил, определяющих возможную генерацию кода возврата в той или иной форме. Хотите более подробно? Вот схема алгоритма:

1. Установить конфигурацию.

1.1. Установить статические переменные.

1.2. Присвоить значения по умолчанию.

1.3. Выполнить анализ командной строки.

2. Начать анализ трафика. 2.1. Открыть устройство прослушивания с максимально возможной производительностью.

2.2. Применить фильтрацию ядра к потоку данных, который вскоре будет активизирован.

2.3. Активизировать поток.

3. Начать спуфинг. 3.1.Открыть устройство отправки данных с максимально возможной производительностью.

3.2. Послать ARP-запрос на поиск МАС-адреса маршрутизатора.

4. Разбор прослушиваемого пакета (бесконечный цикл, который срабатывает по приему пакета). 4.1. Применить правила анализа.

4.2. Потребовать пространство пользователя для ГР-и МАС-адреса.

4.2.1. Поиск ARP-запросов для своего 1Р-адреса.

4.2.2. Деструктивное преобразование ARP-запроса в ARP-ответ с указанием IP-адреса и МАС-адреса в пространстве пользователя.

4.2.3. Отсылка преобразованного пакета.

4.3. Поиск ARP-ответов с МАС-адресами маршрутизатора.

4.3.1. Создание кэша для последующего решения задач маршрутизации.

4.4. Поиск запросов PING (ICMP ECHO) к своим IP-и МАС-адресам.

4.4.1. Деструктивное преобразование ICMP ECHO и ответ на него.

4.4.2. Уменьшение счетчика времени жизни пакета TTL.

4.4.3. Пересчет контрольной суммы пакета.

4.4.4. Отсылка преобразованного пакета.

4.5. Маршрутизация пакета на свой МАС-адрес.

4.5.1. При необходимости проверить, является ли полученный пакет 1Р-пакетом.

4.5.2. Деструктивное переназначение Ethemet-адресов получателя и отправителя на адреса отправителя пакета и получателя в локальной сети соответственно.

4.5.3. Если можно вычислить контрольную сумму, то уменьшить счетчик времени жизни пакета и повторно вычислить контрольную сумму пакета.

4.5.4. Отослать измененный пакет.

Начало: директивы препроцессора и объявления функций. Ниже приводится полный код для использования. Его трудно прокомментировать. В интересах обсуждения отступ в комментариях был удален. Давайте начнем!

#define TITLE “DoxRoute: Userspace IP Router” #define VERSION “0.1”
#define CODERS “Copyright (C) 2001 Dan Kaminsky (dan@doxpara. com)”
#define CODENAME “Bender”
#define GIANT “Mark Grimes(obecian@packetninja.net)”

Конечно, следует доверять там, где это оправданно. Удивительно, но приведенных строк достаточно для построения кода с использованием блестящего пакета nemesis компании Grimes, хотя его использование практически не заметно.

#include <stdio.h> #include <stdlib.h>
#include <unistd.h>
#include <libnet.h>
#include <pcap.h>
#ifndef IP V 4ADDRLEN #define IPV4 ADDR LEN 4 #endif

Прежде всего следует определить необходимые для работы приложения библиотеки. Для программы DoxRoute потребуются три вещи. Во-первых, стандартные библиотеки, необходимые почти каждому приложению на языке С. Они подключаются при помощи файлов stdio.h, stdlib.h и unistd. Во-вторых, система для отправки фальсифицированных пакетов. Она инкапсулирована внутри файла libnet.h, очевидно, связанного с библиотекой libnet. И наконец, в-третьих, система прослушивания любых пакетов, передаваемых по каналу связи. Подключение такой системы осуществляется при помощи файла pcap.h библиотеки libpcap. Но более важным является не то, что реализовано, а то, что не реализовано. Обычно для любой предназначенной для работы в сети программы, особенно программы обработки пакетов на низком уровне, требуется огромное число зависимых от операционной системы библиотек и включаемых в программу файлов заголовков. Используемые файлы и заголовки сильно изменяются от платформы к платформе, что является головной болью не только при переходе от одной платформы к другой, но и от одной версии ядра к другой. Программа сталкивается с ордами директив препроцессора с большим числом макросов #ifdef которые определяют последовательность действий на каждой системе. После этого кода программа приобретает вполне законченный вид.

Использование библиотек libpcap и libnet позволяет изменить это. В них содержатся описания входящих и выходящих пакетов, а также некоторые базовые структуры, которые необходимы для того, чтобы понять, что вообще происходит на самом деле. Появляется возможность отвлечься от рассмотрения пустой болтовни, зависимой от операционной системы:

void usage(); void print_ip(FILE * stream, uchar * ip);
void print_mac(FILE * stream, u char * mac);
int
main(int argc, char **argv)
{

Объявления переменных. В основном все переменные предназначены для функции getopt - общего синтаксического анализатора опций командной строки: int opx; extern char *optarg; extern int opterr;

К настоящему моменту времени читатель уже, вероятно, заметил, что в операционной системе UNIX почти все приложения командной строки совместно используют одинаковый синтаксис: что-то вроде foo - X - у параметр. Этот формат входных параметров стандартизирован и обрабатывается библиотечной функцией getopt. Очень старые платформы для успешного анализа входных параметров потребуют от программиста добавить в начало его программного кода директиву # include <getopt.h>. Более современные стандарты предусматривают помещение функции getopt как части файла unistd.h:

pcap_t *рсар; /* РСАР file descriptor */ u_char *packet; /* Our newly captured packet */ struct pcap_pkthdr pkthdr; /* Packet metadata-time received, size */

struct bpf_program fp; /* Structure to hold kernel packetfilter
*/
char pfprogram[255]; /* Buffer for uncompiled packet filter */
char dev[255]; /* Name of device to use */ int immediate = 1; /* Flag to suck packets at max speed */
int promise = 1; /* Flag to grab all packets visible */

Особого пояснения требует буфер pfprogram. Аналогичное выражение можно использовать в программе tcpdump или tethereal точно так же, как и, например, порт 22 или хост 1.2.3.4 и udp. Фактически описание буфера является входной спецификацией конструирования фильтров внутри библиотеки libpcap. Библиотека libpcap сама транслирует фильтр в выполняемый код. Достаточно только передать осмысленную с точки зрения синтаксиса строку параметров, а все остальное библиотека доделает сама. Результат впечатляет:

struct libnet ethemet hdr *eth = NULL; struct libnet ip hdr *ip = NULL;
struct libnet tcp hdr *tcp = NULL;
struct libnet_arp_hdr *arp = NULL;
struct libneticmphdr *icmp = NULL;
struct libnet udp hdr *udp = NULL;

В библиотеке libnet определены базовые типы пакетов, которые описаны во включаемом файле include/libnet/libnet-headers.h. Подобное определение типов пакетов не только экономит время, но и позволяет стандартизировать структуры описания пакетов, по крайней мере при создании переносимых сетевых инструментальных средств: struct libnet link int *1; uchar *newpacket; uchar user_ip[IPV4_ADDR_LEN+l]; uchar upstream_ip[IP V4ADDRLEN+1 ]; uchar test_ip[IPV4_ADDR_LEN+l]; struct inaddr testipa;

/* MAC addresses = Local Link-Level Hardware Addresses On The Network */
u char user_mac[ETHER_ADDR_LEN+l]; /* MAC to receive packets on */
u char upstream_mac[ETHER_ADDR_LEN+l]; /* MAC to forward packets to */
u char bcast_mac[ETHER_ADDR_LEN+l]; /* Forward addr for all MACs */
u char test_mac[ETHER_ADDR_LEN+l]; /* A buffer to test against */

В этих строчках кода присутствует стеснительный и, вероятно, ненужный хакинг. Важно, что создан статический массив для заполнения различных адресов: собственного IP-адреса, МАС-адреса маршрутизатора, которому будет передан пакет, и т. д. Но благодаря странностям функции sscanf и тому факту, что при быстрой работе утрачивается некоторая безопасность, буфера перезаписываются странными и не до конца выясненными способами. Буфера можно очистить, создавая буфер одного из устройств большего, чем это действительно нужно, размера. Этот способ не очень элегантен, он даже уродлив, но вполне работоспособен. Для правильного решения возникшей проблемы необходимо написать собственный вариант функции sscanf, выполняющий правильный разбор способов задания MAC- и IP-адресов, но автор попытался сохранить этот код разумно компактным и простым: char errbuf[255]; int do checksum = 0; int verbose = 0; int i = 0;

Установка значений по умолчанию. Одна важная особенность, присущая всем программам, заключается в задании их поведения по умолчанию. Тем самым минимизируется объем знаний, необходимых программе во время ее первого запуска. Например, Web-серверам не обязательно указывать имя домашней страницы всякий раз, когда кто-либо подключается к http://www.host.com. По умолчанию если не указано ничего другого, то при подключении по этому адресу пользователю возвращается ответ, как если бы он запросил http://www.host.com/index.html. Точно так же следует установить значения по умолчанию для маршрутизации пакетов:

/* Set Broadcast MAC to FF:FF:FF:FF:FF:FF*/ bcast_mac[0] = OxFF;
bcast_mac[l] = OxFF;
bcast_mac[2] = OxFF;
bcast_mac[3] = OxFF;
bcast_mac[4] = OxFF;
bcast_mac[5] = OxFF;

Иногда выбор установленных по умолчанию значений не представляет большого труда. Основные стандарты Ethernet определяют, что при задании в пакетах МАС-адреса FF: FF: FF: FF: FF: FF эти пакеты должны получить все хосты данной подсети. Локальная сеть на основе протокола Ethernet только недавно стала переключаемой средой, поэтому ранее использование адреса FF: FF: FF: FF: FF: FF больше носило характер «рекомендательного» сообщения для сетевых плат, которые должны были передать этот пакет операционной системе даже в том случае, если это сообщение не было адресовано определенному хосту. Ныне сетевые платы не видят сетевой трафик до тех пор, пока переключатель не посчитает, что он предназначен заданному хосту. В программе широковещательная рассылка МАС-адресов осуществляется следующим образом. Во многих протоколах предусмотрен запрос ко всем хостам локальной подсети. Для наших целей наиболее уместен протокол ARP:

/* Set Default Userspace MAC Address to 00:E0:B0:B0:D0:D0 */ user_mac[0] = 0x00;
user_mac[l] = OxEO;
user_mac[2] = OxBO;
user_mac[3] = OxBO;
user_mac[4] = OxDO;
user_mac[5] = OxDO;

Покажем, как можно в сети создать виртуальную сетевую карту, определив по умолчанию ее сетевой адрес отправителя. В действительности можно использовать любой адрес. Тривиальным и зачастую хорошим решением была бы рандомизация этого значения. Но рандомизация подразумевает, что нельзя будет по желанию запускать и останавливать маршрутизатор. Каждый раз при старте маршрутизатора в фоновом режиме хосты должны будут повторно назначить IP-адрес шлюза. Для этого им нужно будет заняться поиском новых обслуживаемых МАС-адресов. (Если читатель решит реализовать рандомизацию, то ему следует позаботиться о том, чтобы младшие значащие биты первого байта user_mac[0] не были установлены. А если они будут установлены, то в результате будет получен групповой МАС-адрес в локальной сети, использование которого приводит к очень интересным результатам.)

/* Set Default Upstream IP */ upstream_ip[0] = 10; upstream_ip[l] = 0; upstream_ip[2] = 1; upstream_ip[3] = 254;

Програма DoxRoute не является законченной реализацией маршрутизатора. Это лишь его скелет. Фактически пакеты только отсылаются реальному шлюзу. Исходя из опыта, адрес 10.0.1.254 обычно используется для шлюзования пакетов частных сетей, в которых должна быть выполнена программа DoxRoute. Кстати, вовсе не случайно переменной user ip не устанавливается значение по умолчанию. Причина подобных действий известна как политика добрососедства: когда это возможно, то не следует рушить существующих систем. Любой отправленный IP-адрес может иметь вполне определенный смысл для уже развернутых систем. Вместо этого пусть пользователь найдет свободный IP-адрес и займется анализом проходящего через него сетевого трафика. Более сложная реализация предусматривала бы для нахождения свободного адреса использование протокола динамической конфигурации хоста DHCP, но это наложило бы довольно серьезные ограничения для клиентов, пожелавших направить сетевой трафик через отдельный мобильный маршрутизатор.

/* Set Default Interface */ snprintf(dev, sizeof(dev), “%s”, pcap_lookupdev(NULL));

В оперативной странице руководства сказано, что «рсар lookupdevQ возвращает указатель на сетевое устройство, который может быть использован функциями рсар open live () и рсар lookupnetQ. В случае ошибки возвращается значение NULL и в переменную errbuf записывается соответствующее сообщение об ошибке». Это немного непонятно. На самом деле возвращается указатель на строку, содержащую имя устройства, которую мы покорно запоминаем для возможного будущего использования. Командная строка: использование параметров командной строки для того, чтобы избежать жестко запрограммированных зависимостей. Ах, функция getopt. Эта стандартная функция очень полезна для разбора командной строки в стиле UNIX. Но ее работа не столь понятна, как, допустим, написание программ с ее помощью. Пример добротного использования функции getopt приведен ниже:

/* Parse Options */ while ((opt = getopt(argc, argv, «i:r:R:m:cv»)) != EOF) {
switch (opt) {
case “i”: /* Interface */
snprintf(dev, sizeof(dev), “%s”, optarg);
break;
case “v”:
verbose = 1;
break;

Устанавливается цикл разбора всех параметров командной строки. Переменной цикла является счетчик аргументов, который каждый раз уменьшается на единицу и который указывает на первый найденный аргумент командной строки. Кроме того, задается строка, определяющая анализируемые флаги. В любой командной строке программы различают два основных вида параметров. Первый задает дополнительные аргументы, как, например, doxroute - i ethO. Второй является полностью законченным и самодостаточным, как, например, doxroute -v. Функция getopt представляет оба эти типа параметров как i: v. Двоеточие после i является признаком анализируемого аргумента, а указатель optarg должен указывать на аргумент. Отсутствие двоеточия после v означает, что простое присутствие флажка является достаточным поводом для завершения работы (в этом случае для большинства приложений установка глобальной переменной в единицу активизирует генерацию диагностики):

case “г”: /* Router IP */ sscanf(optarg, “%hu.%hu.%hu.%hu”,

&upstream_ip[0], &upstream_ip[l],
&upstream_ip[2],
&upstream_ip[3]);
break;
case “R”: /* Router MAC */ sscanf(optarg, “%X:%X:%X:%X:%X:%X”,
&upstream_mac[0], &upstream_mac[ 1 ],
&upstream_mac[2],
&upstream_mac[3], &upstream_mac[4],
&upstream_mac[5]);
break;
case “m”: /* Userspace MAC */ sscanf(optarg, “%X:%X:%X:%X:%X:%X”,
&user_mac[0], &user_mac[l], &user_mac[2],
&user_mac[3], &user_mac[4],
&user_mac[5]);
break;

Для анализа адресов применены не самые хорошие способы, но тем не менее они работают. Такой способ решения был выбран для того, чтобы противостоять взлому из-за ошибок обработки типов:

case “с”: /* Checksum */ do_checksum = 1;

break;
default:
usageO;
}
}
/* Retrieve Userspace IP Address */ if (argv[optind] != NULL) { sscanf(argv[optind], “%hu.%hu.%hu.%hu”,
&user_ip[0], &user_ip[l], &user_ip[2],
&user_ip[3]);
} else usageO;

Чего функция getopt не может предусмотреть, так это отсутствия флажков. Другими словами, ситуацию отсутствия флажков следует предусмотреть именно в этом месте. Здесь же (в функции usage) можно затребовать наиболее важные данные для работы программы -реализовать тайный прием IP-адресов. Следует отметить, что, как правило, функция usageQ почти всегда завершает программу с флагом ошибки. Обычно это свидетельствует о неправильных действиях пользователя и необходимости вызова RTFM для уточнения ошибки. Запуск Libpcap. Следующее, что потребуется сделать для подготовки к фактическому мониторингу сети с целью поиска интересного трафика, - это спланировать свою реакцию:

/* Begin sniffing */ рсар = pcap_open_live(dev, 65535, promise, 5, NULL);

if (pcap == NULL) {
perror(“pcap_open_live”);
exit(EXITFAILURE);
}

При отсутствии ошибок открывается окно главного интерфейса с указанием спецификаций максимально возможного захвата без учета размера захватываемых данных. Перехватываются все доступные этому интерфейсу пакеты независимо от того, адресованы они одобренному ядром операционной системы МАС-адресу или нет. Для синтаксического анализа пакетов используется минимальная задержка, понижающая риск возможных ошибок:

if (ioctl(pcap_fileno(pcap), BIOCIMMEDIATE, &immediate)) { /*perror(“Couldn’t set BPF to Immediate Mode.”); */
}

Прежде чем пакет будет передан на обработку, устанавливается задержка 5 мс. Это специально сделано для успешного завершения обработки пакета на платформах с недостаточной скоростью работы. Быстродействие - это хорошо, но в действительности гораздо интереснее иметь дело с каждым пакетом в момент его поступления. Сказанное Linux выполняет в любом случае, но операционные системы типа BSD и, возможно, некоторые другие платформы для определения режима Immediate Mode используют опцию управления вводом / выводом IOCTL. Этот режим является своего рода отдаленным родственником опции сокета TCPNODELAY, которая вынуждает обрабатывать каждый сегмент данных настолько быстро, насколько это возможно, в противоположность тому, когда только определенное количество данных может передаваться на следующий уровень обработки. Опция IOCTL настолько сильно улучшает производительность, что просто непонятно, каким образом на некоторых платформах можно обходиться без нее. В целом флажок BIOCIMMliDIA ТЕ сообщает библиотеке libpcap о необходимости блокировки чтения и установке буфера минимально возможного размера. При этом гарантируется максимальное время обработки пакетов маршрутизатором. Это хорошая вещь.

Некоторые платформы могут жаловаться о посылке им опции IOCTL. Поэтому если читатель захочет узнать, присуща ли этой строчке кода ошибка или нет, то пусть он раскомментирует закомментированный раздел:

/* * Create the filter to catch ARP requests, ICMP’s, and routable
* packets.
*/
snprintf(pfprogram, sizeof(pfprogram), “arp or icmp or ether dst %hX:%hX:%hX:%hX:%hX:%hX”, user_mac[0], user_mac[l], user_mac[2],
user_mac[3], user_mac[4], user_mac[5]);
/* Compile and set a kernel-based packet filter*/
if (pcap_compile(pcap, &fp, pfprogram, 1, 0x0) == -1) { pcap_perror(pcap, “pcapcompile”); exit(EXITFAILURE);
}
if (pcap_setfilter(pcap, &fp) == -1) { pcap_perror(pcap, “pcap setfilter”); exit(EXITFAILURE);
}

Наличие возможности откликнуться на все видимые пакеты еще не означает, что это действительно нужно сделать. Нет никакой нужды анализировать весь трафик, и так добросовестно обрабатываемый ядром операционной системы! Поэтому сначала настроим фильтр, используя функцию snprintf. Только теперь, после завершения функции getopt, можно фильтровать пакеты, предназначенные для заданного МАС-адреса. Поэтому перед тем как прослушать трафик, надо знать свой МАС-адрес. Простой способ компиляции и активизации правил фильтрации был показан в предшествующем коде. Реализовать описанный способ непросто. Успех его реализации зависит от элегантности и доступности интерфейса программного кода ядра, написанного другими людьми с соблюдением требований переносимости с одной платформы на другую. Позднее будет осуществлен поиск пакетов специфического типа. Любая подсказка, которая сможет пролить свет на загрузку анализатора пакетов, будет полезной. Дареному коню в зубы не смотрят и все такое прочее.

С этого момента, наконец, появляется возможность приступить к перехвату пакетов.

Noa.o Libnet. /* Get Direct Connection To The Interface */
if ((1 = libnet_open_link_interface(dev, errbuf)) == NULL) {
fprintf(stderr, “Libnet failure opening link
interface: %s”,
errbuf);
}

Интерфейс связи предоставляет пользователю способ получения необработанных пакетов сразу же после прихода их по линии связи. Libpcap позволяет выбирать необработанные пакеты, a libnet - отправлять их. Подобная симметричность двух программных средств очень полезна. Чуть позже это станет видно лучше. Но все упирается в цену успеха. Возможность определить адрес аппаратных средств, которым посылаются данные, означает отсутствие какой-либо помощи со стороны ядра операционной системы. Обычно ядро само определяет адрес аппаратного средства, которому пользователь собирается послать сообщение. В противном случае пользователь должен все делать самостоятельно. Это раздражает во время попыток переслать пакеты случайным хостам подсети, потому что приходится вручную управлять маршрутизацией, ARP-запросами и т. д. Промежуточный способ посылки пакетов позволяет сохранить за ядром операционной системы ответственность за передачу данных на уровне канала передачи данных, который отвечает за прием и передачу пакетов, сервис на уровне дэйтаграмм, локальную адресацию и контроль ошибок. Но при этом приложению предоставляется разумная свобода действий на сетевом и более высоких уровнях. Этот интерфейс известен как непосредственный интерфейс сокетов без какой-либо обработки. К нему можно обратиться при помощи слегка измененного способа вызова libnet. Но в интересах написания программ маршрутизации необходим непосредственный интерфейс связи с библиотекой, поскольку не всегда следует направлять пакеты туда, где обычно размещается системное ядро.

Прелести монокультуры: темные стороны работы в ie web | Защита от хакеров корпоративных сетей | Генерация пакета: поиск следующего «прыжка».


Защита от хакеров корпоративных сетей



Новости за месяц

  • Июнь
    2019
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс