Коллектив авторов - Защита от хакеров корпоративных сетей
i = libnet_write_link_layer(l, dev, packet, pkthdr.caplen);
if (verbose)
fprintf(stdout, “ICMP: Wrote %i bytesn”, i);
/* Route Packet */
} else if (!memcmp(eth->ether_dhost, user_mac,
ETHER_ADDR_LEN)) {
memcpy(eth->ether_dhost, upstream_mac,
ETHER_ADDR_LEN);
memcpy(eth->ether_shost, user_mac, ETHER_ADDR_LEN);После того что пришлось сделать для протокола ICMP, самостоятельно реализовать функции маршрутизатора не очень сложно. Следует только выбрать любой, не предназначенный программе пакет, передающийся по фальсифицированному адресу аппаратных средств, и отослать его другому MAC-адресу. Вполне возможно, что придется еще раз уменьшить значение предписанного времени жизни пересылаемого пакета TTL:
if (do_checksum == 1) {
ip->ip_ttl—;
libnet_do_checksum(packet + LIBNET_ETH_H, IPPROTO_IP,
LIBNET_IP_H);
libnet_do_checksum(packet + LIBNET_ETH_H, ip->ip_p,
ntohs(ip->ip_len) – LIBNET_IP_H);
}Обратите внимание, что, по всей видимости, нет особой необходимости принимать какие-либо меры по поводу странных пакетов, которые передаются по отличающимся от IP протоколам и создают помехи для контрольных сумм. Ведь только хосты, посылающие по протоколу IP ARP-запросы, интересуют фальсифицированные MAC-адреса. Но, на всякий случай, будет лучше, если дополнительно ввести проверку на попытку маршрутизации пакета IP. То, что программа предоставляет больше свободы действий, чем ядра современных операционных систем, означает, что в большинстве случаев ядра операционных систем предполагают, что они поддерживают работу с дружественным TCP/IP-стеком. В этом заключается клад возможностей спуфинга. Независимо от причин, почему так происходит, в интересующих исследователя случаях почти всегда попытки спуфинга могут быть повторно проанализированы и найдены способы противодействия им. Если для этого появятся достаточные основания, то можно случайным образом создать шумовые помехи, изменить представляющие интерес специфические строки, по требованию отослать пакеты, ограничить полосу пропускания, создать новые IP-адреса для хостов своей и даже чужой подсети. Это всего лишь инфраструктура. Дело в том, что нет никакой необходимости даже в небольшой части аппаратных средств для осуществления действительно интересных вещей. Некоторые вполне прилично кажущиеся программы будут фальсифицировать то, что нужно злоумышленнику, а сети окажутся недостаточно мудрыми, чтобы противостоять этому. Все, что злоумышленник может сделать, – это отослать следующее:
i = libnet_write_link_layer(l, dev, packet, pkthdr.caplen);
if (verbose)
fprintf(stdout, “DATA: Sent %i bytes to %sn”, i,
inet_ntoa(ip-
>ip_dst));
}}}
/* Enough for now ... */
pcap_close(pcap);
return EXIT_SUCCESS;
}
void
print_ip(FILE * stream, u_char * ip)
{
fprintf(stream, “%i.%i.%i.%in”, ip[0], ip[1], ip[2],
ip[3]);
}
void
print_mac(FILE * stream, u_char * mac)
{
fprintf(stream, “%X:%X:%X:%X:%X:%Xn”, mac[0], mac[1],
mac[2], mac[3], mac[4], mac[5]);
}Осталось сказать несколько слов об очистке ресурсов. Большинство систем имеют ограничение на число одновременно захваченных пакетов как следствие ограничений ядра операционной системы, которые задаются во время компиляции. У программы имеется дескриптор файла захваченных пакетов, который закрывается при ее завершении. Обработка захваченных пакетов ведется в бесконечном цикле. В случае аварийного завершения программы код обработки никогда не будет выполнен. Прежде чем приложение завершится, будущему коду пользователя может потребоваться цикл обработки захваченных пакетов. Убедитесь, что по завершении работы все будет закрыто!
void usage()
{
fprintf(stderr, “DoxRoute 0.1: Userspace TCP/IP Router, by
Dan Kaminsky ([email protected])n”);
fprintf(stderr, “
Usage: doxroute [-i interface] [-m userspace_mac]n”);
fprintf(stderr, “
[-r/R upstream_ip/mac] [-cv] userspace_ipnn”);
fprintf(stderr, “
Example: doxroute -r 10.0.1.254 10.0.1.169n”);
fprintf(stderr, “
Options: n”);
fprintf(stderr, “
-i [interface] : Select the interface to be used.n”);
fprintf(stderr, “
-r [upstream_ip] : MAC Address of upstream routern”);
fprintf(stderr, “
-R [upstream_mac] : MAC Address of upstream router/
gateway.n”);
fprintf(stderr, “
-m [userspace_mac]: MAC Address for this software.n”);
fprintf(stderr, “
-c : Verify Checksums(and decrement IP
TTL).n”);
fprintf(stderr, “
-v : Verbose Mode.n”);
fprintf(stderr, “
Notice: This is just a proof of concept. Useful stuff
later.n”); exit(1);
}В конечном итоге была разобрана вся внутренняя часть программы DoxRoute. Вовсе не предполагается, что читатель попытается понять всю программу. Пусть он просто перепишет ее исходный текст с www.doxpara.com/tradecraft/doxroute. Следующая команда компиляции построит doxroute:
gcc “libnet-config —defines” -O3 -Wall -funroll-loops -
fomit-frame-pointer -pipe -I/usr/local/include -L/usr/local/
lib -lpcap -o doxroute doxroute.c /usr/local/lib/libnet.aМожно найти копии libnet и libpcap на их домашних страничках www.packetfactory.net/Projects/Libnet и www.tcpdump.org respectively соответственно. В особых случаях при мониторинге DoxRoute или при простой попытке изучить работу нового протокола потребуется Ethereal. По-видимому, Ethereal является лучшей системой снифинга, разработанной для UNIX. Ее можно найти по адресу www.ethereal.com. Просмотрите еще раз главу 10 для уяснения деталей снифинга более подробно.
Малоизвестное: спуфинг через асимметричные межсетевые экраны
В идеальном мире сеть является прозрачной абстракцией. Одна система хочет переговорить с другой. Для этого ей достаточно послать пакет по нужному адресу и знать, что он будет доставлен. По разным причинам вопросы адресации и ответа на полученные пакеты будут изложены в следующей главе.
Сеть стала менее прозрачной. Чаще, чем что-либо, межсетевые экраны размещаются вне защищаемой сети, и если больше нет иных средств, то они предотвращают прием данных по всем входящим соединениям, кроме явно разрешенных. К выходящим соединениям применяются более либеральные правила. В этом проявляется очень сильное свойство асимметричных систем защиты. Входящие соединения доступны только в том случае, если они явно разрешены, а все выходящие соединения, кроме явно запрещенных, разрешены.
Предположение состоит в том, что входящие соединения установлены с плохим большим внешним миром, где никому нельзя верить. А выходящие соединения инициированы из относительно небольшой локальной сети, где большинству хостов в разумной степени можно доверять. Как правило, подобное предположение справедливо, хотя и чревато проблемами в случае опутывания клиентов различными шпионскими программами. Особенно если пользователи искушены в вопросах запуска программ, которые открывают сетевые подключения от их имени. Фактически это означает, что программные обманы – не такая уж редкость в сети.
К сожалению, существует главная проблема использования межсетевых экранов. Она очевидна для сети, в которой разрешены только выходящие соединения для подключения к хостам, не защищенным межсетевым экраном, или к хостам, у которых есть необходимые разрешения для входящих соединений. Вряд ли две сети смогут связаться друг с другом, если у них установлены только выходящие соединения. Даже если предположить, что оба межсетевых экрана доверяют своим защищаемым хостам выбрать удаленный хост, с которым они хотели бы связаться. Ни одна из сторон все равно не сможет принять данные от другой, поэтому установить связь невозможно.
Сказанного уже достаточно для обозначения проблемы, которой посвящена следующая глава. В главе 13 описаны методы ее решения при помощи запутанных способов безопасного туннелирования трафика. Ранее эти способы были проклятием для проектировщиков сети.
Хотя есть другое мнение по данному вопросу. Выберем находящиеся под защитой межсетевого экрана два хоста и, возможно, незащищенный межсетевым экраном, третий хост, который может тайно послать ограниченное число данных обоим хостам. Межсетевой экран разрешает только выходящие соединения. Можно ли в этом случае так обмануть расположенные между двумя сетями межсетевые экраны, чтобы каждый из экранов думал, что другой принимает входящие соединения?
Можно. Межсетевые экраны используют соединения асимметрично, различая входящие и выходящие соединения. Но большинству соединений присуща внутренняя двусторонность, что является сетевым проявлением двунаправленных сокетов UNIX. Фактически двусторонность присутствует только во время инициализации соединения. Фальсифицируя правильный инициализирующий пакет от «правильного» хоста в правильный момент времени, вполне возможно сделать соединение симметричным во время попытки установления соединения и вынудить два межсетевых экрана установить соединение друг с другом.
Симметричное выходящее соединение по протоколу TCP: продуманная экспериментальная оболочка брокера соединения TCP с квитированиемДопустим, что нужно рассмотреть в замедленном темпе следующую ситуацию и выявить все сопутствующие ей события. Два хоста предпринимают попытки установить выходящее TCP-соединение друг с другом. Каждый из хостов находится под защитой межсетевого экрана, настроенного на пропуск только выходных данных. Рассматриваемая ситуация в первую очередь касается межсетевых экранов с возможностью трансляции сетевых адресов. Алиса при инициализации TCP-соединения начала бы с посылки пакета SYN. Отправленный Алисой пакет SYN поступает к ее межсетевому экрану, который в своей таблице состояний отмечает попытку Алисы установить соединение с Бобом. Также он запоминает, что отформатированный соответствующим образом ответ Боба должен поступить обратно Алисе. Далее пакет SYN пересылается через Интернет тому, кого Алиса увидела как Боба. Возможно, что в пакете в качестве адреса отправителя был указан адрес межсетевого экрана Алисы.