Защита от хакеров корпоративных сетей
Шрифт:
В этих строчках кода присутствует стеснительный и, вероятно, ненужный хакинг. Важно, что создан статический массив для заполнения различных адресов: собственного IP-адреса, MAC-адреса маршрутизатора, которому будет передан пакет, и т. д. Но благодаря странностям функции sscanf и тому факту, что при быстрой работе утрачивается некоторая безопасность, буфера перезаписываются странными и не до конца выясненными способами. Буфера можно очистить, создавая буфер одного из устройств большего, чем это действительно нужно, размера. Этот способ не очень элегантен, он даже уродлив, но вполне работоспособен. Для правильного решения возникшей проблемы необходимо написать собственный вариант функции sscanf, выполняющий правильный разбор способов задания MAC– и IP-адресов, но автор попытался
char errbuf[255];
int do_checksum = 0;
int verbose = 0;
int i = 0;Установка значений по умолчанию. Одна важная особенность, присущая всем программам, заключается в задании их поведения по умолчанию. Тем самым минимизируется объем знаний, необходимых программе во время ее первого запуска. Например, Web-серверам не обязательно указывать имя домашней страницы всякий раз, когда кто-либо подключается кПо умолчанию если не указано ничего другого, то при подключении по этому адресу пользователю возвращается ответ, как если бы он запросилТочно так же следует установить значения по умолчанию для маршрутизации пакетов:
/* Set Broadcast MAC to FF:FF:FF:FF:FF:FF*/
bcast_mac[0] = 0xFF;
bcast_mac[1] = 0xFF;
bcast_mac[2] = 0xFF;
bcast_mac[3] = 0xFF;
bcast_mac[4] = 0xFF;
bcast_mac[5] = 0xFF;Иногда выбор установленных по умолчанию значений не представляет большого труда. Основные стандарты Ethernet определяют, что при задании в пакетах MAC-адреса FF: FF: FF: FF: FF: FF эти пакеты должны получить все хосты данной подсети. Локальная сеть на основе протокола Ethernet только недавно стала переключаемой средой, поэтому ранее использование адреса FF: FF: FF: FF: FF: FF больше носило характер «рекомендательного» сообщения для сетевых плат, которые должны были передать этот пакет операционной системе даже в том случае, если это сообщение не было адресовано определенному хосту. Ныне сетевые платы не видят сетевой трафик до тех пор, пока переключатель не посчитает, что он предназначен заданному хосту. В программе широковещательная рассылка MAC-адресов осуществляется следующим образом. Во многих протоколах предусмотрен запрос ко всем хостам локальной подсети. Для наших целей наиболее уместен протокол ARP:
/* Set Default Userspace MAC Address to 00:E0:B0:B0:D0:D0 */
user_mac[0] = 0x00;
user_mac[1] = 0xE0;
user_mac[2] = 0xB0;
user_mac[3] = 0xB0;
user_mac[4] = 0xD0;
user_mac[5] = 0xD0;Покажем, как можно в сети создать виртуальную сетевую карту, определив по умолчанию ее сетевой адрес отправителя. В действительности можно использовать любой адрес. Тривиальным и зачастую хорошим решением была бы рандомизация этого значения. Но рандомизация подразумевает, что нельзя будет по желанию запускать и останавливать маршрутизатор. Каждый раз при старте маршрутизатора в фоновом режиме хосты должны будут повторно назначить IP-адрес шлюза. Для этого им нужно будет заняться поиском новых обслуживаемых MAC-адресов. (Если читатель решит реализовать рандомизацию, то ему следует позаботиться о том, чтобы младшие значащие биты первого байта user_mac[0] не были установлены. А если они будут установлены, то в результате будет получен групповой MAC-адрес в локальной сети, использование которого приводит к очень интересным результатам.)
/* Set Default Upstream IP */
upstream_ip[0] = 10;
upstream_ip[1] = 0;
upstream_ip[2] = 1;
upstream_ip[3] = 254;Програма DoxRoute не является законченной реализацией маршрутизатора. Это лишь его скелет. Фактически пакеты только отсылаются реальному шлюзу. Исходя из опыта, адрес 10.0.1.254 обычно используется для шлюзования пакетов частных сетей, в которых должна быть выполнена программа DoxRoute. Кстати, вовсе не случайно переменной user_ip не устанавливается значение по умолчанию. Причина подобных действий известна как политика добрососедства: когда это возможно, то не следует рушить существующих систем. Любой отправленный IP-адрес может иметь вполне определенный смысл для уже развернутых систем. Вместо этого пусть пользователь найдет свободный IP-адрес и займется анализом проходящего через него сетевого трафика. Более сложная реализация предусматривала бы для нахождения свободного адреса использование протокола динамической конфигурации хоста DHCP, но это наложило бы довольно серьезные ограничения для клиентов, пожелавших направить сетевой трафик
/* Set Default Interface */ snprintf(dev, sizeof(dev), “%s”, pcap_lookupdev(NULL));
В оперативной странице руководства сказано, что «pcap_lookupdev возвращает указатель на сетевое устройство, который может быть использован функциями pcap_open_live и pcap_lookupnet. В случае ошибки возвращается значение NULL и в переменную errbuf записывается соответствующее сообщение об ошибке». Это немного непонятно. На самом деле возвращается указатель на строку, содержащую имя устройства, которую мы покорно запоминаем для возможного будущего использования. Командная строка: использование параметров командной строки для того, чтобы избежать жестко запрограммированных зависимостей. Ах, функция getopt. Эта стандартная функция очень полезна для разбора командной строки в стиле UNIX. Но ее работа не столь понятна, как, допустим, написание программ с ее помощью. Пример добротного использования функции getopt приведен ниже:
/* Parse Options */
while ((opt = getopt(argc, argv, «i:r:R:m:cv»)) != EOF) {
switch (opt) {
case “i”: /* Interface */
snprintf(dev, sizeof(dev), “%s”, optarg);
break;
case “v”:
verbose = 1;
break;Устанавливается цикл разбора всех параметров командной строки. Переменной цикла является счетчик аргументов, который каждый раз уменьшается на единицу и который указывает на первый найденный аргумент командной строки. Кроме того, задается строка, определяющая анализируемые флаги. В любой командной строке программы различают два основных вида параметров. Первый задает дополнительные аргументы, как, например, doxroute – i eth0. Второй является полностью законченным и самодостаточным, как, например, doxroute -v. Функция getopt представляет оба эти типа параметров как i: v. Двоеточие после i является признаком анализируемого аргумента, а указатель optarg должен указывать на аргумент. Отсутствие двоеточия после v означает, что простое присутствие флажка является достаточным поводом для завершения работы (в этом случае для большинства приложений установка глобальной переменной в единицу активизирует генерацию диагностики):
case “r”: /* Router IP */
sscanf(optarg, “%hu.%hu.%hu.%hu”,
&upstream_ip[0], &upstream_ip[1],
&upstream_ip[2],
&upstream_ip[3]);
break;
case “R”: /* Router MAC */
sscanf(optarg, “%X:%X:%X:%X:%X:%X”,
&upstream_mac[0], &upstream_mac[1],
&upstream_mac[2],
&upstream_mac[3], &upstream_mac[4],
&upstream_mac[5]);
break;
case “m”: /* Userspace MAC */
sscanf(optarg, “%X:%X:%X:%X:%X:%X”,
&user_mac[0], &user_mac[1], &user_mac[2],
&user_mac[3], &user_mac[4],
&user_mac[5]);
break;Для анализа адресов применены не самые хорошие способы, но тем не менее они работают. Такой способ решения был выбран для того, чтобы противостоять взлому из-за ошибок обработки типов:
case “c”: /* Checksum */
do_checksum = 1;
break;
default:
usage;
}
}
/* Retrieve Userspace IP Address */
if (argv[optind] != NULL) {
sscanf(argv[optind], “%hu.%hu.%hu.%hu”,
&user_ip[0], &user_ip[1], &user_ip[2],
&user_ip[3]);
} else
usage;Чего функция getopt не может предусмотреть, так это отсутствия флажков. Другими словами, ситуацию отсутствия флажков следует предусмотреть именно в этом месте. Здесь же (в функции usage) можно затребовать наиболее важные данные для работы программы – реализовать тайный прием IP-адресов. Следует отметить, что, как правило, функция usage почти всегда завершает программу с флагом ошибки. Обычно это свидетельствует о неправильных действиях пользователя и необходимости вызова RTFM для уточнения ошибки. Запуск Libpcap. Следующее, что потребуется сделать для подготовки к фактическому мониторингу сети с целью поиска интересного трафика, – это спланировать свою реакцию: