Злой роутинг. Проворачиваем хитроумную атаку MITM в Wi-Fi-сети
Форсайт
Атака «человек посередине», пожалуй, первое, что приходит на ум, когда возникает задача получить пользовательские данные, такие как логины и пароли к различным сервисам, а также передаваемую информацию: почту, сообщения мессенджеров и прочее. ARP-спуфинг, DNS-спуфинг, ICMP-редирект, Evil twin — про все эти техники ты уже, возможно, слышал. В данной статье я расскажу тебе про еще один способ устроить MITM в Wi-Fi-сети, не самый простой, но работоспособный.
Материал адpесован специалистам по безопасности и тем, кто собираeтся ими стать. Вся информация предоставлена исключительно в ознакомительных целях. Ни редакция, ни автор не несут ответственности за любой возможный вред, причиненный материалами данной статьи.
Преамбула
Итак, как и всегда, для данной атаки есть пара ограничений:
- Мы должны быть подключены к атакуемой точке доступа.
- У нас должна быть возможность прослушивать широковещательный трафик в сети и перехватывать широковещательные запросы DHCPDISCOVER, DHCPREQUEST и ARP, чтобы обнаруживать конфликты адресов в локальной сети.
Итак, как же это работает? Атака разделяется на несколько этапов:
- Производим атаку DHCP Starvation.
- Отправляем Wi-Fi Deauth пакеты.
- Перехватываем ARP-запросы от клиентов, отвечаем на них, чтобы создать конфликт IP-адресов и принудить клиента отправить DHCPDECLINE.
- Перехватываем запросы DHCPDISCOVER и DHCPREQUEST, отвечаем на них.
- Profit!
Разберемся в этой схеме поподробнее.
DHCP Starvation
Подключаемся к атакуемой Wi-Fi-сети и производим атаку DHCP Starvation с целью пополнить пул свободных IP-адресов. Для этого необходимо выполнить следующие шаги.
Формируем и отправляем широковещательный DHCPDISCOVER-запрос, при этом представляемся как DHCP relay agent. В поле giaddr (Relay agent IP) указываем свой IP-адрес 192.168.1.172, в поле chaddr (Client MAC address) — рандомный MAC 00:01:96:E5:26:FC, при этом на канальном уровне в SRC MAC выставляем свой MAC-адрес: 84:16:F9:1B:CF:F0.

Сервер отвечает сообщением DHCPOFFER агенту ретрансляции (нам) и предлагает клиенту с MAC-адресом 00:01:96:E5:26:FC IP-адрес 192.168.1.156.

После получения DHCPOFFER отправляем широковещательный DHCPREQUEST-запрос, при этом в DHCP-опции с кодом 50 (Requested IP address) выставляем предложенный клиенту IP-адрес 192.168.1.156, в опции с кодом 12 (Host Name Option) — рандомную строку dBDXnOnJ. Важно:значения полей xid (Transaction ID) и chaddr (Client MAC address) в DHCPREQUEST и DHCPDISCOVER должны быть одинаковыми, иначе сервер отбросит запрос, ведь это будет выглядеть как другая транзакция от того же клиента либо другой клиент с той же транзакцией.

Сервер отправляет агенту ретрансляции сообщение DHCPACK. С этого момента IP-адрес 192.168.1.156 считается зарезервированным за клиентом с MAC-адресом 00:01:96:E5:26:FC на 12 ч(время аренды по умолчанию).


Wi-Fi Deauth
Следующим шагом проводим Wi-Fi Deauth. Работает эта схема примерно так.

Подробнее о деаутентификации клиентов в Wi-Fi-сети можно почитать здесь и здесь.
Переводим свободный беспроводной интерфейс в режим мониторинга:

Отправляем deauth-пакеты с целью отсоединить атакуемого клиента 84:16:F9:19:AD:14 Wi-Fi-сети ESSID: WiFi DHCP MiTM.

DHCPDECLINE
После того как клиент 84:16:F9:19:AD:14 отсоединился от точки доступа, вероятнее всего, он заново попробует подключиться к Wi-Fi-сети WiFi DHCP MiTM и получить IP-адрес по DHCP. Так как ранее он уже подключался к этой сети, то будет отправлять только широковещательный DHCPREQUEST.

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

Естественно, такой запрос широковещательный, поэтому мы можем его перехватить и ответить на него.

После этого клиент фиксирует конфликт IP-адресов и отправляет широковещательное сообщение отказа DHCP — DHCPDECLINE:

DHCPDISCOVER
Итак, последний этап атаки. После отправки DHCPDECLINE клиент с самого начала проходит процедуру получения IP-адреса, а именно отправляет широковещательный DHCPDISCOVER. Легитимный DHCP-сервер не может ответить на этот запрос, так как пул свободных IP-адресов переполнен после проведения атаки DHCP Starvation и поэтому заметно тормозит, зато на DHCPDISCOVER можем ответить мы — 192.168.1.172.
Клиент 84:16:F9:19:AD:14 (Win10-desktop) отправляет широковещательный DHCPDISCOVER.

Отвечаем DHCPOFFER.

В DHCPOFFER мы предложили клиенту IP-адрес 192.168.1.2. Клиент, получив данное предложение только от нас, отправляет DHCPREQUEST, выставляя при этом в requested ipзначение 192.168.1.2, и мы отвечаем DHCPACK.
Клиент 84:16:F9:19:AD:14 (Win10-desktop) отправляет широковещательный DHCPREQUEST.

Отвечаем DHCPACK.

Клиент принимает наш DHCPACK и в качестве шлюза по умолчанию и DNS-серверавыставляет наш IP-адрес: 192.168.1.172, а DHCPNACK от точки доступа, присланный на две секунды позже, просто проигнорирует.

Вопрос: почему точка доступа прислала DHCPOFFER и DHCPNACK на две секунды позже, да еще и предложила тот же IP-адрес 192.168.1.102, ведь клиент отказался от него?

Чтобы ответить на этот вопрос, немного изменим фильтр в Wireshark и посмотрим ARP-запросы от точки доступа.

Ответ: после проведения атаки DHCP Starvation у DHCP-сервера не оказалось свободных IP-адресов, кроме того, от которого отказался один из клиентов: 192.168.1.102. Поэтому, получив DHCPDISCOVER-запрос, DHCP-сервер в течение двух секунд отправляет три ARP-запроса, чтобы узнать, кто использует IP-адрес 192.168.1.102, и после того, как сервер убедится, что данный IP-адрес свободен, поскольку никто не ответил, выдает его клиенту. Но уже слишком поздно: злоумышленник успел ответить быстрее.
Результаты
Таким образом, мы можем выставлять любые сетевые параметры: шлюз по умолчанию, DNS-сервер и другие — любому подключенному или новому клиенту в атакуемой Wi-Fi-сети, при условии, что мы к ней уже подключены и можем прослушивать широковещательный трафик.
PoC
Ну и конечно же, PoC.
Послесловие. Apple vs DHCP
Как оказалось, macOS и iOS переплюнули всех в плане получения сетевых настроек по протоколу DHCP. Когда эти операционные системы отправляют DHCPREQUEST, DHCP-сервер отвечает им DHCPACK, и они выставляют сетевые настройки из ответа сервера. Вроде пока все как у всех:

Но проблема в том, что DHCPREQUEST широковещательный и злоумышленник, как правило, без особых проблем может его перехватить и ответить DHCPACK, но, конечно, позднее легитимного DHCP-сервера, то есть ответ злоумышленника приходит вторым. Все остальные DHCP-клиенты на других ОС просто проигнорируют второй DHCPACK, но на macOS и iOS все не так.
Как ты думаешь, какие настройки выставляют данные операционные системы? Ответ: те настройки, которые будут содержаться в DHCPACK злоумышленника (во втором DHCPACK ~~во втором DHCPACK, Карл!~~).

Как ты думаешь, баг это или фича? Я подумал — баг и на всякий случай завел заявку на Apple Bug Reporter. Скоро этой заявке исполнится месяц, но ни одного комментария от специалистов Apple я так и не получил.

На заявке в Apple Bug Reporter я не остановился и написал письмо в product-security@apple.com.

Специалисты Apple совсем не быстро, но все же ответили и сказали, что их DHCP-клиент работает в соответствии с RFC 2131. То есть это не бага, а фича — вот и конец истории.
Apple Wifi MiTMer
Для самых ленивых я подготовил скрипт apple_wifi_mitmer.py, который в автоматическом режиме находит все устройства компании Apple в Wi-Fi-сети, деаутентифицирует и выставляет на них в качестве шлюза и DNS-сервера свой IP-адрес.
В аргументах скрипта всего-то нужно указать имя беспроводного интерфейса, который уже подключен к исследуемой Wi-Fi-сети, и еще один беспроводной интерфейс для отправки deauth-пакетов. Как это работает, можно посмотреть тут.