Я хочу продемонстрировать решение задачи, которое большинством «сетевиков» считается невозможной в принципе. Речь идет о вычислении физического местоположения хоста в неуправляемой сети. Под неуправляемой сетью подразумевается сеть на неуправляемых коммутаторах, а под определением местоположения — ответ:
«такой-то хост подключен к свичу, который находится здесь»
Сразу оговорю входные условия:
— я являюсь администратором, т.е знаю топологию сети;
— у меня есть база абонентов, точки подключения которых мне известны.
Нарушения топологии сети, а также жульничество со стороны абонентов (обмен ip, смена точки подключения) в некоторой степени уменьшают точность результата. Тем не менее, я регулярно пользуюсь данным алгоритмом в своей сети и он показывает довольно точные данные.
В чем сложность?
Неуправляемая сеть — это черный ящик, любой ethernet фрейм, который приходит к вам, не обладает никакой информацией через какие коммутаторы он прошел. Неуправляемый свич — это прозрачное устройство, оно никак не изменяет фреймы, только лишь направляет их в нужные (на его взгляд) порты.
Таким образом, мы не можем получить информацию о пути прохождения ни из ethernet фреймов ни от свичей.
На самом же деле, это не совсем так. Информацию запросить у коммутаторов мы не можем, но у нас есть возможность менять их поведение и анализировать рузультат.
Как известно, каждый неуправляемый коммутатор имеет таблицу соответствий mac-port. Эта таблица обновляется каждым входящим фреймом по очень простому алгоритму: на какой порт пришел фрейм, к тому порту привязывается mac-адрес из поля src-mac текущего фрейма. В дальнейшем любой пришедший фрейм с dst-mac как у текущего, будет направлен строго в порт, ассоциированный с этим mac.
В процессе, таблица mac-адресов может изменяться, если фрейм с точно таким же src-mac войдет в другой порт. В этом случае старая информация «забывается». Обычно такая ситуация возникает, когда вы перекоммутируете кабели. На этой «особенности» основан алгоритм обнаружения.
Не буду затягивать с теорией и приведу его.
Итак. Мы имеем неуправляемую гирлянду свичей (суровая реальность мелких домашних сетей), выбираем одну из веток. На конце этой ветки выбираем любого абонента. Его я называю агентом. Он выполняет ключевую роль — поиск неизвестного хоста (в скриптах я называю его hacker) будет происходить на участке сервер-агент. Таким образом, в качестве агента желательно выбрать наиболее удаленного абонента.
Начинается итерация:
1) Arp-запросами запрашиваются ip агента и ip хакера. Ip могут находится в разных логических подсетях, для нас это неважно. Важно то,
что arp-запросами мы «переводим» сеть в ее нормальное состояние, поскольку в дальнейшем будем немного ее дестабилизировать.
2) Берем из базы любого абонента, местоположение, которого нам известно. Я называю его user. Осуществляем ethernet-спуффинг путем посылки arp-request:
src-mac — hacker mac
src-ip — неважно (можно hacker или фейковый ip)
dst-mac — user mac
dst-ip — user ip (можно фейковый ip)
Цель данного пакета — «перепрограммировать» порты (изменить таблицу MAC-адресов) в цепочке свичей от сервера до user маком hacker-а. Если в сети на «перепрограммированном» участке кто-либо отправит пакет на MAC хакера, он будет получен нашим сервером, а не хакером.
3) На агента посылается arp-request:
src-mac — hacker mac
src-ip — неважно (можно hacker или фейковый ip, важно чтоб в подсети agent-а)
dst-mac — agent mac
dst-ip — agent ip
Данным пакетом, мы заставляем агента ответить на arp-запрос, который пришел якобы от хакера.
Необходимо отметить очень важный момент: инкапсуляцию протоколов. Дело в том, что arp-запрос имеет свои данные, но он «упаковывается» в ethernet-фрейм, который имеет свои данные. В частности src-mac при стандартном использовании arp-request, что в arp-пакете, что в ethernet-фрейме совпадают. В отличие от предыдущего пакета, нам нужно осуществить именно arp-спуффинг, но не ethernet! Т.е. в ethernet фрейме src-mac должен быть нашего сервера, а в arp пакете src-mac = hacker mac. Если это условие будет соблюдено, то коммутаторы, через которые пройдет фрейм, не изменят свои таблицы MAC-адресов.
4) На сервере переключаемся в promiscuous режим (т.е не отбрасываем пакеты, которые идут к нам, но не на наш адрес) и мониторим arp-reply.
Если:
а) получаем пакет направленный на hacker mac — значит географически hacker находится между user и сервером
б) не получаем — вероятно hacker находится за user
Во 2-м случае нет абсолютной гарантии, поэтому необходимо повторить несколько раз все пункты чтобы повысить вероятность, а также принять во внимание данные при тестировании на других абонентах.
На рисунке имеем цепочку из 4х коммутаторов. Красной линией обозначен путь прохождения пакета в пункте 2. В результате произойдет «перепрограммирование» таблицы мак-порт ближайшего к серверу свича так, что он будет думать «хакер подсоединен к порту №1». Никакие другие свичи не изменят своего состояния т.к пакет не пройдет через них.
После запроса server -> agent (пункт 3), последний отсылает ответ на мак хакера т.к. src-mac был подменен. Поскольку на участке Hacker-Agent все свичи не меняли своего состояния, пакет беспрепятственно дойдет до хакера.
В случае, когда User находится на участке Hacker-Agent, ответ агента придет на сервер:
5) Переходим к пункту 1 и выбираем следующего user
В конце тестирования мы имеем таблицу: user — получен/не получен ответ от агента. Если выложить данные на карту (а мой скрипт так и делает), то администратор мгновенно отсеивает мелкие отклонения (обычно их нет) и получает очень точный результат: хакер находится на стыке блоков получен/не получен ответ.
Все, что я здесь описал, повторюсь, мною реализовано на практике: скрипты написаны на perl (use Net::Packet; use Net::Packet::Dump;).
Автор: ef_end_y