Атаки на провод и на сервисы
Что TLS действительно предотвращает, а что нет, подмена ARP и DNS в сети, которая не твоя, почему отказ в обслуживании не лечится фильтрацией и ограничение скорости как мера, которая реально доезжает до прода.
Трек по сетям уже показал тебе рукопожатие TLS и проверку сертификата. Следующий за этим вопрос безопасности уже и полезнее: что атакующий на пути всё ещё может сделать, если TLS реализован правильно? Ответ — больше, чем ничего, и намного меньше, чем всё, а интересное именно в том, где проходит граница. Всё ниже предполагает, что протокол реализован корректно. Сломанные реализации — отдельная тема и куда более редкая, чем намекают заголовки. TLS даёт три вещи. Конфиденциальность: байты в проводе нечитаемы. Целостность: изменённый байт обнаруживается, а не принимается. И аутентификацию сервера: ты знаешь, что согласованный ключ принадлежит тому имени, которое ты запросил. Атакующие бьют именно по последнему, потому что оно зависит от вещи вне протокола — от твоего хранилища доверенных корней. Если атакующий может поставить корневой сертификат на твоё устройство или если используемое тобой ПО уже приехало с таким сертификатом, рукопожатие пройдёт, замочек появится, а трафик расшифруют посередине. Это не уязвимость TLS. Это TLS, работающий ровно как задумано, с якорем доверия, которого там быть не должно. Второй путь проще и не требует криптографии вообще: страница, которая выглядит как страница входа и ею не является. TLS тут не поможет, потому что сертификат на похожий домен совершенно действителен для этого домена.
У ARP нет аутентификации. Хост спрашивает, кто владеет IP-адресом, ответить может любой, а ответ кэшируется. В сети, где коммутатор под твоим контролем, это решаемая проблема; в общей сети это свободный пропуск. Атака не экзотична и ничего не ломает: нужно лишь раз за разом объявлять, что заданный адрес находится на твоём MAC, чтобы жертвы сначала отправляли трафик тебе. Практическая мера — перейти в сеть, которая не твоя, и она эффективнее любого ПО, которое можно поставить потом. Поэтому это важно даже для зашифрованного трафика: из-за метаданных. Атакующий на пути может и не читать твои байты, но он видит, с какими адресами ты говоришь, когда, как часто и как много. Он также может решить не пересылать дальше, и тогда пассивная позиция превращается в отказ в обслуживании. Защита на стороне узла — привязка адреса шлюза к известному MAC или VPN, который заворачивает весь трафик в точку, которой ты доверяешь. Защита на стороне коммутатора — функции, которые отбрасывают объявления, не имеющие права приходить с этого порта. И то и другое реально; ни то, ни другое недоступно в Wi-Fi на конференции. Идея отравления без механики. Опасность создаёт не ложный ответ сам по себе, а его кэширование.
who has 192.168.1.1? tell 192.168.1.50 <- gateway ARP, normal
who has 192.168.1.1? tell 192.168.1.77 <- repeated, from a laptop
victim ARP cache
192.168.1.1 -> MAC of 192.168.1.77 <- poisoned entry
result: victim sends gateway-bound traffic to the laptop first
mitigation dynamic ARP inspection on the switch
mitigation port security, one MAC per port
mitigation encrypted protocols with certificate checkingМеханизм с той степенью подробности, которая нужна для защиты. Работает он потому, что ответ принимается без каких-либо доказательств.DNS — часть сети, превращающая имя в адрес, и проектировалась она тогда, когда сеть была маленькой и все в ней были своими. Резолвер, который принимает записи, которых не запрашивал, и затем их кэширует, будет отдавать их до истечения времени жизни. В этом и форма отравления кэша: атакующий влияет на один ответ, а резолвер разносит его по всем клиентам, которые спросят потом. Именно кэш превращает мгновенное влияние в долгое, поэтому время жизни — то число, которое определяет, насколько всё плохо. DNSSEC подписывает ответы, поэтому резолвер может убедиться, что запись пришла из зоны, которой она принадлежит, и не была изменена. Он ничего не шифрует и не делает запрос приватным. DNS over HTTPS и DNS over TLS шифруют запрос, чтобы наблюдатель в сети не мог его прочитать или переписать, но они не доказывают правильность ответа; они просто переносят доверие с локальной сети на резолвер, который ты выбрал. Честное резюме: оба механизма частичны, развёртывание DNSSEC неравномерно, а практический совет пользователю — настроить резолвер, которому доверяешь, вместо того чтобы полагаться на то, что выдаст сеть. Отказ в обслуживании — та категория атак, где защита действительно трудна, и стоит понять почему, а не собирать контрмеры. Фильтрация работает, когда вредоносный трафик отличим от законного. При отказе в обслуживании он часто неотличим: пакеты корректно сформированы, приходят с настоящих адресов и просят настоящие страницы. Разница только в том, сколько их и куда они направлены. Правило межсетевого экрана, отбрасывающее атаку, отбросит и клиентов. Именно это имеют в виду, когда говорят, что нельзя отфильтровать то, что не отличается от настоящего трафика, и это структурный предел, а не отсутствующая функция. SYN-cookies — классический ответ, и он поучителен тем, от чего приходится отказаться. Вместо хранения состояния на каждое полуоткрытое соединение сервер кодирует нужное ему в номере последовательности, который отправляет обратно, и проверяет это при приходе финального подтверждения. Цена в том, что часть опций TCP в таком режиме согласовать нельзя, поэтому соединения чуть менее функциональны. Для публичного сервиса это всё равно верный размен, потому что альтернатива — умеренное количество поддельного трафика кладёт сервис. Чего SYN-cookies не лечат — поток полностью установленных соединений, поэтому остаток урока про ограничение скорости. Атаке с усилением не нужно много канала от атакующего. Он отправляет маленький запрос с поддельным адресом источника сервису, который выдаёт большой ответ, и ответ приходит жертве. Отношение запроса к ответу и есть коэффициент усиления, и это свойство протокола, а не атакующего. Все известные случаи — сервисы, отвечающие по UDP без рукопожатия, поэтому адрес источника там никогда не проверяется. Поэтому открытый резолвер, открытый сервер NTP или выставленный наружу memcached — не нейтральный факт о твоей сети: это оружие, которое кто-то направит на третью сторону, а в поле отправителя будет твой адрес. Коэффициенты усиления по протоколам. Последняя строка — причина, по которой memcached на публичном интерфейсе стал аварией, а не мелкой ошибкой конфигурации. У защиты две половины, и они принадлежат разным людям. Если ты эксплуатируешь сервис, которым злоупотребляют, ты закрываешь его от публичного интернета: авторитетный резолвер не должен отвечать на рекурсию от посторонних, и ничто, говорящее по склонному к усилению UDP, не должно слушать на публичном адресе. Если ты цель, тебе нужна ёмкость, которой ты не владеешь, а на практике — провайдер, способный поглотить и отфильтровать трафик выше по течению, до того как он дойдёт до твоего канала. Неудобная правда в том, что вторая половина стоит денег пропорционально атаке, и никакая настройка на стороне сервера её не заменяет. Ограничение скорости — та мера, которую действительно внедряют, и это этюд о сопутном ущербе. На каждом уровне, где можно считать, найдётся группа законных пользователей, выглядящая как один атакующий. Подсчёт по адресу источника наказывает всех за общим офисным подключением или за NAT оператора, то есть большинство мобильных пользователей. Подсчёт по аккаунту позволяет атакующему с множеством аккаунтов держаться под лимитом, а легитимному скрипту выгрузки данных — упереться в блокировку. Уровня, который этого избегает, нет, потому что лимит — это граница, проведённая через непрерывность, и она всегда разрежет кого-то. Практический подход — комбинировать несколько слабых сигналов, поднимать стоимость получения того, что ты считаешь, и следить, чтобы лимит отказывал деградацией, а не поломкой. Каждый уровень, на котором можно считать, и законный трафик, который на нём попадётся. Правильный ответ обычно — больше одного сразу.
normal open
client SYN -> server
server SYN-ACK -> client
client ACK -> server connection established
backlog pressure
client SYN -> server half-open, in the backlog
server SYN-ACK -> client no reply ever comes
... thousands more, backlog fills, new SYNs are dropped
SYN cookies the server answers without storing state
the ACK carries back everything it needs
cost to the server: one SYN, 40 bytes
cost to the attacker: one spoofed source addressSYN-флуд в подробностях. Асимметрия, на которой он держится, в том, что атакующий тратит один маленький пакет, а сервер — память и таймер.Практика
Пользователь в гостиничной сети видит, что браузер ругается на сертификат банка, а после нажатия «продолжить» страница выглядит обычно. Какое объяснение лучше всего соответствует наблюдениям?
Подсказки
- Спроси, что атакующему пришлось бы предъявить, чтобы клиент принял соединение. Сертификат — это подпись, а подпись должна выстраиваться в цепочку к тому, чему устройство уже доверяет.
- Если бы сетевой атакующий действительно сломал TLS, смена пароля тоже не помогла бы: новый пароль пошёл бы по тому же каналу.
Сопоставь каждую атаку с уровнем, на котором она работает, и с тем, что ей нужно для успеха.
Подсказки
- Назови уровень каждой атаки: канальный, разрешение имён, транспортный или сама форма трафика.
- Одна атака здесь вообще ничего не ломает. Она просто шлёт трафика больше, чем вмещает канал, и поэтому никакая фильтрация на стороне сервера не отвечает на неё полностью.
Напиши rateLimiter(limit, windowMs). Он возвращает allow(key, now), который возвращает true, если по этому ключу за последние windowMs миллисекунд было меньше limit запросов, считая только разрешённые.
Код выполняется у тебя, а не у нас — мы его не запускаем. Проверь решение по каждому требованию и отметь выполненные.
Подсказки
- Храни список уже принятых отметок времени. При каждом новом запросе выбрасывай те, что выпали из окна, и смотри, что осталось.
- Ограничивай сначала по ключу, потом по источнику. Единственный дизайн, который проваливается всегда, — один общий счётчик: он позволяет одному шумному клиенту заблокировать всех.
Вопросы по этому уроку
Это бесплатно?
Да. Первый уровень каждого предмета бесплатный и не требует аккаунта. Дальше уровни и старшие грейды платные — именно это позволяет проекту существовать.
На какой возраст рассчитано?
Для любознательных подростков примерно с 12 лет и для взрослых, начинающих с нуля. Опыт программирования не предполагается: уроки по сетям и физике не требуют математики сверх школьной.
Нужно ли уже уметь программировать?
Нет. Логика, физика и сети начинаются с нуля. Код ты пишешь в разделе языков — и он тоже начинается с самого начала.
Нужно что-то устанавливать?
Нет. Всё работает в браузере: теория, практика и интерактивные симуляции. Скачивать нечего и настраивать нечего.
Сколько времени занимает один предмет?
Урок — от 10 до 15 минут. Грейд «джун» это примерно 12–20 уроков, то есть несколько недель регулярных занятий, а не один вечер.
Обязательно идти по порядку?
Внутри грейда уровни открываются по очереди: каждый опирается на предыдущий. А между предметами ты свободен — начинай с логики, физики или сетей.