MITM-атака: как кто-то встаёт между тобой и сервером

Разбираю, как работает атака «человек посередине» на уровне протоколов: ARP-спуфинг, подмена DNS, SSL stripping. И что реально мешает злоумышленнику влезть в твой трафик.

Представь, что ты пишешь записку и просишь соседа по парте передать её другу на другом конце класса. Сосед может прочитать записку. Может подменить пару слов. Может вообще выкинуть твою и написать свою — а ты и не узнаешь, потому что ответ придёт обратно через того же соседа. Вот это и есть атака «человек посередине», или MITM (Man-in-the-Middle). Только вместо парты — сеть, а вместо соседа — тот, кто умеет встать на пути твоего трафика.

Звучит как что-то из шпионских фильмов, но на деле это одна из самых старых и до сих пор живых сетевых атак. Я долго относился к ней как к учебному примеру из курса по сетям — пока однажды не поймал себя на мысли, что подключаюсь к банку через вокзальный Wi-Fi без VPN. Тогда и захотелось разобраться, что именно тут может пойти не так.

Суть атаки

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

  ТЫ  ──────────────────────────────►  СЕРВЕР
      ◄──────────────────────────────

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

  ТЫ  ──────►  ЗЛОУМЫШЛЕННИК  ──────►  СЕРВЕР
      ◄──────                 ◄──────
                    │
                    ▼
            читает и подменяет

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

Удобно делить MITM на два этапа. Сначала встать на пути трафика — это про сеть. Потом уже разобраться с шифрованием — это про TLS. Дальше разберу оба.

Этап первый: встать на пути

ARP-спуфинг

Самый классический способ влезть в трафик внутри локальной сети — например, той самой публичной Wi-Fi-сети в кафе.

Внутри сети устройства находят друг друга не по IP, а по MAC-адресам — физическим адресам сетевых карт. Чтобы узнать, какой MAC соответствует нужному IP, компьютер кричит на всю сеть: «у кого IP 192.168.1.1 (это роутер), отзовитесь своим MAC?». Кто отозвался — тому и шлём. Этот механизм называется ARP.

Проблема в том, что ARP никого не проверяет. Любой ответ принимается на веру. Злоумышленник просто отвечает на чужие запросы: «IP роутера — это мой MAC». И заодно говорит роутеру обратное: «IP твоего ноутбука — тоже мой MAC». Теперь весь трафик между тобой и роутером идёт через машину атакующего.

            КАК ДОЛЖНО БЫТЬ
   ТЫ  ──────►  РОУТЕР  ──────►  ИНТЕРНЕТ

            ПОСЛЕ ARP-СПУФИНГА
   ТЫ  ──────►  АТАКУЮЩИЙ  ──────►  РОУТЕР  ──────►  ИНТЕРНЕТ
        «я роутер»     │
                       ▼
                 весь трафик у него

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

Подмена DNS

DNS — это телефонная книга интернета. Ты вводишь mybank.ru, а DNS превращает имя в IP-адрес, к которому реально пойдёт соединение. Запросы эти исторически ходят открытым текстом и без подписи.

Если атакующий уже встал между тобой и роутером (см. ARP выше), он ловит твой DNS-запрос и отвечает раньше настоящего сервера: «mybank.ru — это вот такой IP» — и подсовывает адрес своей машины. Браузер честно идёт по этому адресу, открывает копию сайта банка, ты вводишь логин и пароль — и отдаёшь их прямо в руки.

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

Поддельная точка доступа

Иногда даже спуфить ничего не надо. Достаточно поднять Wi-Fi-точку с названием вроде Free_Airport_WiFi и подождать. Телефоны вокруг сами цепляются к знакомым или к открытым сетям, и весь их трафик с самого начала идёт через тебя. Встраиваться ни во что не нужно — ты и так уже посередине.

Этап второй: что делать с HTTPS

Допустим, трафик жертвы пошёл через атакующего. Но сейчас почти всё ходит по HTTPS, и просто прочитать его не выйдет — он зашифрован. Тут и начинается интересное.

SSL stripping

Самый коварный приём, придуманный ещё в 2009 году Мокси Марлинспайком. Он бьёт не по шифрованию, а по моменту до него.

Смотри, как обычно происходит вход на сайт. Ты редко пишешь https:// руками — чаще просто mybank.ru или жмёшь старую ссылку. Браузер сначала стучится по http://, а сервер отвечает: «иди на https://». И только потом начинается защищённое соединение. Вот эта первая открытая секунда — дыра.

Атакующий перехватывает тот самый первый HTTP-запрос. С сервером он сам устанавливает честный HTTPS, а тебе отдаёт обычный HTTP. Для сервера всё выглядит нормально — он говорит с кем-то по HTTPS. А ты сидишь на HTTP и не видишь ни замочка, ни предупреждений. Просто страница без шифрования, на которую ты вводишь пароль открытым текстом.

   ТЫ ──http──► АТАКУЮЩИЙ ──https──► СЕРВЕР
      (открыто)           (зашифровано)

   Сервер думает: всё ок, HTTPS.
   Ты думаешь: ну, сайт как сайт.
   Пароль улетает открытым текстом.

Самое противное — тут нет ошибки сертификата, на которую можно среагировать. Замочка просто нет, а на его отсутствие почти никто не смотрит.

Поддельный сертификат

Второй путь — не понижать HTTPS, а попытаться его подделать. Атакующий подсовывает свой сертификат на mybank.ru. В норме браузер тут же поднимет тревогу: сертификат подписан не тем, кому доверяет система, — и покажет красный экран с предупреждением.

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

Отсюда правило, в которое стоит въесться намертво: никогда не проматывай предупреждение браузера о сертификате. Это ровно тот момент, когда защита кричит, что её пытаются обойти.

Что реально защищает

Хорошая новость: за годы против MITM накопился крепкий набор контрмер. Плохая — работают они слоями, и ни один слой сам по себе не закрывает всё.

  • HTTPS везде и без HTTP-версии. Пока есть хоть одна открытая страница, есть и щель для SSL stripping. Сайт должен говорить только по HTTPS.
  • HSTS. Заголовок, которым сервер говорит браузеру: «ко мне ходи только по HTTPS, даже не пробуй HTTP». А если домен попал в встроенный в браузеры preload-список, то и самый первый запрос уже не уйдёт открытым. Это и есть прямое лекарство от SSL stripping.
  • Проверка сертификата. Тот самый красный экран. Не игнорируй его. Для мобильных приложений идут дальше и применяют certificate pinning — приложение заранее знает, какой именно сертификат у его сервера, и любой другой отвергает, даже формально валидный.
  • Защищённый DNS. DNS-over-HTTPS и DNS-over-TLS прячут и подписывают запросы, так что подменить ответ на лету уже не выйдет.
  • VPN на чужом Wi-Fi. Самое простое для обычного человека. VPN заворачивает весь трафик в свой шифрованный туннель. Даже если кто-то сидит посередине в кафе, он видит лишь поток нечитаемых байтов до VPN-сервера, и ARP-спуфинг с подменой DNS об этот туннель разбиваются.

Если свести к одному совету для не-инженера: на любом публичном Wi-Fi включай VPN и никогда не кликай «всё равно продолжить» на предупреждениях о сертификате. Этого хватает, чтобы закрыть подавляющее большинство сценариев.

А разработчику — относиться к сети как к враждебной среде по умолчанию. Не «за фаерволом безопасно», а «между двумя моими сервисами вполне может кто-то сидеть». HTTPS внутри, HSTS снаружи, нормальная проверка сертификатов в каждом HTTP-клиенте. Скучно, зато работает.

Вся атака «человек посередине» держится на одном допущении — что трафик идёт туда, куда ты думаешь, и тому, кому ты думаешь. Защита, по сути, сводится к тому, чтобы это допущение перестало быть просто верой и стало проверяемым фактом.

← Back to Blog