Как с помощью wireshark проверить порт. Wireshark: классика анализа сетевых пакетов. Другие примеры фильтров

Оригинал: Network sniffing
Автор: Paul Cobbaut
Дата публикации: 12 марта 2015 г.
Перевод: A. Панин
Дата перевода: 1 апреля 2015 г.

Глава 23. Перехват сетевого трафика

Администратор сети должен уметь работать со сниффером, таким, как wireshark или tcpdump , для диагностирования проблем сети.

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

23.1. Приложение wireshark

23.1.1. Установка wireshark

В данном примере приведена команда для установки приложения wireshark в дистрибутивах, использующих пакеты программного обеспечения с расширением.deb (включая Debian, Mint, Xubuntu и другие дистрибутивы).

Root@debian8:~# Чтение списков пакетов Готово Построение дерева зависимостей Чтение информации о состоянии Готово... (вывод сокращен)

В дистрибутивах, использующих пакеты программного обеспечения с расширением.rpm , таких, как CentOS, RHEL и Fedora, для установки приложения wireshark может использоваться утилита yum .

# yum install wireshark Loaded plugins: fastestmirror Loading mirror speeds from cached hostfile ... (вывод сокращен)

23.1.2. Выбор сетевого интерфейса

При запуске приложения wireshark в первый раз вам придется выбрать сетевой интерфейс. Вы увидите диалог, который выглядит аналогично приведенному на иллюстрации ниже.

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

Или же вы можете последовать общим рекомендациям и использовать утилиту tcpdump или какой-либо другой инструмент для перехвата трафика и записи данных в файл. Любые перехваченные данные могут быть проанализированы позднее с помощью приложения wireshark .

23.1.3. Минимизация трафика

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

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

И все же более важным инструментом для минимизации трафика являются фильтры, которые будут обсуждаться в следующем разделе.

23.1.4. Перехват трафика, генерируемого утилитой ping

Я запустил сниффер и захватил все пакеты, переданные по сети в результате исполнения трех команд ping (не имеет смысла выполнять эти команды от лица пользователя root):

Root@debian7:~# ping -c2 ns1.paul.local PING ns1.paul.local (10.104.33.30) 56(84) bytes of data. 64 bytes from 10.104.33.30: icmp_req=1 ttl=64 time=0.010 ms 64 bytes from 10.104.33.30: icmp_req=2 ttl=64 time=0.023 ms --- ns1.paul.local ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1001ms rtt min/avg/max/mdev = 0.010/0.016/0.023/0.007 ms root@debian7:~# ping -c3 linux-training.be PING linux-training.be (188.93.155.87) 56(84) bytes of data. 64 bytes from antares.ginsys.net (188.93.155.87): icmp_req=1 ttl=56 time=15.6 ms 64 bytes from antares.ginsys.net (188.93.155.87): icmp_req=2 ttl=56 time=17.8 ms 64 bytes from antares.ginsys.net (188.93.155.87): icmp_req=3 ttl=56 time=14.7 ms --- linux-training.be ping statistics --- 3 packets transmitted, 3 received, 0% packet loss, time 2003ms rtt min/avg/max/mdev = 14.756/16.110/17.881/1.309 ms root@debian7:~# ping -c1 centos7.paul.local PING centos7.paul.local (10.104.33.31) 56(84) bytes of data. 64 bytes from 10.104.33.31: icmp_req=1 ttl=64 time=0.590 ms --- centos7.paul.local ping statistics --- 1 packets transmitted, 1 received, 0% packet loss, time 0ms rtt min/avg/max/mdev = 0.590/0.590/0.590/0.000 ms

В общей сложности из сети было захвачено более чем 200 пакетов. Все станет гораздо очевиднее в том случае, если введете строку icmp в поле фильтра и нажмете кнопку "Применить" ("Apply").

23.1.5. Перехват трафика, генерируемого утилитой ping и клиентом dns

Работая с той же сессией захвата данных, применим отличный фильтр. Мы хотим отслеживать трафик, относящийся как к протоколу dns , так и к протоколу icmp , поэтому нам придется ввести названия двух упомянутых протоколов в поле фильтра.

Для захвата данных, относящихся к двум рассматриваемым протоколам, в поле фильтра должна быть введена строка "dns or icmp" . В случае ввода строки "dns and icmp" не будет выведено информации о каких-либо пакетах, так как не существует пакетов, относящихся к обоим упомянутыми протоколам.

При рассмотрении приведенной выше иллюстрации можно заметить, что пакеты 25 и 26 имеют исходные и целевые IP-адреса 10.104.33.30. Это объясняется тем, что клиент DNS работает на том же компьютере, что и сервер DNS.

Аналогичная ситуация наблюдается и в случае пакетов 31 и 32, ведь с помощью утилиты ping осуществляется отправка пакетов рабочей системе, на которой запущена данная утилита.

23.1.6. Определенный IP-адрес

В данном случае осуществляется фильтрация пакетов, относящихся к протоколу DNS и содержащих определенный IP-адрес. В качестве фильтра используется строка "ip.addr==10.104.33.30 and dns" . Директива and сообщает приложению о том, что следует выводить информацию о каждом пакете, соответствующем двум условиям.

Пакет 93 содержит запрос DNS , направленный на получение записи типа A домена linux-training.be. Пакет 98 содержит ответ от сервера DNS . Как вы думаете, что происходило после отправки пакета 93 и до приема пакета 98? Попытайтесь ответить на этот вопрос перед чтением следующего раздела (при работе с различными системами всегда полезно пытаться предсказывать наступающие события и проверять корректность своих предсказаний).

23.1.7. Фильтрация на основе фреймов

Корректным термином, используемым для обозначения перехваченного пакета, является термин фрейм (из-за того, что мы осуществляем перехват пакетов на уровне 2 сетевой модели OSI). Таким образом, для вывода информации о пакетах с определенными номерами, следует использовать директиву frame.number в поле фильтра.

23.1.8. Исследование содержимого пакетов

Средняя панель окна сниффера может быть раскрыта. При выборе строки в рамках данной панели вы можете увидеть соответствующие значения байт в поле нижней панели.

На иллюстрации ниже показана средняя панель окна сниффера с выбранным адресом моего ноутбука.

Учтите, что описанная выше техника отлично работает при перехвате трафика, передаваемого через один сетевой интерфейс. Если же вы перехватываете трафик, к примеру, с помощью команды tcpdump -i any , вы столкнетесь с методом перехвата пакетов "Linux cooked capture" .

23.1.9. Другие примеры фильтров

Вы можете комбинировать два описания протоколов с помощью директивы логической операции or ("ИЛИ"), расположенной между ними. На иллюстрации ниже показан способ захвата исключительно пакетов, относящихся к протоколам ARP и BOOTP (или DHCP).

А на следующей иллюстрации показан способ перехвата пакетов, относящихся к протоколу DNS и содержащих определенный IP-адрес.

23.2. Утилита tcpdump

В случае работы с интерфейсом командной строки системы перехват пакетов может осуществляться с помощью утилиты tcpdump . Ниже приведены некоторые примеры ее использования.

При использовании команды tcpdump host $ip будет выводиться информация обо всем трафике, относящимся к определенному узлу (в данном случае с IP-адресом 192.168.1.38).

Root@ubuntu910:~# tcpdump host 192.168.1.38 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes

Перехват трафика, относящегося исключительно к протоколу ssh (протокол TCP, порт 22), может осуществляться с помощью команды tcpdump tcp port $порт. Длина строк вывода урезана до 76 символов для более удобного чтения.

Root@deb503:~# tcpdump tcp port 22 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 96 bytes 14:22:20.716313 IP deb503.local.37973 > rhel53.local.ssh: P 666050963:66605 14:22:20.719936 IP rhel53.local.ssh > deb503.local.37973: P 1:49(48) ack 48 14:22:20.720922 IP rhel53.local.ssh > deb503.local.37973: P 49:113(64) ack 14:22:20.721321 IP rhel53.local.ssh > deb503.local.37973: P 113:161(48) ack 14:22:20.721820 IP deb503.local.37973 > rhel53.local.ssh: . ack 161 win 200 14:22:20.722492 IP rhel53.local.ssh > deb503.local.37973: P 161:225(64) ack 14:22:20.760602 IP deb503.local.37973 > rhel53.local.ssh: . ack 225 win 200 14:22:23.108106 IP deb503.local.54424 > ubuntu910.local.ssh: P 467252637:46 14:22:23.116804 IP ubuntu910.local.ssh > deb503.local.54424: P 1:81(80) ack 14:22:23.116844 IP deb503.local.54424 > ubuntu910.local.ssh: . ack 81 win 2 ^C 10 packets captured 10 packets received by filter 0 packets dropped by kernel

Та же операция, но с записью захваченных данных в файл, может осуществляться с помощью команды tcpdump -w $имя_файла.

Root@ubuntu910:~# tcpdump -w sshdump.tcpdump tcp port 22 tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes ^C 17 packets captured 17 packets received by filter 0 packets dropped by kernel

С помощью команды tcpdump -r $имя_файла может быть выведено содержимое файла, созданного в предыдущем примере.

Root@ubuntu910:~# tcpdump -r sshdump.tcpdump

Множество других примеров использования рассматриваемой утилиты может быть найдено на странице руководства man tcpdump .

23.3. Практическое задание: перехват сетевого трафика

23.4. Корректная процедура выполнения практического задания: перехват сетевого трафика

1. Установите приложение wireshark в вашу систему (работающую не в виртуальной машине).

В дистрибутивах Debain/Ubuntu: aptitude install wireshark

В дистрибутивах Red Hat/Mandriva/Fedora: yum install wireshark

2. Используйте утилиту ping генерации трафика между вашим и каким-либо другим компьютером.

Ping $ip_адрес

3. Начните перехват сетевого трафика.

(sudo) wireshark

Выберите сетевой интерфейс (вероятно, eth0)

4. С помощью фильтра осуществите вывод информации исключительно о тех пакетах, которые содержат ответы на запросы от утилиты ping.

Введите "icmp" (без кавычек) в поле фильтра и нажмите кнопку "Применить" ("Apply").

5. Теперь передайте утилите ping имя домена (такое, как www.linux-training.be) и попытайтесь перехватить пакеты с запросом и ответом DNS. Какой DNS-сервер был использован? Был ли использован протокол TCP или UDP для передачи запроса и ответа?

В первую очередь запустите сниффер.

Введите "dns" в поле фильтра и нажмите кнопку "Применить" ("Apply").

Root@ubuntu910:~# ping www.linux-training.be PING www.linux-training.be (88.151.243.8) 56(84) bytes of data. 64 bytes from fosfor.openminds.be (88.151.243.8): icmp_seq=1 ttl=58 time=14.9 ms 64 bytes from fosfor.openminds.be (88.151.243.8): icmp_seq=2 ttl=58 time=16.0 ms ^C --- www.linux-training.be ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1002ms rtt min/avg/max/mdev = 14.984/15.539/16.095/0.569 ms

Окно приложения wireshark должно выглядеть аналогичным образом.

На основе информация из окна приложения wireshark можно сделать вывод о том, что запрос DNS передавался с помощью пакета UDP, после чего несложно дать ответы на поставленные вопросы.

6. Найдите закрытый вебсайт, имеющий форму запроса пароля. Попытайтесь войти на него, использовав имя пользователя "paul" и пароль "hunter2" в процессе работы сниффера. Теперь попытайтесь найти введенные имя пользователя и пароль в захваченных с помощью сниффера данных.

У каждого из команды ][ свои предпочтения по части софта и утилит для
пен-теста. Посовещавшись, мы выяснили, что выбор так разнится, что можно
составить настоящий джентльменский набор из проверенных программ. На том и
решили. Чтобы не делать сборную солянку, весь список мы разбили на темы – и в
этот раз коснемся утилит для снифинга и манипулирования пакетами. Пользуйся на
здоровье.

Wireshark

Netcat

Если говорить о перехвате данных, то Network Miner снимет с «эфира»
(или из заранее подготовленного дампа в PCAP-формате) файлы, сертификаты,
изображения и другие медиа, а также пароли и прочую инфу для авторизации.
Полезная возможность - поиск тех участков данных, что содержат ключевые слова
(например, логин пользователя).

Scapy

Сайт:
www.secdev.org/projects/scapy

Must-have для любого хакера, представляющий собой мощнейшую тулзу для
интерактивной манипуляции пакетами. Принять и декодировать пакеты самых
различных протоколов, ответить на запрос, инжектировать модифицированный и
собственноручно созданный пакет - все легко! С ее помощью можно выполнять целый
ряд классических задач, вроде сканирования, tracorute, атак и определения
инфраструктуры сети. В одном флаконе мы получаем замену таких популярных утилит,
как: hping, nmap, arpspoof, arp-sk, arping, tcpdump, tetheral, p0f и т.д. В то
же самое время Scapy позволяет выполнить любое, даже самое специфическое
задание, которое никогда не сможет сделать уже созданное другим разработчиком
средство. Вместо того чтобы писать целую гору строк на Си, чтобы, например,
сгенерировать неправильный пакет и сделать фаззинг какого-то демона, достаточно
накидать пару строчек кода с использованием Scapy ! У программы нет
графического интерфейса, а интерактивность достигается за счет интерпретатора
Python. Чуть освоишься, и тебе уже ничего не будет стоить создать некорректные
пакеты, инжектировать нужные фреймы 802.11, совмещать различные подходы в атаках
(скажем, ARP cache poisoning и VLAN hopping) и т.д. Разработчики сами настаивают
на том, чтобы возможности Scapy использовались в других проектах. Подключив ее
как модуль, легко создать утилиту для различного рода исследования локалки,
поиска уязвимостей, Wi-Fi инжекции, автоматического выполнения специфических
задач и т.д.

packeth

Сайт:
Платформа: *nix, есть порт под Windows

Интересная разработка, позволяющая, с одной стороны, генерировать любой
ethernet пакет, и, с другой, отправлять последовательности пакетов с целью
проверки пропускной способности. В отличие от других подобных тулз, packeth
имеет графический интерфейс, позволяя создавать пакеты в максимально простой
форме. Дальше - больше. Особенно проработано создание и отправка
последовательностей пакетов. Ты можешь устанавливать задержки между отправкой,
слать пакеты с максимальной скоростью, чтобы проверить пропускную способность
участка сети (ага, вот сюда-то и будут ддосить) и, что еще интереснее -
динамически изменять параметры в пакетах (например, IP или MAC-адрес).


В этом уроке описаны технологии сетевого хакинга, основанные на перехвате сетевых пакетов. Хакеры используют такие технологии для прослушивания сетевого трафика с целью хищения ценной информации, для организации перехвата данных с целью атаки «человек посредине», для перехвата TCP-соединений, позволяющих, скажем, подменять данные, и выполнения других, не менее интересных действий. К сожалению, большая часть этих атак на практике реализована только для сетей Unix, для которых хакеры могут использовать как специальные утилиты, так и системные средства Unix. Сети Windows, по всей видимости, обойдены вниманием хакеров, и мы вынуждены ограничиться при описании инструментов перехвата данных программами-сниферами, предназначенными для тривиального прослушивания сетевых пакетов. Тем не менее, не следует пренебрегать хотя бы теоретическим описанием таких атак, особенно антихакерам, поскольку знание применяемых технологий хакинга поможет предотвратить многие неприятности.

Сетевой снифинг

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

Для демонстрации технологии снифинга мы применим весьма популярную программу-снифер SpyNet , которую можно найти на многих Web-сайтах. Официальный сайт программы SpyNet находится по адресу http://members.xoom.com/layrentiu2/ , на котором можно загрузить демо-версию программы.

Программа SpyNet состоит из двух компонентов - CaptureNet и PipeNet . Программа CaptureNet позволяет перехватывать пакеты, передаваемые по сети Ethernet на сетевом уровне, т.е. в виде кадров Ethernet. Программа PipeNet позволяет собирать кадры Ethernet в пакеты уровня приложений, восстанавливая, например, сообщения электронной почты, сообщения протокола HTTP (обмен информацией с Web-сервером) и выполнять другие функции.

К сожалению, в демо-версии SpyNet возможности PipeNet ограничены демонстрационным примером сборки пакета HTTP, так что мы не сможем продемонстрировать работу SpyNet в полном объеме. Однако мы продемонстрируем возможности сетевого снифинга SpyNet на примере нашей экспериментальной сети, передав текстовый файл с хоста Sword-2000 на хост Alex-З с помощью обычного проводника Windows. Одновременно на компьютере А1ех-1 мы запустим программу CaptureNet , которая перехватит переданные пакеты и позволит прочитать содержимое переданного файла в кадрах Ethernet. На Рис. 1 представлен текст секретного сообщения в файле secret.txt ; мы постараемся найти этот текст в перехваченных кадрах Ethernet.

Рис. 1. Текст секретного сообщения в окне Notepad

Для перехвата кадров Ethernet выполните такие действия.

На компьютере Alex-З запустите программу CaptureNet . В отобразившемся рабочем окне программы выберите команду меню Capture * Start (Захват * Запуск) и запустите процесс перехвата сетевых кадров.

Средствами проводника Windows скопируйте файл security.txt с компьютера Sword-2000 на А1ех-3 .

После передачи файла secret.txt выберите команду меню Capture * Stop (Захват * Стоп) и остановите процесс перехвата.

Перехваченные кадры Ethernet отобразятся в правой части рабочего окна программы CaptureNet (Рис. 2), причем каждая строка в верхнем списке представляет кадр Ethernet, а под списком отображается содержимое выбранного кадра.

Рис. 2. Кадр Ethernet содержит текст секретного сообщения

Просмотрев список перехваченных кадров, мы без труда найдем тот из них, который содержит переданный нами текст This is a very big secret (Это очень большой секрет).

Подчеркнем, что это - самый простой пример, когда записывался весь перехваченный сетевой трафик. Программа CaptureNet позволяет перехватывать пакеты, пересылаемые по определенным протоколам и на определенные порты хостов, выбирать сообщения с определенным содержимым и накапливать перехваченные данные в файле. Техника выполнения таких действий несложна, и ее можно освоить по справочной системе программы SpyNet .

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

Методы перехвата сетевого трафика

Прослушиванце сети с помощью программ сетевых анализаторов, подобных приведенной выше CaptureNet , является первым, самым простым способом перехвата данных. Кроме SpyNet для снифинга сетей используется множество инструментов, изначально разрабатываемых для целей анализа сетевой активности, диагностирования сетей, отбора трафика по указанным критериям и других задач сетевого администрирования. В качестве примера такой программы можно назвать tcpdump (http://www.tcpdump.org ), которая позволяет записывать сетевой трафик в специальный журнал для последующего анализа.

Для защиты от прослушивания сети применяются специальные программы, например, AntiSniff (http://www.securitysoftwaretech.com/antisniff ), которые способны выявлять в сети компьютеры, занятые прослушиванием сетевого трафика. Программы-антисниферы для решения своих задач используют особый признак наличия в сети прослушивающих устройств - сетевая плата компьютера-снифера должна находиться в специальном режиме прослушивания. Находясь в режиме прослушивания, сетевые компьютеры особенным образом реагируют на IР-дейтаграммы, посылаемые в адрес тестируемого хоста. Например, прослушивающие хосты, как правило, обрабатывают весь поступающий трафик, не ограничиваясь только посланными на адрес хоста дейтаграммами. Имеются и другие признаки, указывающие на подозрительное поведение хоста, которые способна распознать программа AntiSniff .

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

Ложные запросы ARP

Чтобы перехватить и замкнуть на себя процесс сетевого взаимодействия между двумя хостами А и В злоумышленник может подменить IР-адреса взаимодействующих хостов своим IP-адресом, направив хостам А и В фальсифицированные сообщения ARP (Address Resolution Protocol - Протокол разрешения адресов). С протоколом ARP можно познакомиться в Приложении D, где описана процедура разрешения (преобразования) IP-адреса хоста в адрес машины (МАС-адрес), зашитый в сетевую плату хоста. Посмотрим, как хакер может воспользоваться протоколом ARP для выполнения перехвата сетевого взаимодействия между хостами А и В.

Для перехвата сетевого трафика между хостами А и В хакер навязывает этим хостам свой IP-адрес, чтобы А и В использовали этот фальсифицированный IP-адрес при обмене сообщениями. Для навязывания своего IР-адреса хакер выполняет следующие операции.

Злоумышленник определяет МАС-адреса хостов А и В, например, с помощью команды nbtstat из пакета W2RK .

Злоумышленник отправляет на выявленные МАС-адреса хостов А и В сообщения, представляющие собой фальсифицированные ARP-ответы на запросы разрешения IP-адресов хостов в МАС-адреса компьютеров. Хосту А сообщается, что IР-адресу хоста В соответствует МАС-адрес компьютера злоумышленника; хосту В сообщается, что IP-адресу хоста А также соответствует МАС-адрес компьютера злоумышленника.

Хосты А и В заносят полученные МАС-адреса в свои кэши ARP и далее используют их для отправки сообщений друг другу. Поскольку IР-адресам А и В соответствует МАС-адрес компьютера злоумышленника, хосты А и В, ничего не подозревая, общаются через посредника, способного делать с их посланиями что угодно.

Для защиты от таких атак сетевые администраторы должны поддерживать базу данных с таблицей соответствия МАС-адресов и IP-адресов своих сетевых компьютеров. Далее, с помощью специального программного обеспечения, например, утилиты arpwatch (ftp://ftp.ee.lbl.gov/arpwatch-2.lab.tar.gz ) можно периодически обследовать сеть и выявлять несоответствия.

В сетях UNIX такого рода атаку ложными запросами ARP можно реализовать с помощью системных утилит отслеживания и управления сетевым трафиком, например, arpredirect . К сожалению, в сетях Windows 2000/XP такие надежные утилиты, по-видимому, не реализованы. Например, на сайте NTsecurity (http://www.ntsecurity.nu ) можно загрузить утилиту GrabitAII , представленную как средство для перенаправления трафика между сетевыми хостами. Однако элементарная проверка работоспособности утилиты GrabitAII показывает, что до полного успеха в реализации ее функций еще далеко.

Ложная маршрутизация

Чтобы перехватить сетевой трафик, злоумышленник может подменить реальный IP-адрес сетевого маршрутизатора своим IP-адресом, выполнив это, например, с помощью фальсифицированных ICMP-сообщений Redirect. Полученное сообщение Redirect хост А должен, согласно документу RFC-1122, воспринять как ответ на дейтаграмму, посланную другому хосту, например, В. Свои действия на сообщение Redirect хост А определяет, исходя из содержимого полученного сообщения Redirect, и если в Redirect задать перенаправление дейтаграмм из А в В по новому маршруту, именно это хост А и сделает.

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

Для защиты от такой атаки следует отключить (например, с помощью брандмауэра) на хосте А обработку сообщений ICMP Redirect, а выявить IP-адрес компьютера злоумышленника может команда tracert (в Unix это команда tracerout). Эти утилиты способны найти появившийся в локальной сети дополнительный, непредусмотренный при инсталляции, маршрут, если конечно администратор сети проявит бдительность.

Приведенное выше примеры перехватов (которыми возможности злоумышленников далеко не ограничиваются) убеждают в необходимости защиты данных, передаваемых по сети, если в данных содержится конфиденциальная информация. Единственным методом защиты от перехватов сетевого трафика является использование программ, реализующих криптографические алгоритмы и протоколы шифрования, и позволяющих предотвратить раскрытие и подмену секретной информации. Для решения таких задач криптография предоставляет средства для шифрования, подписи и проверки подлинности передаваемых по защищенным протоколам сообщений

Практическую реализацию всех описанных в Главе 4 криптографических методов защиты обмена информацией предоставляют сети VPN (Virtual Private Network - Виртуальные частные сети). Краткий обзор принципов и методов криптографической защиты можно найти в Приложении Е, а в приводится подробное описание средств криптографической защиты, предоставляемых приложением PGP Desktop Security (http://www.pgp.com ).

Перехват TCP-соединения

Наиболее изощренной атакой перехвата сетевого трафика следует считать захват TCP-соединения (TCP hijacking), когда хакер путем генерации и отсылки на атакуемых хост TCP-пакетов прерывает текущий сеанс связи с хостом. Далее, пользуясь возможностями протокола TCP по восстановлению прерванного TCP-соединения, хакер перехватывает прерванный сеанс связи и продолжает его вместо отключенного клиента.

Для выполнения атак перехвата TCP-соединения создано несколько эффективных утилит, однако все они реализованы для платформы Unix, и на сайтах Web эти утилиты представлены только в виде исходных кодов. Таким образом, нам, как убежденным практикам в благородном деле хакинга, от атак методом перехвата TCP-соединения проку не много. (Любители разбираться в чужом программном коде могут обратиться к сайту http://www.cri.cz/~kra/index.html , где можно загрузить исходный код известной утилиты перехвата TCP-соединения Hunt от Павла Крауза (Pavel Krauz)).

Несмотря на отсутствие практических инструментов, мы не можем обойти стороной такую интересную тему, как перехват TCP-соединений, и остановимся на некоторых аспектах таких атак. Некоторые сведения о структуре TCP-пакета и порядке установления TCP-соединений приведены в Приложении D этой книги, здесь же основное внимание мы уделим такому вопросу - что же именно позволяет хакерам выполнять атаки перехвата TCP-соединений? Рассмотрим эту тему подробнее, опираясь, в основном, на обсуждение в и .

Протокол TCP (Transmission Control Protocol - Протокол управления передачей) является одним из базовых протоколов транспортного уровня OSI, позволяющим устанавливать логические соединения по виртуальному каналу связи. По этому каналу передаются и принимаются пакеты с регистрацией их последовательности, осуществляется управление потоком пакетов, организовывается повторная передача искаженных пакетов, а в конце сеанса канал связи разрывается. Протокол TCP является единственным базовым протоколом из семейства TCP/IP, имеющим продвинутую систему идентификации сообщений и соединения.

Для идентификации TCP-пакета в TCP-заголовке существуют два 32-разрядных идентификатора, которые также играют роль счетчика пакетов, называемых порядковым номером и номером подтверждения. Также нас будет интересовать еще одно поле TCP-пакета, называемое управляющими битами. Это поле размером 6 бит включает следующие управляющие биты (в порядке слева направо):

URG - флаг срочности;

АСК - флаг подтверждения;

PSH - флаг переноса;

RST - флаг переустановки соединения;

SYN - флаг синхронизации;

FIN - флаг завершения соединения.

Рассмотрим порядок создания TCP-соединения.

1. Если хосту А необходимо создать TCP-соединение с хостом В, то хост А посылает хосту В следующее сообщение:

А -> В: SYN, ISSa

Это означает, что в передаваемом хостом А сообщении установлен флаг SYN (Synchronize sequence number - Номер последовательности синхронизации), а в поле порядкового номера установлено начальное 32-битное значение ISSa (Initial Sequence Number - Начальный номер последовательности).

2. В ответ на полученный от хоста А запрос хост В отвечает сообщением, в котором установлен бит SYN и установлен бит АСК. В поле порядкового номера хост В устанавливает свое начальное значение счетчика - ISSb; поле номера подтверждения будет при этом содержать значение ISSa, полученное в первом пакете от хоста А, увеличенное на единицу. Таким образом, хост В отвечает таким сообщением:

В -> A: SYN, АСК, ISSb, ACK(ISSa+1)

3. Наконец, хост А посылает сообщение хосту В, в котором: установлен бит АСК ; поле порядкового номера содержит значение ISSa + 1 ; поле номера подтверждения содержит значение ISSb + 1 . После этого TCP-соединение между хостами А и В считается установленным:

А -> В: АСК, ISSa+1, ACK(ISSb+1)

4. Теперь хост А может посылать пакеты с данными на хост В по только что созданному виртуальному TCP-каналу:

А -> В: АСК, ISSa+1, ACK(ISSb+1); DATA

Здесь DATA обозначает данные.

Из рассмотренного выше алгоритма создания TCP-соединения видно, что единственными идентификаторами TCP-абонентов и TCP-соединения являются два 32-битных параметра порядкового номера и номера подтверждения - ISSa и ISSb . Следовательно, если хакеру удастся узнать текущие значения полей ISSa и ISSb , то ему ничто не помешает сформировать фальсифицированный TCP-пакет. Это означает, что хакеру достаточно подобрать текущие значения параметров ISSa и ISSb пакета TCP для данного TCP-соединения, послать пакет с любого хоста Интернета от имени клиента данного TCP-подключения, и данный пакет будет воспринят как верный!

Опасность такой подмены TCP-пакетов важна и потому, что высокоуровневые протоколы FTP и TELNET реализованы на базе протокола TCP, и идентификация клиентов FTP и TELNET-пакетов целиком основана на протоколе TCP.

К тому же, поскольку протоколы FTP и TELNET не проверяют IР-адреса отправителей сообщений, то после получения фальсифицированного пакета серверы FTP или TELNET отправят ответное сообщение по указанному в ложном пакете IP-адресу хакерского хоста. После этого хакерский хост начнет работу с сервером FTP или TELNET со своего IР-адреса, но с правами легально подключившегося пользователя, который, в свою очередь, потеряет связь с сервером из-за рассогласования счетчиков.

Таким образом, для осуществления описанной выше атаки необходимым и достаточным условием является знание двух текущих 32-битных параметров ISSa и ISSb , идентифицирующих TCP-соединение. Рассмотрим возможные способы их получения. В случае, когда хакерский хост подключен к атакуемому сетевому сегменту, задача получения значений ISSa и ISSb является тривиальной и решается путем анализа сетевого трафика. Следовательно, надо четко понимать, что протокол TCP позволяет в принципе защитить соединение только в случае невозможности перехвата атакующим сообщений, передаваемых по данному соединению, то есть только в случае, когда хакерский хост подключен к сетевому сегменту, отличному от сегмента абонента TCP-соединения.

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

Математическое предсказание начального значения параметров TCP-соединения экстраполяцией предыдущих значений ISSa и ISSb .

Использование уязвимостей по идентификации абонентов TCP-соединения на rsh-серверах Unix.

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

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

Заключение

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

Антихакер должен знать, что единственным спасением от перехвата данных является их шифрование, т.е. криптографические методы защиты. Посылая по сети сообщение, следует заранее предполагать, что кабельная система сети абсолютно уязвима, и любой подключившийся к сети хакер сможет выловить из нее все передаваемые секретные сообщения. Имеются две технологии решения этой задачи - создание сети VPN и шифрование самих сообщений. Все эти задачи очень просто решить с помощью пакета программ PGP Desktop Security (ее описание можно найти, например, в ).

Иногда при использовании интернета возникают ситуации, при которых происходит утечка трафика или непредвиденный расход системных ресурсов. Чтобы быстро провести анализ и обнаружить источник проблемы, используют специальные сетевые инструменты. Об одном из них, WireShark, пойдёт речь в статье.

Общая информация

Перед тем, как пользоваться WireShark, нужно ознакомиться с областью её применения, функционалом и возможностями. Вкратце: программа позволяет перехватывать пакеты в режиме реального времени в проводных и беспроводных сетевых подключениях. Применяется в протоколах Ethernet, IEEE 802.11, PPP и аналогичных. Можно использовать и перехват трафика звонков VoIP.

Программа распространяется под лицензией GNU GPL, что означает - бесплатно и с открытым исходным кодом. Можно запустить её на многих дистрибутивах Linux, MacOS, и есть также версия для операционной системы Windows.

Как пользоваться WireShark?

Во-первых, сначала стоит установить её в систему. Так как одним из наиболее часто используемых Linux дистрибутивов является Ubuntu, то и все примеры будут показаны именно в нем.

Для установки достаточно набрать в консоли команду:

sudo apt-get install wireshark

После этого программа появится в главном меню. Можно запустить её оттуда. Но лучше делать это из терминала, так как ей нужны права суперпользователя. Это можно сделать так:

Внешний вид

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

Блок Capture содержит список доступных для захвата сетевых интерфейсов. При выборе, например, eth0 и нажатии кнопки Start запустится процесс перехвата.

Окно с перехватываемыми данными также разделено логически на несколько частей. Сверху находится панель управления с различными элементами. Следом за ним идёт список пакетов. Он представлен в виде таблицы. Здесь можно увидеть порядковый номер пакета, время его перехвата, адрес отправления и получения. Также можно изъять данные об используемых протоколах, длине и других полезных сведений.

Ниже списка расположено окно с содержимым технических данных выбранного пакета. А ещё ниже имеется отображение в шестнадцатеричном виде.

Каждое представление можно развернуть в большом окне для более удобного чтения данных.

Применение фильтров

В процессе работы программы перед пользователем всегда будут пробегать десятки, а то и сотни пакетов. Отсеивать их вручную довольно трудно и долго. Поэтому официальная инструкция WireShark рекомендует использовать фильтры.

Для них есть специальное поле в окне программы — Filter. Чтобы сконфигурировать фильтр более точно, имеется кнопка Expression.

Но для большинства случаев хватит и стандартного набора фильтров:

  • ip.dst — ip адрес назначения пакета;
  • ip.src — адрес отправителя;
  • ip.addr — просто любой ip;
  • ip.proto — протокол.

Использование фильтров в WireShark — инструкция

Чтобы попробовать, как работает программа с фильтрами, нужно в ввести определённую команду. Например, такой набор — ip.dst == 172.217.23.131 - покажет все летящие пакеты на сайт "Гугл". Чтобы просмотреть весь трафик — и входящий и исходящий, - можно объединить две формулы — ip.dst == 172.217.23.131 || ip.src == 172.217.23.131. Таким образом, получилось использовать в одной строке сразу два условия.

Можно использовать и другие условия, например ip.ttl < 10. Данная команда выведет все пакеты с длительностью жизни меньше 10. Чтобы выбрать данные по их размеру, можно применить такой подход — http.content_length > 5000.

Дополнительные возможности

Для удобства в WireShark есть способ быстро выбрать в качестве анализируемого поля параметры пакета. Например, в поле с техническими данными можно щёлкнуть правой кнопкой на нужном объекте и выбрать Apply as Column. Что означает его перевод в область поля в качестве колонки.

Аналогично можно выбрать любой параметр и как фильтр. Для этого в контекстном меню есть пункт Apply as Filter.

Отдельный сеанс

Можно пользоваться WireShark как монитором между двумя узлами сети, например, пользователем и сервером. Для этого нужно выбрать интересующий пакет, вызвать контекстное меню и нажать Follow TCP Stream. В новом окне отобразится весь лог обмена между двумя узлами.

Диагностика

WireShark обладает отдельным инструментом для анализа проблем сети. Он называется Expert Tools. Найти его можно в левом нижнем углу, в виде круглой иконки. По нажатию на ней откроется новое окно с несколькими вкладками — Errors, Warnings и другие. С их помощью можно проанализировать, в каких узлах происходят сбои, не доходят пакеты, и обнаружить прочие проблемы с сетью.

Голосовой трафик

Как уже было сказано, WireShark умеет перехватывать и голосовой трафик. Для этого отведено целое меню Telephony. Это можно использовать для нахождения проблем в VoIP и их оперативного устранения.

Пункт VoIP Calls в меню Telephony позволит просмотреть совершенные звонки и прослушать их.

Экспорт объектов

Это, наверное, самый интересный функционал программы. Он позволяет пользоваться WireShark как перехватчиком файлов, которые передавались по сети. Для этого нужно остановить процесс перехвата и выполнить экспорт HTTP объектов в меню File. В открывшемся окне будет представлен список всех переданных за сессию файлов, которые можно сохранить в удобное место.

В заключение

К сожалению, актуальную версию WireShark на русском языке в сети найти будет трудно. Наиболее доступная и часто используемая есть на английском.

Также обстоят дела и с подробной инструкцией по WireShark на русском. Официальная от разработчика представлена на английском. В сети есть много небольших и кратких руководств по WireShark для начинающих.

Однако тем, кто давно работает в IT сфере, разобраться с программой не представит особых сложностей. А большие возможности и богатый функционал скрасит все трудности при изучении.

Стоит отметить, что в некоторых странах использование сниффера, каковым и является WireShark, может быть противозаконным.

Общая схема

Последовательность шагов, которая должна выполнить программа, использующая библиотеку pcap (от PacketCAPture) для выполнения своей задачи, такова:

  • Определить сетевой интерфейс, который будет прослушиваться. (В Linux это может быть eth0, в BSD xl1).
  • Инициализировать pcap . При этом библиотеке сообщается, на каком интерфейсе мы будем слушать данные. Возможно прослушивание нескольких интерфейсов одновременно (в разных сессиях).
  • В случае необходимости создать фильтр (например, нас интересуют только TCP пакеты, приходящие на порт 23), "скомпилировать" этот фильтр и применить к той или иной сессии.
  • Перейти в цикл приема пакетов. После этого всякий раз, когда приходит очередной пакет и он проходит через указанный фильтр, вызывается функция, которую нужно заранее определить. Эта функция может выполнять любые действия, которые мы захотим. Она может разбирать пакет и выдавать его пользователю, может сохранять его на диск или вообще ничего не делать.
  • По окончании работы нужно закрыть все открытые сессии.

Рассмотрим перечисленные шаги подробно.

Определение интерфейса

Для определения интерфейса, на котором необходимо производить прослушивание, можно воспользоваться двумя способами.

Первый состоит в том, что имя интерфейса задает пользователь. Рассмотрим следующую программу:

#include #include Int main(int argc, char *argv) { char *dev = argv; printf("Device: %s\n", dev); return(0); }

Пользователь указывает интерфейс, передавая его имя через первый аргумент нашей программы. Естественно, указываемый пользователем интерфейс должен существовать.

Второй способ - узнать имя интерфейса у самой библиотеки:

#include #include Int main() { char *dev, errbuf; dev = pcap_lookupdev(errbuf); printf("Device: %s\n", dev); return(0); }

В этом случае pcap передает нам имя интерфейса, которым он владеет. В строку errbuf будет передано описание ошибки, если таковая возникнет при исполнении вызова pcap_lookupdev() .

Открытие интерфейса для перехвата пакетов

Для создания сессии перехвата трафика необходимо вызвать функцию pcap_open_live() . Прототип этой функции (из страницы руководства по pcap) выглядит следующим образом:

Pcap_t *pcap_open_live (char *device, int snaplen, int promisc, int to_ms, char *ebuf)

Первый аргумент - имя устройства, которое мы определили на предыдущем шаге. snaplen - целое число, определяющее максимальное количество байт сетевого кадра, которое будет захватываться библиотекой. Если promisc установлен в true, интерфейс переходит в так называемый promiscuous mode (перехватываются пакеты, адресованные другим станциям сети). to_ms - тайм-аут в миллисекундах (в случае, если значение установлено в ноль, чтение будет происходить до первой ошибки, в минус единицу - бесконечно). Наконец, errbuf - строка, в которую мы получим сообщение об ошибке. Функция возвращает хэндл (дескриптор) сессии.

Для демонстрации рассмотрим фрагмент кода:

#include Pcap_t *handle; handle = pcap_open_live(somedev, BUFSIZ, 1, 0, errbuf);

Здесь открывается интерфейс, имя которого указано в строке somedev , указывается сколько байт пакета захватывать (значение BUFSIZ определено в pcap.h). Сетевой интерфейс переключается в promiscuous режим. Данные будут читаться до тех пор, пока не произойдет ошибка. В случае ошибки можно вывести ее текстовое описание на экран, используя указатель errbuf.

Замечание по поводу перехвата трафика в promiscuous и non-promiscuous режимах: эти два метода очень отличаются. В случае перехвата трафика в non-promiscuous режиме узел получает только тот трафик, который направлен или относится к нему. Только трафик до, от и маршрутизируемый через хост будет перехвачен нашей программой. В promiscuous режиме сетевой интерфейс принимает все пакеты, идущие через кабель. В некоммутируемом окружении это может быть весь сетевой трафик. Его явное преимущество в том, что он предоставляет большее количество пакетов для перехвата, что может быть (или может не быть) полезным, в зависимости от того, для чего вы перехватываете сетевой поток.

Однако, перехват трафика в promiscuous режиме можно обнаружить; другой узел может с высокой точностью определить, используем ли мы promiscuous режим. Кроме того, он работает только в некоммутируемом окружении (таком как концентраторы или коммутаторы, которые затоплены arp пакетами). В третьих, в случае, если сеть сильно загружена, наша программа будет использовать большое количество системных ресурсов.

Фильтрация трафика

Часто перехватчик пакетов нужен для перехвата не всех, а только определенных пакетов. Например, бывают случаи, когда мы хотим перехватывать трафик на 23-тий порт (telnet) в поисках паролей. Или, возможно, мы хотим перехватить файл, которые пересылается по 21-му порту (FTP). Возможно, мы хотим перехватывать только DNS трафик (53-ий порт UDP). В любом случае, очень редко необходимо перехватывать все данные. Для фильтрации трафика предназначены функции pcap_compile() и pcap_setfilter() .

После того, как мы вызвали pcap_open_live() и получили функционирующую сессию перехвата трафика, мы можем применить наш фильтр. Естественно, можно реализовать фильтр вручную, разбирая ETH/IP/TCP заголовки после получения пакета, но использование внутреннего фильтра pcap более эффективно, и кроме того, это проще.

Перед тем тем, как применить фильтр, нужно его "скомпилировать". Выражение для фильтра хранится в обыкновенной строке (массиве символов). Синтаксис таких выражений подробно описан в странице руководства по tcpdump (man tcpdump).

Для компиляции фильтра используется функция pcap_compile() . Ее прототип выглядит следующим образом:

Int pcap_compile(pcap_t *p, struct bpf_program *fp, char *str, int optimize, bpf_u_int32 netmask)

Первый аргумент - хэндл (дескриптор) нашей сессии (pcap_t *handle в предыдущем примере). Следующий аргумент - указатель на область в памяти, где мы будем хранить скомпилированную версию нашего фильтра. Далее идет само выражение фильтра в виде обычной строки. Следующий параметр определяет, нужно ли оптимизировать наше выражение или нет (как обычно, 0 означает "нет", 1 - "да"). Последний параметр - маска сети, к которой применяется наш фильтр. Функция возвращает -1 в случае ошибки, все другие значения говорят о успешном завершении.

После того, как выражение скомпилировано, его нужно применить, что осуществляется с помощью функции pcap_setfilter() . Ее прототип таков:

Int pcap_setfilter(pcap_t *p, struct bpf_program *fp)

Первый аргумент - хэндл(дескриптор) нашей сессии перехвата пакетов, второй - указатель на скомпилированную версию выражения для фильтра (как правило - второй аргумент функции pcap_compile()).

В нижеследующем примере демонстрируется использование фильтра:

#include Pcap_t *handle; // дескриптор сессии char dev = "eth0"; // интерфейс, на котором мы будем слушать char errbuf; // Строка с ошибкой struct bpf_program filter; // Скомпилированное выражение для фильтра сhar filter_app = "port 23"; // Выражение для фильтра bpf_u_int32 mask; // Сетевая маска нашего интерфейса bpf_u_int32 net; // IP адрес нашего интерфейса pcap_lookupnet(dev, &net, &mask, errbuf); handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf); pcap_compile(handle, &filter, filter_app, 0, net); pcap_setfilter(handle, &filter);

Эта программа подготавливает перехватчик для пакетов, идущих на или с 23-го порта, в promiscuous режиме, на интерфейсе eth0. Пример содержит функцию pcap_lookupnet() , которая возвращает сетевой адрес и маску сети для устройства, имя которого передано ей как параметр. Ее использование необходимо, так как для того, чтобы наложить фильтр, мы должны знать адрес и маску сети.

Перехват пакетов

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

U_char *pcap_next(pcap_t *p, struct pcap_pkthdr *h)

Первый аргумент - хэндл нашей сессии, второй - указатель на структуру, в которой будет храниться такая информация о пакете, как время, когда он был перехвачен, длина пакета и длина его отдельной части (например, в случае, если пакет фрагментирован). pcap_next() возвращает указатель u_char на область памяти, где хранится пакет, описанный этой структурой.

Демонстрация использования pcap_next() для перехвата одного пакета:

#include #include int main() { pcap_t *handle; char *dev; char errbuf; // строка с описанием ошибки struct bpf_program filter; // скомпилированный фильтр char filter_app = "port 23"; // фильтр bpf_u_int32 mask; // сетевая маска bpf_u_int32 net; // наш ip адрес struct pcap_pkthdr header; // заголовок пакета, который заполнит pcap const u_char *packet; // сам пакет // определим интерфейс dev = pcap_lookupdev(errbuf); // получим сетевой адрес и маску интерфейса pcap_lookupnet(dev, &net, &mask, errbuf); // откроем сессию перехвата в promiscuous режиме handle = pcap_open_live(dev, BUFSIZ, 1, 0, errbuf); // скомпилируем и применим пакетный фильтр pcap_compile(handle, &filter, filter_app, 0, net); pcap_setfilter(handle, &filter); // перехватим пакет packet = pcap_next(handle, &header); // выведем его длину в консоль printf("Jacked a packet with length of [%d]\n", header.len); // закроем сессию pcap_close(handle); return(0); }

Эта программа перехватывает пакеты на устройстве, которое возвращает pcap_lookupdev() , переводя его в pormiscuous режим. Она обнаруживает пакет, который идет через 23-ий порт (telnet) и выводит его размер в байтах. Вызов pcap_close() закрывает открытую сессию перехвата.

Альтернативный метод, хотя и более труден для понимания, но, скорее всего, более полезен. Существуют очень мало (если вообще существуют) перехватчиков пакетов, которые используют pcap_next() . В подавляющем большинстве случаев они используют pcap_loop() или pcap_dispatch() (который, в свою очередь, использует pcap_loop()). Для того, чтобы понять использование этих двух функций, нужно понимать идею callback-функций (функций обратного вызова).

Callback-функции - часто использующийся прием программирования. Принцип довольно прост. Предположим, у вас есть программа, которая ожидает какого-либо события. С целью, например, обработки нажатия клавиши. Каждый раз, когда нажимается клавиша, я хочу вызывать функцию, которая обработает это событие. Функция, которую я использую - callback-функция. Каждый раз, когда пользователь нажимает клавишу, моя программа вызовет callback-функцию. Callback-функции используются в pcap , но вместо того, чтобы вызывать их, когда пользователь нажмет на клавишу, pcap вызывает их, когда получает очередной пакет. pcap_loop() и pcap_dispatch() - функции, которые практически одинаково используют механизм callback-функций. Обе вызывают callback-функцию, каждый раз, когда pcap перехватывает пакет, который проходит через фильтр (если, конечно, фильтр скомпилирован и применен к сессии, в противном случае callback-функции передаются все перехваченные пакеты)

Прототип функции pcap_loop():

Int pcap_loop (pcap_t *p, int cnt, pcap_handler callback, u_char *user);

Первый аргумент - хэндл нашей сессии. Следующее целое число говорит pcap_loop() сколько всего пакетов нужно перехватить (отрицательное значение обозначает, что перехват пакетов должен происходить, пока не произойдет ошибка). Третий аргумент - имя callback-функции (только имя, без скобок). Последний аргумент используется в некоторых приложениях, но обычно он просто установлен в NULL. pcap_dispatch() практически идентична, единственная разница в том, как функции обрабатывают таймаут, величина которого задается при вызове pcap_open_live() . pcap_loop() просто игнорирует таймауты, в отличие от pcap_dispatch() . Детали - в man pcap .

Перед тем, как привести пример использования pcap_loop() , мы должны рассмотреть формат нашей callback-функции. Мы не можем произвольно определить прототип callback-функции, так как pcap_loop() не будет знать, что с ней делать. Прототип нашей callback-функции должен быть таким:

Void got_packet (u_char *args, const struct pcap_pkthdr *header, const u_char *packet);

Рассмотрим его подробнее. Первое - функция возвращает пустое значение (void). Это логично, так как pcap_loop() не может знать, что делать с возвращаемым значением. Первый аргумент совпадает с последним аргументом pcap_loop(). Какое бы значение не использовалось как последний аргумент pcap_loop() , оно пробрасывается в качестве первого аргумента callback-функции каждый раз когда она вызывается из pcap_loop() . Второй аргумент - заголовок pcap , который содержит информацию о том, когда был перехвачен пакет, его размер и т.д. Структура pcap_pkthdr определена в pcap.h следующим образом:

Struct pcap_pkthdr { struct timeval ts; // временная метка bpf_u_int32 caplen; // длина захваченной части пакета bpf_u_int32 len; // полная длина пакета };

Последний аргумент callback-функции наиболее интересен. Это указатель на буфер, который и содержит, собственно, весь пакет, перехваченный с помощью pcap_loop() .

Как использовать переменную packet ? Пакет содержит множество атрибутов, так что, как вы можете представить, он на самом деле не строка, а некоторый набор структур (например, пакет TCP/IP будет содержать ethernet-, ip-, tcp-заголовок и сами данные). Параметр packet , имеющий тип u_char , на самом деле сериализованная версия этих структур. Для того, чтобы получить полезные данные из этих структур, мы должны провести некоторые преобразования.

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

Struct sniff_ethernet { u_char ether_dhost; u_char ether_shost; u_short ether_type; /* IP? ARP? RARP? etc */ }; // IP заголовок struct sniff_ip { #if BYTE_ORDER == LITTLE_ENDIAN u_int ip_hl:4, ip_v:4; #endif #if BYTE_ORDER == BIG_ENDIAN u_int ip_v:4, /* version */ ip_hl:4; /* header length */ #endif /* not _IP_VHL */ u_char ip_tos; u_short ip_len; u_short ip_id; u_short ip_off; #define IP_RF 0x8000 /* reserved fragment flag */ #define IP_DF 0x4000 /* dont fragment flag */ #define IP_MF 0x2000 /* more fragments flag */ #define IP_OFFMASK 0x1fff /* mask for fragmenting bits */ u_char ip_ttl; /* time to live */ u_char ip_p; /* protocol */ u_short ip_sum; /* checksum */ struct in_addr ip_src,ip_dst; /* source and dest address */ }; struct sniff_tcp { u_short th_sport; u_short th_dport; tcp_seq th_seq; /* sequence number */ tcp_seq th_ack; /* acknowledgement number */ #if BYTE_ORDER == LITTLE_ENDIAN u_int th_x2:4, /* (unused) */ th_off:4; /* data offset */ #endif #if BYTE_ORDER == BIG_ENDIAN u_int th_off:4, /* data offset */ th_x2:4; /* (unused) */ #endif u_char th_flags; #define TH_FIN 0x01 #define TH_SYN 0x02 #define TH_RST 0x04 #define TH_PUSH 0x08 #define TH_ACK 0x10 #define TH_URG 0x20 #define TH_ECE 0x40 #define TH_CWR 0x80 #define TH_FLAGS \ (TH_FIN|TH_SYN|TH_RST|\ TH_ACK|TH_URG|TH_ECE|TH_CWR) u_short th_win; /* window */ u_short th_sum; /* checksum */ u_short th_urp; /* urgent pointer */ };

Если используются описания структур из стандартных заголовочных файлов, то иногда для того, чтобы программа, использующая описание TCP-заголовка, откомпилировалась без ошибок, нужно определить символ _BSD_SOURCE , перед подключением заголовочных файлов. Альтернативный способ - определить структуры, описывающие TCP-заголовок, вручную.

pcap , естественно, использует точно такие же структуры, когда перехватывает пакеты. Затем он просто создает u_char строку (буфер) и копируют данные из структур в нее. Как разобрать строку обратно на структуры? Это легко делается с помощью указателей и преобразований типов.

Сначала объявим переменные, которые нам нужны для разбора u_char пакета на отдельные заголовки:

Const struct sniff_ethernet *ethernet; const struct sniff_ip *ip; const struct sniff_tcp *tcp; const char *payload; int size_ethernet = sizeof(struct sniff_ethernet); int size_ip = sizeof(struct sniff_ip); int size_tcp = sizeof(struct sniff_tcp);

Теперь делаем преобазование типов:

Ethernet = (struct sniff_ethernet*)(packet); ip = (struct sniff_ip*)(packet + size_ethernet); tcp = (struct sniff_tcp*)(packet + size_ethernet + size_ip); payload = (u_char *)(packet + size_ethernet + size_ip + size_tcp);

После этого мы можем обращаться к полям всех структур обычным образом, например:

If (tcp->th_flags & TH_URG) { ... }; ... printf("TTL = %d\n", ip->ip_ttl);

Завершение работы

По завершении работы нужно закрыть сессию. Это делается с помощью функции pcap_close() .