/* Lookup the router */

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

libnet_init_packet(LIBNET_ETH_H + LIBNETARPH, &newpacket);

Являясь простой оболочкой malloc, libnetJnit_packet инициализирует заданное количество памяти (в этом случае необходимое количество памяти для заголовков Ethernet и ARP) и создает указатель newpacket на выделенную таким образом память:

libnet_build_ethernet(bcast_mac, /*eth->ether_dhost*/ user_mac, /*eth->ether_shost*/ ETHERTYPEARP, /*eth->ether_type*/
NULL, /*extra crap to tack on*/
0, /*how much crap*/ newpacket);

Следует полностью определить базовую часть пакета: указать, куда пакет направляется, откуда поступил, тип пакета и т. д. В рассматриваемом случае пакет является широковещательным сообщением ARP из МАС-адреса пространства. Учитывая указатель newpacket правильным образом, указываем на заголовок Ethernet: libnet_build_arp(ARPHRD_ETHER, ETHERTYPE IP,

ETHER ADDR LEN,
IPV 4ADDRLEN,
ARPOPREQUEST,
usermac,
user_ip,
bcastmac,
upstreamip,
NULL,
0,
newpacket + LIBNETETHH);

Библиотека libnet предоставляет полезные функции и учитывает почти все обрабатываемые выпуски программ, достаточные для заполнения полей пакета. При заполнении ARP-пакета требуется заполнить поля МАС-адреса пользователя и его 1Р-адрес, причем IP-адрес перечислен в списке upstream ip и должен быть принят во внимание любым, кто может прослушать этот адрес. Следует отметить, что эта груда байтов к указателю newpacket непосредственно не добавляется. По протоколу Ethernet она передается следующему заголовку фиксированного размера:

i = libnet_write_link_layer(l, dev, newpacket, LIBNET ETH H +
LIBNETARPH); if (verbose)!
fprintf(stdout, “ARP REQUEST: Wrote %i bytes looking for ” , i);
print_ip(stdout, upstream ip);
}

Точно так же как машины отправляются в путь, пример отправляет Ethernet и ARP-заголовки, найденные им по указателю newpacket, а затем выполняет код, написанный для отладки. Функция Libnet write Unk layer получает от библиотеки libnet номер соединения, адрес памяти отсылаемого пакета, как бы ни велик был пакет, а затем возвращает число успешно переданных байтов: libnet_destroy_packet(&newpacket);

Если функция libnetJnit_packet была аналогична функции malloc, то это просто свободно распространяемое приложение с лучшим названием. Трах-тарах! Только что пакет был отослан. Что теперь дальше?

Возвращение пакета: подбор обратного трафика.

/* Get the next packet from the queue, */ while (1) { packet = (u char *) pcap_next(pcap, &pkthdr); if (packet) {

Обратите внимание на то, что рсар next - простая функция: учитывая активный дескриптор файла libcpap и место для размещения пакета, функция рсар next возвращает адрес памяти захваченного пакета. Эта память доступна для чтения и записи, что и было использовано в примере. Следует сделать некоторое замечание. То ли из-за опции IOCTL, то ли из-за особенностей платформы, на которой выполняется libpcap, но во время чтения пакета прерывание функции pcap_next блокируется. В противном случае цикл будет повторяться до тех пор, пока не будет завершен разбор пакета:

/* * Маке packet parseable - switching on

* eth->ether_type and ip->ip_p is also a valid
* strategy. Ail structs are defined in
* /usr/include/libnet/libnet-headers.h */
/* Layer 1 : libnet_ethernet_hdr structs */
(char *)eth = (char *)packet;
/* Layer 2: libnet_arp_hdr / libnet_ip_hdr structs */
(char *)arp = (char *)ip = (char *)packet + LIBNETETHH;
/*
* Layer 3 : libnet icmp hdr / libnet tcp hdr /
* libnet udp hdr structs
*/
(char *)icmp = (char *)tcp = (char *)udp = (char *)packet +
LIBNETETHH + LIBNETIPH;

Используемая в данном случае линия поведения очень проста. Каждая структура пакета выравнивается в области памяти, отведенной для его размещения, причем эта область точно такая же, как если этот пакет был заданного типа. Было бы глупо заполнить структуры неправильными данными, полагаясь лишь на выбор области памяти указателями eth->ether type (на уровне канала передачи данных) или ip->ip р (на сетевом уровне), которые указывают на структуру описания пакета. Если так сделать, то при ошибке в разборе пакетов будут утеряны важные данные segfaults. Например, при попытке получить порядковый номер ТСР-пакета из области памяти, в которой на самом деле хранится UDP-пакет и у которого нет такого значения, ничего хорошего не получится. Но с другой стороны, рассмотренный способ достаточно гибок, потому что в общем случае только ядро операционной системы отважится прочитать эти данные. В конце концов, программе DoxRoute не очень интересно, как пользователь будет читать данный пакет. Одно важное предостережение относительно разбора пакетов: при захвате пакетов интерфейсу локального хоста не доступен заголовок Ethernet, поэтому не следует при чтении данных локального хоста пользоваться смещением LIBNET ЕТН Н:

/* Handle ARPs: */ if (ntohs(eth->ether_type) == ETHERTYPEARP && arp->ar_op == htons(ARPOPREQUEST) &&
!memcmp(arp->ar_tpa, user ip, IPV4_ADDR_LEN)) {
/*
* IF: The ethernet header reports this as an
* ARP packet, the ARP header shows it a
* request for translation, and the address
* being searched for corresponds to this
* “stack”...
*
*/

В этом месте программа ищет запросы ARP. Первое, что нужно сделать, - это удостовериться в том, что полученные данные действительно являются пакетом, содержащим нужный запрос. Для этого требуется пара надоедливых вещей. Во-первых, необходимо изменить порядок байтов в данных, на которые указывает указатель eth->ether type, по крайней мере на системах с прямым порядком байтов. (Вполне возможно, что предложенный способ плохо работает на системах с обратным порядком байтов.) Это выполняется при помощи вызова функции ntohs, которая управляет переключением от сети к хосту. Затем следует проверить, что удаленная сторона осуществляет повторный запрос, повторно переключая порядок используемых байтов. На сей раз используется функция htons для представления ARP-запроса в присущий для сети формат. Наконец, коснемся вопроса о том, соответствует ли найденный ARP-запрос IP-адресу, присутствие которого искалось в сети для ее фальсификации. Это осуществляется при помощи инвертирования результата работы функции тетстр, возвращающей первый байт, которым отличаются два буфера. Причем нулевой код возврата означает, что различие между буферами не найдено, точно то, что нам и хотелось. Таким способом код возврата инвертируется в единичное значение:

memcpy(eth->ether_dhost, eth->ether_shost, ETHERADDRLEN);
memcpy(eth->ether_shost, usermac, ETHER ADDR LEN);

Одной из действительно крутых вещей, которые можно сделать благодаря совместимости буферов ИЪрсар и libnet, является то, что по желанию можно на месте переставлять пакеты в сети, а затем отослать их обратно без повторной инициализации памяти или передачи содержимого через какой-либо контекст или еще как-нибудь. (В этом нет ничего нового. Программы ядра операционной системы делают это годами. Но рассматриваемый случай - это случай нахождения в пространстве пользователя в предположении работы Netscape, mpgl23 или еще чего-нибудь без имитации работы сетевой платы!) Поскольку делается попытка ответить отправителю Ethernet-пакета, поэтому просто и деструктивно копируем оригинальный адрес отправителя в поле адресата. Затем записываем в поле «хост-отправитель» пакета Ethernet МАС-адрес, который обязательно существует в сети:

memcpy(arp->ar_tha, arp->ar_sha, ETHER ADDR LEN); memcpy(arp->ar_sha, user mac, ETHERADDRLEN);

Ax, акронимы! Какой замечательный способ начинать день! ARP-акронимы на самом деле не слишком плохи - tha и sha не означают ничего больше, кроме как «адрес хоста получателя» и «адрес хоста отправителя». В копировании на месте важно то, что это точный эквивалент только что сделанного на уровне Ethernet: «Отправитель ARP в поле user mac информирует ARP-получателя, кто послал ARP запрос последним». Автор надеется, что читатель не удивится избыточности протокола:

arp->ar_op = htons(ARPOP REPLY); memcpy(test_ip, arp->ar_spa, IPV4_ADDR_LEN); memcpy(arp->ar_spa, arp->ar_tpa, IPV4ADDRLEN); memcpy(arp->ar_tpa, test ip, IPV4ADDRLEN);

Наконец, после преобразования пакета из формата запроса в формат ответа была выполнена замена IP-адресов. В рассматриваемом случае замена выполнена при помощи использования не требующей особого пояснения временной переменной. (Команда XOR тоже сгодилась бы, но автор ленив, а читатель должен был это понять.) После всех манипуляций был получен разумно законченный и правильный вариант ответа на ARP-запрос, который отправляется с инвертированными 1Р-адресами, ARP-адресами аппаратных средств и правильными характеристиками Ethernet-пакета. Бум, сделано: i = libnet_write_link_layer(l, dev, packet, pkthdr.caplen); if (verbose) fprintf(stdout, “ARP: Wrote %i bytes\n”, i);

Структура pkthdr полезна. Фактически это небольшая коллекция метаданных в момент их захвата. Они все потребуются для дальнейшей обработки. Элемент структуры caplen хранит длину захваченных данных. Он полностью подходит для функции установления связи и записи данных, которая нуждается в счетчике числа предполагаемых для отправки байтов. Поскольку при модификации пакетов situ длина их данных в общем случае не будет изменяться (хотя такое и могло произойти), знание оригинальной длины пакета позволяет узнать точное количество отосланных обратно данных. Также поможет и то, что рассматривается протокол с фиксированным размером пакетов, как, например, FTP, а не протокол с пакетами переменной длины, как, например, DNS:

/* Handle ARP replies (responding with upstream IP) */ } else if (eth->ether_type == ntohs(ETHERTYPE_ARP) &&
arp->ar_op == htons(ARPOPREPLY) &&
! memcmp(arp->ar_spa, upstreamip, IPV4_ADDR_LEN)){

Ниже представлен тот же самый процесс, что и при прослушивании запросов ARPOP REQUEST, только теперь осуществляется проверка полей ARPOP REPLY: memcpy(upstream_mac, arp->ar_sha, ETHERADDRLEN); if (verbose) fprintf(stdout, “Router Found: %hu.%hu.%hu.%hu at %X: %X: %X: %X: %X: %X\n”, upstream_ip[0], upstream_ip[l], upstream_ip[2], upstream_ip[3],

upstream_mac[0], upstream_mac[l], upstream_mac[2], upstream_mac[3], upstream_mac[4], upstream_mac[5]);

Помните путь назад, когда был отослан ARP-запрос на поиск нашего маршрутизатора? Ниже показано, как обработать ответ. Следует взять предложенный МАС-адрес, запомнить его в буфере upstreamjnac, копируя его из данных, на которые указывает указатель arp->ar sha. И все, сделано. Отметим, что в действительности такой подход, когда не учитываются состояния программы (обработка без памяти), уязвим к атакам спуфинга. В любое время злоумышленник может безнаказанно послать в адрес программы незатребованный ответ на ARP-запрос, для того чтобы он был использован для обновления величины upstreamjnac. Для борьбы с этим есть неплохие способы, например для предотвращения обновления соединения можно использовать триггерную переменную, для реагирования на вышедшие из строя сайты - предусмотреть монитор маршрутизатора и т. д., но рассмотрение подобных способов выходит за рамки этой главы:

/* Handle ICMP ECHO (Ping) */ } else if (!memcmp(eth->ether_dhost, usermac,
ETHER ADDR LEN) && ntohs(eth->ether_type) == ETHERTYPE IP && memcmp((u_char *) & ip->ip_dst, user ip,
IPV4 ADDR LEN) && ip->ip_p == IPPROTO ICMP && icmp->icmp_type == ICMP ECHO) {

Ax, утилита ping! Как автор по тебе тоскует! Без всякого сомнения, это лучшее средство определения, в каком режиме работает хост: в сети или автономно. Пытаясь достичь хоста, утилита не ищет сведений о нем в ARP-кэше. В процессе работы утилита отображает результат обработки текущих запросов. Фактически утилита ping является эхо-сигналом подканала ICMP протокола IP, направленного к адресуемому хосту с параметром IP ethertype и верным аппаратным адресом. Для того чтобы удостовериться в том, что полученный пакет является пакетом утилиты ping, проверяются пять условий. Несколько необычный способ принятия решения используется для проверки протокола IP, но он работает:

/* Swap Source and Destination MAC addresses */ memcpy(test_mac, eth->ether_dhost, ETHERADDRLEN);
memcpy(eth->ether_dhost, eth->ether_shost, ETHER ADDR LEN); memcpy(eth->ether_shost, test mac, ETHER ADDR LEN);

Алиса посылает пакет Бобу... Боб отвечает Алисе пакетом с инвертированными значениями полей. Все, что делается в приведенном ниже примере, - это инвертирование значений полей отправителя и получателя, для того чтобы сформировать ответ:

/* Swap Source and Destination IP addresses */ testipa = ip->ip_dst; ip->ip_dst = ip->ip_src; ip->ip_src = testipa;

To же самое, что было сделано для МАС-адресов, теперь делается на сетевом уровне для IP-адресов:

/* * Change the packet to a reply, and decrement time
* to live
*/
icmp->icmp_type = ICMPECHOREPLY; ip->ip_ttl-;

Системы, подверженные какому-либо риску зациклиться при маршрутизации, с каждым «прыжком» должны уменьшать счетчик предписанного времени жизни пересылаемого пакета TTL. Это общее правило. Если этого не сделать, то можно получить довольно странные результаты из-за существования риска бесконечной циклической маршрутизации данных. Кроме того, уменьшение значения TTL позволяет избежать усиления действия циклов обратной связи, губительных для сетей. В приведенном ниже примере пакеты с нулевым значением величины TTL не удаляются. Автор привел нижерасположенный фрагмент кода для того, чтобы читатель лучше понял суть дела:

/* Recalculate IP and TCP/UDP/ICMP checksums */ libnet_do_checksum(packet + LIBNETETHH, IPPROTO IP,
LIBNETIPH);
libnetdochecksum (packet + LIBNET ETH H, IPPROTO ICMP, pkthdr.caplen - LIBNET ETH H - LIBNET IP H);

Поскольку данные пакета были модифицированы (было уменьшено значение предписанного времени жизни пересылаемого пакета TTL), то следует откорректировать контрольные суммы, гарантируя тем самым целостность пакета при воздействии на него шума, помех или чего-то еще. Способ формирования контрольных сумм применяется на транспортном уровне (протоколы TCP/UDP/ICMP), который обеспечивает доставку между конечными точками сети. Контрольные суммы обычно применяются в протоколе ICMP. Для протоколов TCP и UDP метод контрольных сумм не применяется из-за сложностей успешного его применения в протоколе IP. В данном примере использование контрольной суммы рассматривается только для примера. В реальных условиях приведенный алгоритм маршрутизации работает гораздо лучше. При вызове алгоритма маршрутизации для указания длины обрабатываемых данных используется поле ip->ip len, что, возможно, приводит к уязвимости этого способа к некоторым типам атак (из-за излишнего доверия к значению переменной, представляющей фактическую длину полного набора данных). Так что будьте внимательны:

i = libnet_write_link_layer(l, dev, packet, pkthdr.caplen); if (verbose) fprintf(stdout, “ICMP: Wrote %i bytes\n”, i);
/* Route Packet */
} else if (!memcmp(eth->ether_dhost, user mac,
ETHER ADDR LEN)) { memcpy(eth->ether_dhost, upstreammac,
ETHERADDRLEN);
memcpy(eth->ether_shost, user mac, ETHER ADDR LEN);

После того что пришлось сделать для протокола ICMP, самостоятельно реализовать функции маршрутизатора не очень сложно. Следует только выбрать любой, не предназначенный программе пакет, передающийся по фальсифицированному адресу аппаратных средств, и отослать его другому МАС-адресу. Вполне возможно, что придется еще раз уменьшить значение предписанного времени жизни пересылаемого пакета TTL: if (dochecksum == 1) {ip->ip_ttl-;

libnetdochecksum (packet + LIBNET ETH H, IPPROTOIP,
LffiNETIPH) ;
libnet_do_checksum(packet + LIBNET ETH H, ip->ip_p, ntohs(ip->ip_len) - LIBNET IP H);
}

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

i = libnet_write_link_layer(l, dev, packet, pkthdr.caplen); if (verbose)
fprintf(stdout, “DATA: Sent %i bytes to %s\n”, i,
inet_ntoa(ip-
>ip_dst));
}}}
/* Enough for now ... */ pcapclose(pcap); return EXITSUCCESS;
}
void
print_ip(FILE * stream, uchar * ip)
{
fprintf(stream, “%i.%i.%i.%i\n”, ip[0], ip[l], ip[2],
ip[3]);
}
void
print_mac(FILE * stream, u char * mac)
{
fprintf(stream, “%X:%X:%X:%X:%X:%X\n”, mac[0], mac[l], mac[2], mac[3], mac[4], mac[5]);
}

Осталось сказать несколько слов об очистке ресурсов. Большинство систем имеют ограничение на число одновременно захваченных пакетов как следствие ограничений ядра операционной системы, которые задаются во время компиляции. У программы имеется дескриптор файла захваченных пакетов, который закрывается при ее завершении. Обработка захваченных пакетов ведется в бесконечном цикле. В случае аварийного завершения программы код обработки никогда не будет выполнен. Прежде чем приложение завершится, будущему коду пользователя может потребоваться цикл обработки захваченных пакетов. Убедитесь, что по завершении работы все будет закрыто! void usage() {

fprintf(stderr, “DoxRoute 0.1: Userspace TCP/IP Router, by Dan Kaminsky (dan@doxpara.com)\n”); fprintf(stderr, “
Usage: doxroute [-i interface] [-m userspace_mac]\n”); fprintf(stderr, “
[-r/R upstream_ip/mac] [-cv] userspace_ip\n\n”); fprintf(stderr, “
Example: doxroute -r 10.0.1.254 10.0.1.169\n”); fprintf(stderr, “
Options: \n”); fprintf(stderr, “
-i [interface] : Select the interface to be usedAn”); fprintf(stderr, “
-r [upstream_ip] : MAC Address of upstream router\n”); fprintf(stderr, “
-R [upstream mac] : MAC Address of upstream router/ gateway An”); fprintf(stderr, “
-m [userspacemac]: 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 laterAn”); exit(l);
}

В конечном итоге была разобрана вся внутренняя часть программы DoxRoute. Вовсе не предполагается, что читатель попытается понять всю программу. Пусть он просто перепишет ее исходный текст с www.doxpara.com/tradecraft/doxroute. Следующая команда компиляции построит doxroute:

gcc “libnet-config -defines” -03 -Wall -funroll-loops - fomit-frame-pointer -pipe -I/usr/local/include -L/usr/local/

lib -lpcap -o doxroute doxroute.с /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 с квитированием Допустим, что нужно рассмотреть в замедленном темпе следующую ситуацию и выявить все сопутствующие ей события. Два хоста предпринимают попытки установить выходящее ТСР-соединение друг с другом. Каждый из хостов находится под защитой межсетевого экрана, настроенного на пропуск только выходных данных. Рассматриваемая ситуация в первую очередь касается межсетевых экранов с возможностью трансляции сетевых адресов. Алиса при инициализации ТСР-соединения начала бы с посылки пакета SYN. Отправленный Алисой пакет SYN поступает к ее межсетевому экрану, который в своей таблице состояний отмечает попытку Алисы установить соединение с Бобом. Также он запоминает, что отформатированный соответствующим образом ответ Боба должен поступить обратно Алисе. Далее пакет SYN пересылается через Интернет тому, кого Алиса увидела как Боба. Возможно, что в пакете в качестве адреса отправителя был указан адрес межсетевого экрана Алисы.

Конечно, Боб никогда не получит этот пакет, потому что на самом деле в сети в качестве Боба выступает его межсетевой экран. Межсетевой экран Боба доверяет Алисе не больше, чем ее межсетевой экран Бобу. Поэтому межсетевой экран Боба отвечает на запрос Алисы отказом в установке соединения, посылая ей пакет RSTIACK. Конечно, когда межсетевой экран Алисы получает этот пакет, он знает, что он и не собирался получать от Боба положительный ответ на запрос подключения в виде пакета SYNIACK. Поэтому он затирает входы в своей таблице состояний, огорчая тем самым Алису.

У Боба сходная проблема. Он также не может вызвать Алису. Межсетевой экран Алисы сбрасывает его запросы точно так же, как его экран сбрасывает запросы Алисы.

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

Да, существует.

«Сейчас я спою песню судьбе!» Применение пакетов с обреченным временем жизни TTL для манипуляций с таблицей локальных состояний. По существу протокол IP очень похож на протокол Lilypad, который позволяет пакетам блуждать от маршрутизатора к маршрутизатору, пока он не достигнет своего адресата. Одна очень серьезная проблема, которая может произойти при ретрансляции пакета в сети (точнее, графе сети), заключается в возникновении по различным причинам бесконечного цикла маршрутизации. Последовательность маршрутизаторов может породить круговую траекторию (цикл), которая никогда не приведет отдельно взятый пакет к адресату. Это подобно езде по кругу, когда потеряна дорога к нужному городу, а водитель находится в слишком затуманенном сознании, чтобы осознать, что он уже тридцать раз проехал мимо одного и того гипермаркета быстрого обслуживания.

В реальном мире нельзя кружить вечно. В конечном счете закончится бензин. Но у пакетов нет бензобаков. Поскольку очень важно, чтобы пакеты не передавались по внутреннему циклу, то для предотвращения этого в каждый пакет включен счетчик предписанного времени жизни пересылаемого пакета TTL. Эта величина уже обсуждалась во время построения эффективного маршрутизатора в пространстве пользователя. Клиент определяет максимальное число «прыжков», которое данный пакет может осуществить при следовании по своему маршруту до адресата (обычно эта величина равна 256). Затем каждый маршрутизатор, через который проходит пакет, уменьшает счетчик предписанного времени жизни пакета TTL на 1. Если маршрутизатор получает пакет с нулевым значением счетчика TTL, то он удаляет его из потока передачи пакетов. Возможно, что при этом по протоколу ICMP будет послано сообщение о превышении времени существования пакета. Подобные сообщения используются для трассировки маршрута. Пакету разрешается сначала осуществить один прыжок, затем другой, третий и т. д.

В сказанном скрыты очень интересные вещи. Межсетевые экраны всегда позволяют проходить через них наружу пакетам с небольшим значением счетчика предписанного времени жизни TTL. Также они пропускают назад сообщения по протоколу ICMP для их оценки клиентом. Это относится и к пакетам, которые направляются законному адресату, но из-за недостаточного значения счетчика TTL обречены на уничтожение раньше, чем достигнут его. Пакет послан с соблюдением всех правил и ограничений, но он никогда не будет получен. Это именно то, что мы ищем! Для законно посланного пакета заводится запись в таблице состояний. Но поскольку адресат этого пакета никогда не получит его, то никогда не будет получен обратный пакет с установленным признаком сброса соединения RST, который удалил бы эту запись из таблицы состояний...

По крайней мере, ни Алиса, ни Боб никогда не пришлют такой ответ.

Поборник сетевого равноправия: пакеты SYMIACK в игре. Алиса и Боб могут оба инициализировать соединение с помощью пакетов SYN. Они даже могут преобразовать предназначенный для сброса состояния пакет RST в невинное ICMP-сообщение о превышении предписанного времени жизни пакета путем посылки обреченного SYN-пакета. Но, несмотря на сказанное, в таблице состояний останется запись, ожидающая подтверждения попытки подключения. Это своего рода проблема, поскольку нет готового механизма, при помощи которого Алиса и Боб смогли бы непосредственно послать пакет SYNIACK. Подобный механизм относится к внутренним элементам принятия входящего соединения, а межсетевой экран разрешает только исходящие соединения.

В соответствии с ранее описанным алгоритмом работы возможность ответа была заблокирована.

Но только то, что Алиса не может послать пакет, еще не означает, что Боб не сможет принять его. Это лишь означает, что кто-то должен отправить пакет для Алисы. Этот кто-то, известный как брокер подключения, мог бы получить от Алисы пакет SYNIACK, который она ожидала получить от Боба, если только его межсетевой экран позволил бы ему отправить сообщение. (Подобное сообщение брокер мог бы получить от Боба, и оно содержало бы все сведения, которые он хотел бы получить от Алисы.) Посредник мог не знать о первоначальном пакете SYN, затерявшемся где-то в сети посередине между Бобом и Алисой. Но если бы оба клиента смогли предоставить достаточно информации о посланных ими пакетах SYN и сути ожидаемого от брокера ответа, то брокер соединения смог бы фальсифицировать посланные Алисе от Боба и Бобу от Алисы пакеты SYNIACK.

Автор назвал эти пакеты SYMIACK (Ack nowledgements both Sym metric and Sim ulated) ввиду того, что они являются подтверждением симметричности и имитации. Брокер имитирует передачу двух почти идентичных пакетов, но направленных в разные стороны сети. Эти специальным образом сформированные пакеты совместно используют не только одни и те же сходные структуры. Они позволяют обоим межсетевым экранам обслуживать симметричные состояния посредством цельного процесса подтверждения установления (квитирования) связи. Оба клиента посылают пакеты SYN, оба межсетевых экрана ожидают пакеты SYNIACK, оба клиента отправляют эти пакеты SYNIACK и одновременно предоставляют возможность послать пакеты-подтверждения АСК друг другу. (Конечно, поскольку ни один из межсетевых экранов не ожидает получения пакета подтверждения АСК, то есть необходимости в его уничтожении.) После того как две стороны будут удовлетворены процессом квитирования связи, будет установлена прекрасная двухсторонняя симметричная связь между двумя хостами, которые ранее не смогли переговорить друг с другом. Начиная с этого места брокеру нет необходимости что-либо делать. И действительно, как только две стороны (Алиса и Боб) обметаются несколькими первыми пакетами, брокер не сможет вторгнуться в сеанс, если даже он попробует это сделать (хотя, вероятно, он сможет послать фальсифицированное сообщение о недостижимости хоста по протоколу ICMP (ICMP Host Unreachable message) обеим сторонам, разрывая их связь).

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

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

этим данным относятся номер порта отправителя и начальный порядковый номер.

Сначала несколько слов о номере порта отправителя. Это число из диапазона от 0 до 65 535, которое используется клиентом для выделения нужного соединения среди любого числа возможных соединений с одним и тем же сервисом на одном и том же хосте. Стандартные межсетевые экраны просто передают этот номер порта дальше. Это означает, что Алиса может заранее выбрать номер порта. Она знает, что когда он испарится при передаче, то это будет означать, что номер порта был передан через межсетевой экран. Реализация трансляции сетевых адресов в межсетевых экранах может быть довольно изощренной. При трансляции межсетевой экран может поставить в соответствие одному IP-адресу целые сети, используя локальный номер порта для того, чтобы различать одно соединение от других. Поскольку теоретически эти соединения выбирают номер порта случайным образом, то обычно не имеет значения, если извне виден другой порт до тех пор, пока во время трансляции сетевых адресов внешние величины не будут преобразованы во внутреннее представление.

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

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

Конечно, никакое предположение не гарантирует правильного результата, но проверить его можно. Путем быстрого открытия многочисленных соединений к брокеру и контроля номеров порта, которые были выбраны при трансляции сетевого адреса, брокер сможет определить, являются ли выбранные порты отправителя полностью случайными, последовательными или каким-то образом предсказуемыми. Если номера портов полностью случайны, то хм это не является невозможным, но это откровенно плохое решение. Номера портов отправителя, как уже говорилось, расположены в диапазоне от 0 до 65 535. Под них отводится 16 бит энтропии. Без подсказки номера порта, который следует выбрать, можно только сохранять посланные пакеты SYMIACK со случайными номерами портов, пока не будет найден тот номер порта, по которому передавались данные. Но для этого для каждого удачно угаданного номера порта потребуется послать в среднем около 320 ООО пакетов (вероятно, получить ответ удастся после перебора примерно половины типового набора). В полном объеме это неосуществимо. Но если будет послано достаточное число обреченных SYN-пакетов, то они займут различные номера портов отправителя по одному и тому же IP-адресу, полученному в процессе трансляции сетевых адресов, и каждый из них будет считаться успешным соответствием в процессе согласования посланных пакетов SYMIACK.

Сколько для этого нужно пакетов? Удивительно, но всего лишь несколько. Ищется совпадение среди 65 ООО возможностей. Согласно теории, прежде чем будет найдена подходящая пара с шансами на успех не менее 50 %, следует перебрать число вариантов, приблизительно равных квадратному корню из всех возможных вариантов. (Это известно как парадокс дня рождения (Birthday Paradox), который назван так потому, что у собранных в комнате двадцати человек есть более пятидесятипроцентные шансы встретить в этой же комнате двух человек с одним и тем же днем рождения. Это несколько противоречит ожиданиям. Для каждого из находящихся в комнате человека шанс родиться в один из дней года оценивается как 365:1, но вполне логично, что чем больше в комнате людей, тем больше шансы на совпадение их дней рождения с заданной датой.) В случае с Алисой, посылающей 256 обреченных пакетов SYN, и брокером, фальсифицирующим поступившие от Боба 256 пакетов SYNIACK, шанс получения Алисой правильного пакета SYNIACK от Боба превышает 50 % (однако при этом Боб пострадает от шквала 255 TCP пакетов сброса соединения RST).

Несколько замечаний по поводу того, что в то время как число пакетов является большим, размер этих пакетов сравнительно невелик. Пустой пакет (пакет, не несущий содержательной информации) занимает в байтах немногим больше места, чем (в терминах libnet) LIBNET_ETH_H(Ethernet) + LIBNET IP H(IP) + LIBNET_TCP_H(TCP). Это всего лишь 14 + 20 + 20 байтов, или 54 байта. 256 х 54 равно почти 14 Кб, что, конечно, является огромным числом по стандартам установления связи, но это намного меньше среднего графического файла читателя. Именно это облегчает иначе невозможную связь. В некоторых сетях на уровне канала передачи данных, как, например, Ethernet, блоки информации канального уровня могут дополняться до 64 байт, но это размер все еще сравнительно небольшой.

Одна очень важная проблема заключается в необходимости знать, какие из многочисленных попыток установления соединения закончились успешно. Помните, трансляция сетевых адресов межсетевыми экранами осуществляется в обратном порядке: то, что видит внешний мир, преобразуется в то, что должна видеть частная сеть - в данном случае ее собственный частный IP-адрес и ее собственный выбранный номер локального порта. Это означает, что Алиса не может, только глядя на номер локального порта, узнать, какой пакет через него был получен. Алиса также не может спросить об этом у брокера. Брокер не знает этого, он только посылает пару сотен пакетов. Откуда он может узнать о пристрастиях и особенностях работы межсетевого экрана Алисы? Ответ должен был содержаться где-нибудь в пакете. Но где? Автор полагает, что, скорее всего, в поле IPID. Редко используемое поле используется для отличия одного пакета IP от другого независимо от протоколов более высокого уровня. Это поле может принимать одно из значений в пределах от 0 до 65 535. Будучи редко использованным, поле, вероятно, большинством межсетевых экранов не изменяется и, в отличие от номера локального порта, не транслируется. Так, если полю IPID будет присвоено значение номера порта адресата в пакете SYMIACK, то откуда бы пакет SYMIACK ни поступил, он сохраняет отметку, которая позволит ему передавать внутри заголовка IP нужные данные.

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

После установки соединения обязательно нужно достичь зеркальной симметрии номеров портов: номер порта адресата должен стать номером порта отправителя, и наоборот. Всегда известен номер порта, по которому данные отправляются, но не обязательно известно, кто их прослушивает. В конечном счете данные установления связи возвращаются с фальсифицированного сервера обратно, но при этом редко есть возможность установить, какой из возможных портов был прослушан. В данном случае возможность выбора даже не рассматривается. Счастье, что вообще есть связь. Более проблематичной является борьба за получение успешного пакета SYMIACK по заданному номеру порта отправителя. Очень важно, чтобы первоначально выбранный порт назначения соответствовал порту отправителя на другом конце соединения и был бы воспринят его межсетевым экраном. Если на той стороне соединения столько же проблем при получении доступа к определенному порту отправителя на межсетевом экране, что и на этой, то число требуемых попыток для установления соединения быстро приравняет к нулю любой шанс просачивания сессии TCP через межсетевой экран. Конечно, все возможно, только шансы того, что звезды и порты выровняются в зеркальную структуру, становятся чрезвычайно низкими. Это немного похоже на наши первоначальные условия - ограничения в управлении установления связи вплоть до случая подключения более ограниченного в своих возможностях сайта к более либеральному сайту.

И самое плохое. В случае использования межсетевого экрана Cisco PIX с отсутствующей опцией norandomseq порядковые номера, которые нужны для ответа каждому пакету TCP, становятся непредсказуемыми при переходе от одной сессии к другой. Поскольку порядковые номера занимают 32 бита, то потребуется 16 бит энтропии (65 ООО попыток) для достижения пятидесятипроцентного шанса получения пакетов SYMIACK. Автору остается только пожелать читателю удачи в этом начинании.

Конечно, по-прежнему остается нерешенным один из самых больших вопросов. Как раньше использовали рассмотренные системы? Наиболее вероятной причиной того, что способ обреченного установления связи не был разработан ранее, является то, что раньше это было невозможно. Нет никаких параметров сокета, которые позволяют определять, когда пакет должен прекратить свое существование. Уже не говоря о параметрах, которые бы точно определяли все выполняемые компоненты процедуры установления связи. Этого не было до второй половины 90-х годов, когда стало очевидным, что простое нападение на сайт большим числом запросов на соединение (лавиной пакетов SYN) от несуществующих хостов (которые не отвечают пакетами RSTIACK) явилось причиной проблем большинства сетевых стеков. Доступные инструментальные средства определяют технологию. Даже если несовершенные инструментальные средства к настоящему времени устарели, автор все еще не знает ни о каких системах, которые составили бы альтернативу ядру операционной системы при выполнении функций сетевых сервисов. Программа DoxRoute является первым и действительно внушающим доверие средством тонкой настройки сетевого трафика. Наиболее вероятно, что первыми системами, реализующими обсужденные в секции способы, будут решения в стиле программы DoxRoute с использованием библиотек libnet/libpcap. Хотя могут быть и другие решения.

Как говорят, все течет, все метается.

Резюме

В результате спуфинга до одного пользователя сети доводится фальсифицированная информация о данных идентификации другого пользователя, что позволяет последнему получить неавторизованный доступ к системе. Классическим примером спуфинга является спуфинг IP-протокола. Протоколы TCP/IP требуют, чтобы каждый хост указал в заголовке пакета адрес отправителя (собственный адрес), но практически нельзя на месте уличить хост во лжи, запретив ему записывать неверные данные. Спуфинг всегда преднамерен, он никогда не бывает случайным. Однако то, что некоторые сбои и ошибки в настройке программ вызывают точно такой же эффект, как и преднамеренный спуфинг, затрудняет определение целей содеянного. Если в силу каких-либо причин администратор сети захочет намеренно нанести обслуживаемой сети ущерб, то, как правило, он сможет правдоподобным образом объяснить свои поступки.

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

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

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

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

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

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

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

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

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

Изучение идентификационных данных захватывает. Идентификационным данным отводится центральное место в атаках спуфинга. Но они имеют самостоятельное значение. Эти данные являются наиболее важным стандартом безопасного взаимодействия и наиболее непризнанной и недооцененной потребностью. Их трудно найти, легко потребовать, невозможно доказать, но им неизбежно нужно доверять. Можно совершать ошибки. Вопрос состоит в том, можно ли спроектировать системы, которые переживут эти ошибки?

Автор желает читателю максимальной удачи при работе со своими системами.

Конспект

Определение спуфинга

• Мерике Кеао (Мепке Кеао) утверждает, что атаки спуфинга «обеспечивают ложную информацию об идентификационных данных для получения неавторизованного доступа к системе».

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

• Спуфинг не всегда злонамерен. Некоторые способы организации сети, как, например, доступ универсальных машин в Интернет или работоспособность большого числа \УеЬ-сайтов, основаны на том, что иногда квалифицируется как спуфинг.

Теоретические основы спуфинга

• Доверие свойственно человеку, и люди с древних пор знают об его уязвимости. Это открытие датируется эпохой Декарта, а скорее всего, еще более ранней.

• Доверие необходимо и неизбежно. Можно доверять чему-нибудь и кому-нибудь, но нельзя ничему и никому не доверять. Тем самым можно скатиться обратно к суеверию и личному удобству в оценке реальности. Мы не можем доверять всему, но мы должны довериться чему-либо и кому-либо. Поэтому жизнь заставляет решать постоянную задачу поиска того, чему и кому доверять.

Эволюция доверия

• Человеческое доверие случайно.

• Говорящий случайно отождествляет собственный голос с произносимыми словами.

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

• Перемещение случайно связывает человека с любым другим, кто случайно его увидел.

• Человеческое доверие асимметрично.

• Способность распознать голос человека еще не означает возможности его имитации при разговоре с кем-либо.

• Способность распознать отпечатки пальцев не означает возможности поменять свои пальцы на чьи-то другие.

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

• Человеческое доверие универсально.

• У человека нет возможности выбрать голос, отпечатки пальцев или уникальное лицо.

• Мы не доверяем легкокопируемым вещам, например популярным афоризмам или одежде.

У становление идентичности в компьютерных сетях

• Все переданные по компьютерной сети биты явно выбираются и одинаково видимы, их можно перезаписать и повторить с необходимой точностью.

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

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

Способность сомневаться

Способность к передаче: «Система может разговаривать со мной?» Иной раз при рассмотрении межсетевых экранов и недоверенных хостов ничего не говорится об их способности передавать данные по линиям связи.

Способность ответить: «Система может мне ответить?» Идея распространенного во многих протоколах первого рубежа защиты основана на том, что хосты, которым не следует доверять, не получат маркера (предопределенную комбинацию битов), который позволил бы им получить ответ от доверенного хоста.

Способность к кодированию: «Система может говорить на моем языке?» Наиболее опасный рубеж обороны. Он терпит катастрофу, когда идея его построения основана на предположении о незнании недоверенными хостами правил разговора по выбранному протоколу (хотя нет особой тайны в том, что будет сказано).

Способность доказывать знание разделяемого секрета: «Есть ли секретные данные, известные как мне, так и системе?» Наиболее общий рубеж защиты, к которому относятся пароли. К сожалению, этот рубеж легко преодолевается злоумышленником сразу после того, как пароли станут использоваться коллективно.

Способность подтвердить секретный ключ криптографической пары: «Я могу распознать ваш голос?» Этот уровень используется PGP и SSL. Он позволяет свободно распространять общедоступный ключ ключевой пары. Одновременно с этим личные и критические операции по расшифровке и подписи данных могут оставаться в безопасности.

Способность подтвердить подлинность криптографической пары: «Ключевая пара представляет идентичность системы независимым образом?» Используемая SSH и DROP способность подтвердить подлинность криптографической пары предотвращает компрометацию нынешних данных в будущем. Единственное, что должно сохранять свою силу в течение длинного периода времени, - это ключ данных идентификации. Все остальное, включая пароль, используемый для шифрования симметричных ключей, имеет меньшее значение.

Обман пользователей настольных компьютеров

• Автообновление приложений прокалывает дыры в защите сети межсетевыми экранами. Оно позволяет выполнить код, присланный недоверенными хостами, часто вообще без всякой проверки.

• Запрет на патчи систем клиента и их постоянная уязвимость взаимно исключают друг друга.

Эффект обмана

• Для уязвимости характерно, что кто-то может воспользоваться преимуществом различия между тем, чем что-либо является, и тем, чем оно кажется. С другой стороны, обман извлекает выгоду из различия между тем, что кто-то посылает кое-что, и тем, что кто-то, кажется, посылает это. Различие очень важное, потому что в основе наиболее бесчеловечных атак спуфинга лежит не только маскировка идентичности злоумышленника, но и сам факт его нападения.

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

• Протокол SSL может быть фальсифицирован с помощью способа, состоящего из трех шагов. Во-первых, увеличение длины URL для запутывания фактического адреса во всплывающем диалоговом окне. Во-вторых, создание строки состояния с включенным признаком «блокировки SSL» и выделение в самостоятельный элемент произвольного, но заслуживающего доверия с точки зрения графики, содержимого окна, j накладываемого на основную экранную форму. В-третьих, для большого правдоподобия может быть определен размер полноэкранного всплывающего прямоугольного окна без обеспечиваемых операционной системой границ или рамок. Впоследствии, по капризу удаленного сервера, они могут быть добавлены.

Малоизвестные подробности: разработка систем спуфинга

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

• Своим существованием библиотека Libnet доказывает возможность построения эффективного, переносимого с платформы на платформу инструментального средства генерации и посылки фальсифицированных пакетов по проводным каналам связи. Одновременно библиотека libpcap предоставляет противоположные функциональные возможности приема пакетов из канала связи. Комбинация названных инструментальных средств работает вполне прилично.

• Маршрутизатор, реализующий основные функции маршрутизации, должен отвечать на ARP-запросы разрешения «несуществующего» IP-адреса и выдавать ARP-ответы, обслуживающие «несуществующий» МАС-адрес аппаратного устройства, который перехватывает приходящие пакеты. Адресованные маршрутизатору пакеты утилиты ping могут быть перехвачены на месте и отосланы ей обратно. Что-либо еще, адресованное по правильному МАС-адресу, может рассматриваться как нечто, предназначенное для дополнительной сети. Конечно, рассмотренный маршрутизатор сильно упрощен, но тем не менее его можно реализовать.

Часто задаваемые вопросы

Вопрос: Есть ли хорошие решения противодействия спуфингу?

Ответ: Существуют решения, которые могут внести существенный вклад в предотвращение определенных типов спуфинга. Например, реализованный должным образом протокол SSH является хорошим решением удаленного терминала. Но ничто не совершенно. Протокол SSH уязвим к атакам типа «злоумышленник посередине», например во время первого обмена ключами. Если обеспечить безопасность получения ключей в первый раз, то об изменении ключей в последующем будет сообщено. Другой большой проблемой использования основанных на криптографии решений является централизованное распределение и управление ключами. Эта проблема уже обсуждалась в главе.

Вопрос: Какие инструментальные средства спуфинга доступны? Ответ: Большинство инструментальных средств спуфинга относятся к сфере сетевых средств. Например, в главе 11 рассказано об использовании инструментальных средств, которые могут как фальсифицировать, так и перехватывать (похищать) сессии, решая задачи активного спуфинга. Другие инструментальные средства спуфинга предназначены для работы с DNS, IP, SMTP и многим другим.

Вопрос: Существуют ли способы проверки получения фальсифицированных пакетов? Ответ: Как правило, фальсифицированные пакеты посылаются вслепую, поэтому «хост отправителя» будет вести себя подозрительно, будто он и вправду не получает никаких ответов на свои пакеты. Забавно, не правда ли? Но только что был обнаружен блестящий способ простого и в разумной степени надежного определения, является ли пакет, полученный от другого отправителя, фальсифицированным. Принцип работы программы Despoof, разработанной печально известным Simple Nomad, основан на следующем простом предположении: нападающий не знает числа сетевых «прыжков» (ближайших маршрутизаторов, находящихся на расстоянии одного «прыжка»), которые нужно совершить хосту для передачи пакета адресату. Поскольку в большинстве случаев маршрутизация в Интернете симметрична, то число «прыжков» к выбранному хосту дает адекватную оценку числа «прыжков», необходимых для ответного сообщения. (Ошибочно полагать, что при простом прозванивании хоста утилитой ping и контроле числа вычитаний единицы из значения счетчика предписанного времени жизни пакета TTL во время обратного путешествия пакета будет получено верное значение числа «прыжков» до хоста адресата. На самом деле будет возвращено число «прыжков», далекое от истинного значения.) Вот что интересно. Злоумышленник не сможет проверить сеть между хостом читателя и фальсифицируемым им узлом. Сравнивая число «прыжков» во время путешествия тестирующего пакета с установленным числом фактически сделанных «прыжков», можно определить, что пакет передавался от отправителя до адресата по неправильному маршруту, и поэтому вполне возможно, что он фальсифицирован. Число «прыжков» во время путешествия тестирующего пакета можно определить по значению ORIGINAL TTL-TTL OFPACKET, которое обычно равно двум в степени некоторого смещения минус число между единицей и двенадцатью. Достаточно интересно, что таким образом можно что-то узнать о фальсификаторе, потому что число пройденных «прыжков» характеризует его сетевой путь. Конечно, фальсификатор вполне может фальсифицировать исходную величину счетчика предписанного времени жизни пакета TTL, для того чтобы защитить себя от такого сетевого мониторинга. Но пока злоумышленник не знает о возможности подобных действий, он так делать и не будет. Если не будут выполнены какие-либо отвлекающие действия, то можно определить, что злоумышленный трафик начинается с середины маршрута, как будто это сетевая атака. Конечно, это вопрос выбора рисков читателя. Программу Despoof можно найти по адресу http://razor.bindview.com/tools/desc/despoof_readme.html. Это действительно интересное инструментальное средство.

Вопрос: Каким образом атакующий сможет перенаправить сетевой трафик так, чтобы он казался пришедшим от других хостов? Ответ: Простейшие и наиболее эффективные способы захвата хоста одной и той же физической подсети описаны в главе 11. Изредка возможно похищение сетевого трафика вне подсети при помощи компрометации промежуточных маршрутизаторов, но наиболее часто это осуществляется с помощью DNS-серверов. Дэвид Уелевич (David Uelevich), основатель Everydns.Net, пишет: «Когда ищется запись домена на сервере имен, то это обычно сервер имен клиентской сети, который осуществляет поиск и по очереди возвращает ответ клиенту. Проблема с «отравлением» DNS возникает в случае, когда сервер имен клиентов воспринимает неверную информацию от удаленного сервера, который либо преднамеренно, либо случайно бездумно раздает коды возврата, изменяющие поведение клиентов сервера имен». Помните, IP-адреса обычно не указывают непосредственно на адресата. (Действительно, в протоколе IPV6 почти невозможно непосредственно указать адресата. Длина адресов в протоколе IPV6 почти в 4 раза длиннее IP-адреса в протоколе IPV4.) Обычно на адресата ссылаются по DNS-имени. Компрометация отображения DNS-имен в IP-адреса будет иметь тот же самый эффект, как если бы оказалось взломано соответствие между приятелем читателя и его телефонным номером. В конце концов, читатель сможет распознать, что на другом конце линии находится не его приятель, а кто-то другой, но компьютер - нет, за исключением, пожалуй, случая использования для такой попытки подключения протокола SSL. В подобном случае нападающий, как брокер соединения, может законным образом перенаправить читателя к его фактическому адресату.

Вопрос: Достаточно ли протокол SSL защищен от спуфинга? Ответ: Это хороший протокол, надежность которого определяется корректной реализацией (по крайней мере, в настоящее время придерживаются такой точки зрения). Но не здесь кроется опасность. Протокол SSL основан на цепочке заверяющих подписей в соответствии с инфраструктурой открытого ключаРЮ (PublicKey Infrastructure). Если читатель смог бы незаметно вставить собственную копию Netscape в тот момент, когда кто-либо обновляет его в режиме автоматического обновления, то у него появилась бы возможность включить собственный ключ подписи для «VeriSign» и претендовать на то, чтобы стать любым сервером HTTPS в мире. С другой стороны, большому числу международных и главным образом неизвестных компаний доверяют только потому, что «VeriSign» хранит их ключи подписи в безопасности. Сомнительно, что многие заботятся о своей безопасности в той же мере, как «VeriSign» заявляет о безопасности их секретных ключей. Компрометация любого из этих международных провайдеров будет эквивалентна ущербу от компрометации ключа «VeriSign». Тот, кто сможет добиться успеха при фальсификации, может стать кем угодно. Вызывает беспокойство и то, что SSL не может всегда оставаться передовым средством обеспечения безопасности. Компрометация ключа в будущем, которая в настоящее время практически невозможна, немедленно сделает сегодняшний трафик общедоступным завтра. В этом заключается позорная уязвимость, которой нет места в главном стандарте криптографической защиты.

Малоизвестные подробности: разработка систем спуфинга | Защита от хакеров корпоративных сетей | Туннелирование


Защита от хакеров корпоративных сетей



Новости за месяц

  • Июль
    2019
  • Пн
  • Вт
  • Ср
  • Чт
  • Пт
  • Сб
  • Вс