Сниффер: щит и меч.

Автор: Константин Максимов
Опубликовано: 10.10.2002
Версия текста: 1.0
Принцип работы сниффера.
Основы передачи данных в сети Ethernet.
Структура программы для прослушивания сети.
Методы защиты от прослушивания сети.
        
          "Убивает не автомат, а человек".
М. Калашников

        
      

Принцип работы сниффера.

Сниффер – это программа, которая позволяет перехватывать сетевой трафик. Когда говорят о снифферах, то обычно проводят аналогию с прослушиванием телефонных разговоров. Подключившись к телефонной сети, можно перехватить беседу людей. Примерно также в компьютерных сетях можно перехватывать информацию, которой обмениваются компьютеры. Прослушивание возможно благодаря особенности архитектуры сети Ethernet (IEEE 802.3). Архитектура большинства локальных сетей основана на технологии Ethernet (ether – эфир, network – сеть), в которой все устройства подключены к одной среде передачи данных и совместно её используют. Топология сети Ethernet – линейная или звездообразная, а скорость передачи данных 10, 100 и 1000 Мбит/сек. Ethernet – это широковещательная сеть, в которой все узлы могут принимать все сообщения через единую магистраль. Используя эту особенность Ethernet, отпадает необходимость несанкционированного подключения к сегменту сети, т.е. не требуется резать кабели. Компьютер, с которого предполагается прослушивать, уже подключен к некоторому сегменту сети.

ПРИМЕЧАНИЕ

Sniff (англ.) – нюхать, фыркать, втягивать носом.

Слово sniffer предприимчивые американцы из фирмы Network Associates зарегистрировали. Оно является торговой маркой, под которой распространяется программа-анализатор работы компьютерной сети.

Сниффер может анализировать только то, что проходит через его сетевую карту. Внутри одного сегмента сети Ethernet все пакеты рассылаются всем машинам, из-за этого возможно перехватывать чужую информацию. Использование коммутаторов (switch, switch-hub) и их грамотная конфигурация уже является защитой от прослушивания. Между сегментами информация передаётся через коммутаторы. Коммутация пакетов – форма передачи, при которой данные, разбитые на отдельные пакеты, могут пересылаться из исходного пункта в пункт назначения разными маршрутами. Так что если кто-то в другом сегменте посылает внутри его какие-либо пакеты, то в ваш сегмент коммутатор эти данные не отправит.

Прослушивающие программы или пакетные анализаторы относятся к классу утилит двойного назначения. С одной стороны снифферы – мощное оружие, с помощью которого можно осуществить пассивную сетевую атаку. Эти программы могут представлять собой серьезную угрозу, поскольку могут перехватывать и расшифровывать имена и пароли пользователей, конфиденциальную информацию, нарушать работу отдельных компьютеров и сети в целом. Известно, что в большинстве протоколов передачи данных (FTP, POP, HTTP, telnet) секретная информация между клиентом и сервером передаётся открытым текстом. Поэтому злоумышленнику не составляет большого труда получить доступ к чужой информации. Достаточно раздобыть программу-сниффер, настроить её фильтры и ждать, когда жертва будет подключаться к серверу. С другой стороны снифферы помогают системным администраторам осуществлять диагностику сети и отслеживать атаки компьютерных хулиганов. Кроме того, они служат для проверки и детального анализа правильности конфигурации сетевого программного обеспечения. Иными словами – щит и меч.

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

Информация передаётся по сети, и получает её каждое устройство этой сети. По умолчанию сетевая плата компьютера видит только то, что предназначено именно для неё. Однако прослушивающие программы устанавливают её в режим приёма всех пакетов – promiscuous mode, прослушивают сеть и заставляют сетевую плату принимать все кадры, вне зависимости от того, кому они адресованы в сети.

ПРИМЕЧАНИЕ

Promiscuous (англ.) – неразборчивый, смешанный.

В основе многих снифферов были и есть сетевые драйверы и библиотеки (libpcap, libnet), которые осуществляют большую часть работы. Дело в том, что для переключения сетевой платы в promiscuous mode требуется низкоуровневое программирование её портов. В многозадачной ОС такую работу могут выполнить только драйверы уровня ядра системы (kernel-mode drivers). Первые программы такого типа были созданы для операционных систем Unix. Для установки вручную сетевого интерфейса в "неразборчивый" режим необходимо включить флаг PROMISC:

$ifconfig eth0 promisc;

для отключения promiscuous mode:

$ifconfig eth0 –promisc.

Вскоре снифферы перебрались в популярную ОС Windows, но их работа в этой системе также требовала сетевого драйвера, который переключал сетевую плату (NIC – network interface card) в специальный режим. До недавнего времени создание программ-снифферов было уделом квалифицированных специалистов. С появлением Windows2000 создать программу для прослушивания сегмента сети стало совсем просто.

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

Основы передачи данных в сети Ethernet.

Каждому устройству в сети Ethernet соответствует уникальный шестибайтовый MAC-адрес (Media Access Control). Единицей передачи данных в такой сети является кадр (frame), который имеет определённую структуру и несёт в себе информацию о получателе, отправителе и сами данные.

struct ETHERNET_FRAME
{
  unsigned char  dest[6];// MAC-адрес получателя
  unsigned char  src[6]; // MAC-адрес отправителя
  unsigned short type;   // версия: IPv4 0x0800, IPv6 0x86DD, ARP 0x0806
  unsigned char  data[]; // данные
};

Кадр может иметь размер от 60 до 1514 байт, из которых первые 14 байт являются служебными. Когда требуется передать большее количество данных, они разбиваются на фрагменты и последовательно направляются в сеть. Кадр передаётся по сети, и получает его каждое устройство этой сети. Значение поля структуры с именем type определяет тип и версию "полезного груза" в кадре. Завершающая секция кадра служит для проверки целостности передаваемых данных и использует код циклического контроля (CRC32 – cyclic redundancy check). Значение этого кода вычисляется с помощью специальной хэш-функции для выявления искажённости числовых данных. Обычно она аппаратно реализована в сетевой плате.

Теперь обратим внимание на полезный груз, который несёт кадр, а именно поле структуры data[]. Чаще всего в качестве данных может быть IP-пакет или ARP-пакет. ARP (address resolution protocol) – это служебный вспомогательный протокол, который осуществляет динамическую трансляцию физических MAC-адресов в логические IP-адреса на основе широковещательной рассылки запросов.

struct ETHERNET_ARP
{
  unsigned short hrd;   // Тип аппаратуры (Ethernet), 0x0001.
  unsigned short pro;   // Протокол (IP), 0x0800.
  unsigned char  hln;   // Длина аппаратного адреса (MAC), 6 байт.
  unsigned char  pln;   // Длина адреса протокола IP, 4 байта.
  unsigned short op;    // Вид операции {Запрос, Ответ} = {1, 2}.
  unsigned char  sha[6];// Аппаратный адрес (MAC) отправителя.
  unsigned char  spa[4];// IP-адрес отправителя.
  unsigned char  tha[6];// Аппаратный адрес (MAC) получателя.
  unsigned char  tpa[4];// IP-адрес получателя.
};

Для доставки пакетов в сети нужно определить физический адрес узла назначения. Именно для этого существует ARP – протокол автоматического определения физических адресов (IP <=> MAC). Когда одному компьютеру нужно начать обмен данными с другим, он ищет MAC-адрес получателя соответствующий запрашиваемому IP-адресу в своей ARP-таблице. Если для нужного IP-адреса не найден соответствующий MAC-адрес, то посылается широковещательный запрос ARP, содержащий искомый IP-адрес назначения, а MAC-адрес для широковещательной рассылки заполнен единицами FF:FF:FF:FF:FF:FF. Целевой хост узнает свой IP-адрес, обрабатывает запрос и посылает ответ. Система готова к пересылке данных по локальной сети.

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

struct IP6Header
{
  unsigned long  ver:4;   // Версия IP-протокола
  unsigned long  tclass:8;// Класс трафика
  unsigned long  label:20;// Метка потока
  unsigned short length;  // Длина пакета
  unsigned char  next;    // Next header (опции)
  unsigned char  hop;     // Hop-limit.
  unsigned char  src[16]; // 128-битный адрес отправителя
  unsigned char  dst[16]; // 128-битный адрес получателя
};

Далее в статье будут рассматриваться только IP-пакеты самой распространённой четвёртой версии. Пакет состоит из заголовка, служебной информации (options) и данных. На языке С этот заголовок выглядит в виде вот такой структуры:

typedef struct _IPHeader
{
  unsigned char  verlen;   // версия и длина заголовка
  unsigned char  tos;      // тип сервиса 
  unsigned short length;   // длина всего пакета 
  unsigned short id;       // Id 
  unsigned short offset;   // флаги и смещения 
  unsigned char  ttl;      // время жизни 
  unsigned char  protocol; // протокол 
  unsigned short xsum;     // контрольная сумма 
  unsigned long  src;      // IP-адрес отправителя 
  unsigned long  dest;     // IP-адрес назначения 
}IPHeader;

Следует помнить, что порядок байт при передаче данных в сети отличается от порядка (старшинства) байт в числах на процессорах семейства x86. В этих процессорах архитектура памяти организована таким образом, что байты в 16-ти и 32-битных числах переставлены в обратном порядке. Это так называемая "little-endian" адресация. Для корректной работы с числами следует использовать функции htons() и htonl(). В драйверах для этой цели следует использовать функции RtlUshortByteSwap(), RtlUlongByteSwap().

Подробно IP протокол описан в RFC за номером 791. Для нас особый интерес представляют поля заголовка protocol, src и dest. Два последних поля – это хорошо известные IP-адреса отправителя и получателя пакета. Например, шестнадцатеричное значение адреса 0x0000140A соответствует 10.20.0.0.

Поскольку в сети постоянно циркулирует огромное количество пакетов, то их лучше отфильтровывать. Критериями фильтрации могут быть IP-адреса, тип вышестоящего протокола (TCP, UDP, ICMP, PUP), а также содержимое пакета. Функции фильтрации весьма полезны, так как не только ограничивают собираемую программой информацию действительно нужной, но и просто обеспечивают её нормальную работу. Вполне возможно, что при интенсивной загрузке локальной сети компьютер и программа-сниффер будут не способны обработать всю поступающую информацию.

ПРИМЕЧАНИЕ

Посчитаем, сколько потребуется времени для заполнения жёсткого диска объёмом 80 Гбайт при перехвате всего трафика с сети 100 Мбит/сек. В секунду будет передано примерно 10 Мбайт. 80 Гбайт / 10 Мбайт/сек = 2,5 часа. Немного…

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

Драйвер сетевой платы (NIC) занимается приёмом и передачей кадров в сеть Ethernet. Максимальный размер IP-пакета, включая служебные данные, составляет 64 килобайта, а максимальный размер данных в кадре, как вы уже знаете, 1500 байт. При необходимости драйвер осуществляет фрагментацию и сборку IP-пакетов. Сетевая подсистема в ОС Windows основана на многоуровневой архитектуре, которую в 1978 году одобрила международная организация стандартов (см. врезку). Таким образом, NIC-драйвер взаимодействует с драйверами вышестоящих протоколов.

Программа для прослушивания сегмента сети работает именно с IP-пакетами. Она использует библиотеку Windows Sockets версии 2.2 и функционирует под управлением Windows 2000 и более поздних систем. Программирование "сырых" сокетов (raw sockets) в системе Windows предыдущих версий было почти невозможно. Неудивительно, что долгое время программы такого типа создавались только под системы Unix и DOS. В таблице 1 перечислены версии WinSock и их возможности.

WinSock 1.1Windows 98WinSock 2.xWinNT 4.0WinSock 2.0Windows 2000WinSock 2.2
Raw ICMPнетдадада
Raw IPнетнетнетда
Raw TCP|UDPнетнетнетнет
Таблица 1.
ПРИМЕЧАНИЕ

До недавнего времени многие программы, особенно для MS-DOS, имели монолитную архитектуру. Внутри программы находился код для низкоуровневой работы с аппаратурой (модемом, сетевой платой), а также весь остальной код для отображения информации и др. Изменение аппаратной части ЭВМ вынуждало модернизировать такие программы.

Современная архитектура сетевого программного обеспечения основана на семиуровневой модели OSI (Open Systems Interconnection). В основе модели лежит принцип абстракции, когда каждый компонент выполняет свои функции и предоставляет некоторый сервис вышестоящему уровню.

Слой (Layer)Описание
ApplicationПриложениеВ этом слое находятся прикладные программы – приложения. К этим программам относятся браузеры, почтовые программы, WWW- и FTP-серверы и клиенты. Они обычно не зависят ни от среды передачи данных, ни от способа передачи данных.
PresentationПредставлениеСлой представлений отвечает за то, как информация, передаваемая по сети, будет представлена пользователю. Например, html-страничка может быть представлена в виде исходного текста или в виде отформатированного документа. Вот другой пример – картинка в формате GIF закодирована в Base64 и передана в составе электронного письма. Раньше этот слой предназначался для установления различных режимов работы терминалов.
SessionСессияСессии – это процедуры обмена данными между приложениями. Сессии предназначены для связи рабочих станций с серверами. FTP Session, POP Session – это как раз сюда.
TransportТранспортПротокол передачи данных высокого уровня. Например, TCP обеспечивает гарантированную доставку информации в отличие от протокола UDP.
NetworkСетьЗнаменитый третий уровень, обычно это IP (internet protocol). Здесь передаются пакеты, осуществляется их маршрутизация, сборка и фильтрация. Пакеты несут в себе информацию об отправителе и получателе.
Data LinkКанал данныхНа этом уровне передаются кадры (порции информации) между компьютерами, коммутаторами и другими устройствами сети (Ethernet, ATM, Token Ring, PPP).
PhysicalФизический каналФизический канал передачи данных, в котором циркулируют электрические сигналы.
Таблица 2.

Структура программы для прослушивания сети.

Обладая базовыми знаниями можно смело приступить к написанию прослушивающей программы для Windows 2000. Каркас программы может состоять из нескольких частей:

В начале каждой программы, использующей Windows Sockets, находится код инициализации сетевой библиотеки (WSAStartup). Затем следует создание сокета, определение имени и IP-адреса компьютера (gethostbyname), с которого запущена программа. В заключение подготовительной стадии устанавливаются параметры сокета (bind). Теперь осталось переключить сокет в режим приёма всех пакетов. Управляющая функция ioctlsocket с параметром-командой SIO_RCVALL включает promiscuous mode.

ПРИМЕЧАНИЕ

Для тех, у кого не установлен свежий Platform SDK сообщаю, что числовое значение константы SIO_RCVALL равно 0x98000001.

Далее следует бесконечный цикл, который остановится только после нажатия клавиши. Внутри цикла идёт приём (recv) и обработка IP-пакетов. Пакеты записываются в единственный буфер и никак не анализируются. Размер буфера (64 кб) подобран с расчётом, чтобы в нём поместился самый большой IP-пакет. В нашем случае нет никакого анализа сетевого трафика. Умный человек сам разберётся, что и как дальше делать.

 
#include <conio.h>
#include <winsock2.h>

#define MAX_PACKET_SIZE    0x10000
// Буфер для приёма данных
static BYTE Buffer[MAX_PACKET_SIZE]; // 64 Kb

void main()
{
  WSADATA     wsadata;   // Инициализация WinSock.
  SOCKET      s;         // Cлущающий сокет.
  char        name[128]; // Имя хоста (компьютера).
  HOSTENT*    phe;       // Информация о хосте.
  SOCKADDR_IN sa;        // Адрес хоста
  long        flag = 1;  // Флаг PROMISC Вкл/выкл.

  // инициализация
  WSAStartup(MAKEWORD(2,2), &wsadata);
  s = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
  gethostname(name, sizeof(name));
  phe = gethostbyname( name );
  ZeroMemory( &sa, sizeof(sa) );
  sa.sin_family = AF_INET;
  sa.sin_addr.s_addr = ((struct in_addr *)phe->h_addr_list[0])->s_addr;
  bind(s, (SOCKADDR *)&sa, sizeof(SOCKADDR));
  
  // Включение promiscuous mode.
  ioctlsocket(s, SIO_RCVALL, &flag);

  // Приём IP-пакетов.
  while( !_kbhit() )
  {
    int count;
    count = recv( s, Buffer, sizeof(Buffer), 0 );
    // обработка IP-пакета
    if( count >= sizeof(IPHeader) )
    {
      IPHeader* hdr = (IPHeader *)Buffer;
      //что-то делаем с пакетом...
    }
  }
  // Конец работы.
  closesocket( s );
  WSACleanup();
}

Вот и всё. Для успешной компиляции следует подцепить библиотечный файл "ws2_32.lib". Теперь вам есть с чего начать создавать [бес]полезную программу. Для экономии места из текста программы удалены все проверки на возможные ошибки. Контроль за возвращаемыми значениями функций необходим для корректной работы программы в любых условиях. Осталось сказать, что весь материал предназначен исключительно для образовательных целей, и автор не несёт ответственности за ущерб, который может быть нанесён после прочтения этой статьи.

Методы защиты от прослушивания сети.

Многих волнует проблема безопасности передачи данных в сети. Проблема может быть решена различными способами. Первый и самый дорогостоящий – аппаратный метод, когда вместо дешёвых концентраторов (hub) устанавливаются коммутаторы (switch). Второй и более надёжный – шифрование сетевого трафика. Информацию можно будет перехватить сниффером, но прочитать её будет невозможно. Шифровать можно с помощью технологии SSL (secure sockets layer), которая встроена почти во все браузеры. Она почти всегда используется в электронной коммерции и вполне надёжна. При работе с электронной почтой сообщения следует шифровать средствами PGP (pretty good privacy) или Secure MIME. В локальных сетях можно включить шифрацию IP-трафика. В Windows 2000 эту работу выполняет встроенный протокол IP Secure. Следуя этим простым советам можно гарантировать конфиденциальность передаваемой информации.

Хочу выразить благодарность всем, кто прислал ценные замечания, в частности:

Vitali Brusentsev, Nickolay Merkin, Alex Ostapenko, Timofey Chadov.


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