Разделы сайта
Выбор редакции:
- Зарядное устройство на основе блока питания ATX Лабораторный блок питания на шим контроллере 3528
- Что делать если провод не заряжает айфон
- Виртуальная машина для Mac Виртуальная windows на mac os
- Про обслуживание Tele2 Как вводить подтверждение оплаты на номер 312
- Работа с внутренней памятью EEPROM Eeprom стирание
- Установка и обновление прошивок Huawei и Honor
- Создание субтитров в программе Subtitle Workshop
- Лазеротерапия (лазерная терапия)Аппарат лазерный терапевтический "Матрикс" Чего лечит аппарат лазерной терапии матрикс
- Накрученные подписки и мошенничество в Telegram Подписчики для телеграмм канала
- Специальность "Инфокоммуникационные технологии и системы связи" (бакалавриат) Инфокоммуникационные технологии и системы связи 11
Реклама
Анализаторы сетевых пакетов. Wireshark (перехватчик сетевых пакетов) Как с помощью wireshark проверить порт |
Общая схемаПоследовательность шагов, которая должна выполнить программа, использующая библиотеку pcap (от PacketCAPture) для выполнения своей задачи, такова:
Рассмотрим перечисленные шаги подробно. Определение интерфейсаДля определения интерфейса, на котором необходимо производить прослушивание, можно воспользоваться двумя способами. Первый состоит в том, что имя интерфейса задает пользователь. Рассмотрим следующую программу: #include Пользователь указывает интерфейс, передавая его имя через первый аргумент нашей программы. Естественно, указываемый пользователем интерфейс должен существовать. Второй способ - узнать имя интерфейса у самой библиотеки: #include В этом случае 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 Здесь открывается интерфейс, имя которого указано в строке 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 Эта программа подготавливает перехватчик для пакетов, идущих на или с 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 Эта программа перехватывает пакеты на устройстве, которое возвращает 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() . У каждого из команды ][ свои предпочтения по части софта и утилит для WiresharkNetcatЕсли говорить о перехвате данных, то Network Miner
снимет с «эфира» ScapyСайт: Must-have для любого хакера, представляющий собой мощнейшую тулзу для packethСайт: Интересная разработка, позволяющая, с одной стороны, генерировать любой Кроме подключения к каналу передачи данных, мопитор должен иметь эффективный способ идентифицировать, какие IP-иакеты перехватывать при их поступлении. Протоколы прикладного уровня Обычно связапы с определенным ТСР-пор- том, например, HTTP использует порг 80. Для отслеживания НТТР-трафика монитор пакетов может ограничиться учетом ТСР-трафика на порту 80. Такое решение может быть принято для каждого конкретного пакета путем анализа поля протокола в IP-заголовке и номеров портов источника и места назначения в TCP- заголовке. Однако выделить весь НТТР-трафик достаточно трудно. Некоторые Web-сайты не используют данный порт, а порты 8000 или 8080. Кроме того, некоторые приложения могут взаимодействовать через порт 80, используя другой протокол. Хотя порты выделяются определенным приложениям, разработчик приложения или системный администратор могут игнорировать эти указания и задействовать порт 80 для приложения, использующего другой протокол. Кроме того, в Web имеется протокол HTTPS, использующий порт 443. Мопитор пакетов может захватить HTTPS-трафик путем отслеживания ТСР-трафика, содержащего в качестве номера порта источника и места назначения порт 443. Однако данные, передаваемые через HTTPS, зашифрованы с применением Secure Socket Layer (SSL). Монитор не может идентифицировать НТТР-сообщения, передаваемые через эти ТСР-соедииения. Однако может перехватывать ТСР-трафик на порту 443 с целью расчета основных статистических показателей, таких как число соединений и байтов, передаваемых с помощью HTTPS. Другие передачи, инициированные Web-браузером, могут использовать другие протоколы прикладного уровня. В некоторых случаях этот трафик может перехватываться путем мониторинга портов, выделенных этим протоколам. Однако ряд приложений использует протоколы, которые динамически назначают номера порто» при передаче данных. Например, клиент и сервер File Transfer Protocol (FTP) могут динамически выбирать номер порта для ТСР-соединеиия, используемого для передачи данных. Аналогично многие протоколы для передачи мультимедийных потоков Обычно не используют определенные номера портов для передачи данных аудио и видео, о чем подробнее будет говориться далее в разделе 14.4.4. Перехват трафика с определенными IP- и TCP-заголовками требует применения фильтра к IP-пакетам по мере их поступления. Как Можно более ранняя фильтрация пакетов сокращает издержки, связанные с копированием и обработкой пакетов, которые будут затем отвергнуты. Мопитор пакетов может иметь специальное аннаратное обеспечение, которое осуществляет классификацию пакетов при их приеме сетевой картой. Если аннаратная поддержка отсутствует, пакеты могут отфильтровываться операционной системой или приложением. Большое число программ мониторинга пакетов основывается на ипструмепталыюм средстве tcpdump LJLM, Tcpj на основе фильтра пакетов Berkeley Packet Filter (BPF) } |
Популярное:
Новое
- Что делать если провод не заряжает айфон
- Виртуальная машина для Mac Виртуальная windows на mac os
- Про обслуживание Tele2 Как вводить подтверждение оплаты на номер 312
- Работа с внутренней памятью EEPROM Eeprom стирание
- Установка и обновление прошивок Huawei и Honor
- Создание субтитров в программе Subtitle Workshop
- Лазеротерапия (лазерная терапия)Аппарат лазерный терапевтический "Матрикс" Чего лечит аппарат лазерной терапии матрикс
- Накрученные подписки и мошенничество в Telegram Подписчики для телеграмм канала
- Специальность "Инфокоммуникационные технологии и системы связи" (бакалавриат) Инфокоммуникационные технологии и системы связи 11
- Одноклассники: как открыть мою страницу