Охота на КАИНа payhash[Wolf D.A.] Спецвыпуск: Хакер, номер #060, стр. 060-064-1 aka acidoptic Не поможет антивирус, не поможет файрвол? "Концепция межсетевого экрана (МСЭ) все еще представляется в виде непроницаемой кирпичной стены, непобедимого магического защитника всего хорошего. Реклама современных производителей только подчеркивает это, обещая полную автоматизированную защиту, стену, способную блокировать все опасности еще на стадии их возникновения, используя алгоритмы, еще два года назад, возможно, и не существовавшие. Но что если на самом деле МСЭ - это не стена, а всего лишь соломенная ширма?" Израэль Дж. Луго и Дон Паркер, перевод Владимира Куксенко "Ты думаешь, инженерный пароль? Нет, брат, сомневаюсь. Иначе бы поснифали telnet. Странно. Как это им удалось? В принципе, snort показал пакетную активность, но это был не telnet (не уровень приложений)". Я услышал этот диалог три года назад, но помню его как сейчас, и много разных мыслей приходит в мою голову. В конце 60-х по заявке вооруженных сил США и под их чутким руководством был спроектирован и смоделирован проект ARPA (RFC 384). Если рассказать о нем в двух словах :), получится, что сеть компьютеров объединена в один логический механизм, и если какую-то часть данного механизма вывести из строя, в целом система не обломится. Все довольны, идея просто замечательна. В результате после недолгих и красивых убеждений ее принял весь мир. Но мир не учел лишь то, что под маской качества и стабильности притаился старший брат - КАИН (Control Authonomical-Informations Networks). Те, кто читают эту статью, наверняка знают такие аббревиатуры, как TCP (UDP)/IP, ICMP. В этих нестрашных буквосочетаниях мы и попробуем найти скрытую угрозу. Голова профессора Доуэля Для начала в деталях разберем сетевой стек IP (RFC 791) (смотрим "Схему 1"). Если применить его относительно языка С, получим следующую несложную структуру: struct ip { u_int8_t ip_vhl; //Версия и размер сетевого стека #define IP_V(ip) (((ip)->gt; ip_vhl & 0xf0) >gt; >gt; 4) #define IP_HL(ip) ((ip)->gt; ip_vhl & 0x0f) u_int8_t ip_tos; //TOS приоритет IP-пакета u_int16_t ip_len; //Размер IP-пакета u_int16_t ip_id; //Идентификатор IP-пакета u_int16_t ip_off; //Офсет IP-пакета в случае его фрагментации #define IP_DF 0x4000 #define IP_MF 0x2000 #define IP_OFFMASK 0x01fff u_int8_t ip_ttl; //Время жизни IP-пакета u_int8_t ip_p; //IP-протокол u_int16_t ip_sum; //Контрольная сумма IP-пакета struct in_addr ip_src, ip_dst; //IP-адрес источника и IP-адрес получателя }; В пакете существуют как обязательные поля, которые нужно грамотно заполнить, так и необязательные - их можно не заполнять (например data 64 Кб). Теперь подумаем о том, что можно записать в эти 64 Кб. Обычно в них пишутся протоколы более высокого транспортного уровня, которые описаны в RFC (TCP, UDP, etc). Основной принцип таких протоколов - это работа с портами. Например, на хост-получатель пришел IP-пакет, а что делать с этим пакетом и как поступить с ним, определяется именно в этом поле. Данными процедурами занимается ядро операционной системы (запомним этот важный факт ;)). Ядро принимает входящие пакеты, обрабатывает их и отдает приложениям (WEB, FTP, SSHD, TELNETD и др.), создавая сетевые сессии, которые можно отслеживать с помощью различных утилит (netstat, sockstat, etc). Как уже было сказано, эти сессии более высокого сетевого уровня, и их можно отследить стандартными способами. Более низкий уровень (Ethernet, IP, ICMP и др.) отслеживается на уровне ядра, доступ к таким сессиям осуществляется через специальные системные вызовы. По такому принципу работают файрволы (firewall) и сетевые сниферы. При определенной конфигурации файрвол защищает систему от нежелательной сетевой сессии. Проще говоря, с его помощью мы запрещаем или разрешаем тот или иной протокол. Все просто! Все защищены, все довольны, на первый взгляд все кажется правильным и логичным, но есть одно "но". Попробуем подумать немного не так, как принято в обществе :), и решить нижеследующую задачу. |