Появилась вчера на Хабре такая вот статья . Когда компания, занимающаяся ИТ-безопасностью заявляет, что spf/dkim/dmarc не работают и существует минимум 18 способов подменить адрес на (вашем!) почтовом сервере, это вызывает озабоченность и желание разобраться в вопросе. Я прочитал оригинальную статью и кратко изложил свое понимание вопроса. Если тема для вас актуальна рекомендую непременно прочитать оригинал.
Основная идея статьи в том, что любая современная система состоит из компонентов, и проблемы чаще всего возникают при их взаимодействии. Всего описано 18 проблем разбитых примерно на 6 категорий, а техники обозначены A1-A18.
Путаница с адресом в helo/mail from
В протоколе smtp адрес отправителя используется в двух командах helo и mail from. Требования к SPF (RFC 7208) гласят, что проверка значения из mail from обязательна, из helo - рекомендуется. Требования к DMARC (RFC 4789) гласит что проверка должна выполняться по значению из mail from, а если значение пустое, то нужно взят значение из helo. В некоторых случаях это может привести к тому, что spf и dmarc будут проверять разные значения.
А1 - несуществующие поддомены. Если указать несуществующий поддомен существующего домена в mail from, то SPF вернет пустое значение. Некоторые реализации SPF не выполняют проверку домена, а сразу берет значение из helo, где злоумышленник может указать нужное ему значение. Но некоторые реализации DMARC все равно используют значение из mail from и могут вернуть положительный результат при проверке домена отправителя.
А2 - "пустой" адрес в mail from. Скобки в почтовом адресе могут использоваться как комментарии (RFC 5322). И некоторые реализации SPF ошибочно трактуют адрес (any@legitimate.com
(непарная левая круглая скобка использована умышленно) как пустой. Но некоторые реализации DMARC считают это корректным адресом и используют для проверки.
Неправильная интерпретация доменного имени
А3 - NULL-неоднозначность. Для обхода проверки dkim используется символ 0x00 в доменном имени, который считается концом строки в некоторых языках, а в некоторых не считается. Для эксплуатации ошибки в подписи dkim в качестве домена отправителя используется, например, legitimate.com
, а в качестве адреса для получения публичного ключа используется attacker.com.\x00.anything
. Если dkim сочтет такой адрес корректным, то для получения публичного ключа будет запрошен dns-адрес attack.com.\x00.any._domainkey.legitimate.com
. DNS сервер интерпретирует 0х00 как конец строки и вернет результат для attack.com. Данная ошибка была обнаружена на gmail.com и уже исправлена.
Ошибки при разборе заголовков аутентификации
Использование символов " ( @ в адресе может приводить к его ошибочному разбору и неверным результатам проверки.
А4 - атакующий использует в dkim подписи адрес legitimate.com(.attacker.com
, а в качестве адреса получателя admin@legitimate.com
. Если на сервере получателя домен в dkim-подписи распарсится неверно (т. е. до скобки, т. к. текст в скобках является комментарием, согласно RFC), то адрес отправителя будет признан верным
А5 - атакующий использует в качестве адреса получателя адрес legitimate.com(.attacker.com
или any@legitimate.com’@a.attacker.com
, подобные адреса получателя могут быть по-разному интерпретированы smtp сервером и при проверке .spf и dmarc. SPF использует legitimate.com(.attacker.com
или legitimate.com@a.attack.com
, DMARC - egitimate.com
.
Авторы статьи приводят список серверов на которых удалось эксплуатировать описанные уязвимости.
Ошибки несоответствия интерфейсов
Самый богатый на ошибки раздел, описано шесть ошибок в трёх категориях.
Неправильная интерпретация заголовка from.
А6 - Использование нескольких заголовков from. RFC требует наличие ровно одного заголовка, но разное ПО может использовать либо первый, либо последний заголовок.
A7 - Использование пробелов в поле from. Противоречит RFC, но разное ПО обрабатывает ситуацию по-разному.
А8 - использование альтернативных заголовков. Некоторое ПО при отсутствии или ошибочном заголовке from может использовать схожие по назначению заголовки, например sender или recent-from.
Неправильная интерпретация адреса.
Поле адреса в заголовке From может иметь достаточно сложный синтаксис, и извлечение действительного адреса непростая задача, которую разное ПО решает по-разному. В частности, адрес может состоять из отображаемого имени, строки с указанием маршрута, собственно адреса и комментариев.
Примеры корректных заголовков:From: “a@a.com” <@b.com, @c.com:d@d.com> (e@e.com)
From: Pete(A nice \) chap) <pete(his account)@silly.test(his host)>
Информация о маршруте была определена в RFC 822, в настоящее время признана устаревшей. RFC 5322 запрещает генерировать это поле, но требует правильно его обрабатывать.
Кроме того, в заголовке from может быть указан список адресов авторов, и тогда требуется заголовок sender. Некоторые символы (запятые и кавычки) интерпретируются специальным образом, и при использовании в качестве обычных символов перед ними необходимо ставить обратный слэш. Кроме того символы non-ascii могут быть закодированы в quoted-printable или base64.
В статье приведены примеры, как разное ПО по-разному извлекает адрес из заголовка from и описаны 5 типов (A9-A13) атак построенных на этом. Наглядные изображения атак и ошибок отображения адресов приведены на картинках ниже.
Spoofing писем с корректными dkim подписями
Если атакующий имеет письмо с корректными dkim подписями, в некоторых случаях возможна подмена заголовков или содержимого письма при его пересылке.
А14. Добавление заголовков, которые не защищены dkim. RFC описывает 19 заголовков, которые следует защищать, но, к примеру Citibank защищает только заголовки from и subject, American Express - from и reply-to. В случае Gmail атакующий может скрыть тело своего сообщения установив заголовок Content-Disposition: attachment;filename=ticket.jpg
А15. Добавление дублирующих заголовков (from, subject, content-type). DKIM защищает подписью только последний заголовок, но 9 из 19 почтовых программ используют первый.
А16. Подмена тела письма. DKIM подпись может указывать длинну подписываемого сообщения. Это используется, например, в Google Groups: к подписанному сообщению может быть добавлена информация о возможности отписаться и при этом подпись останется корректной. Аналогичным образом, атакующий может добавить вредоносные данные в конец письма, сохранив корректность подписи. Кроме того, если не защищен заголовок content-type, атакующий может изменить структуру письма так, чтобы отображалось вредоносное содержимое.
A17. При наличии учетной записи на сервере атакующий может авторизоваться под своей учетной записью, но в заголовке from указать другого пользователя (например, admin). Некоторые почтовые сервера не выполняют проверку и позволяют подобные действия.
А18. Двух-ходовая схема. Атакующий отправляет письмо себе указывая корректный заголовок from, получает письмо с корректной подписью dkim, добавляет второй заголовок from и отправляет жертве. В некоторых случаях возможна ситуация, при которой подпись будет проверена и подтверждена для первого заголовка, но в почтовой программе отобразится второй.
В статье также предложены методы по защите от подобного рода атак (кратко - rtfm, как обычно).
Авторы уведомили CERT/CC и всех вендоров о найденных проблемах и получили позитивную реакцию (Gmail, Zoho, Protonmail и Mail.ru выплатили вознаграждение за каждую из найденных уязвимостей) ото всех кроме Microsoft и Yahoo. Microsoft расценил проблему, как относящуюся к социальной инженерии и не имеющей отношения к проблемам ПО. Yahoo ответил что ошибка состоит в настройке DNS авторов.
Спасибо GlobalSign за мотивацию прочитать оригинальную статью.
ifap
Т.е. чуть ли не все проблемы вызваны тем, что, с одной стороны, авторы некоторых софтовых реализаций не осилили RFC, а с другой - администраторы почтовиков, вместо того чтобы гнать ссаными тряпками всю входящую с кривых серверов почту, принимают ее?
Saiv46
Виноваты и те, кто всё усложнил в RFC:
Вот кому это может пригодится? Упрощённый вариант формата было бы более чем достаточно:
И при неправильном формате можно отбрасывать письмо. Всё остальное можно в других заголовках указать - включая маршрут доставки и сертификат отправителя (если содержимое письма зашифровано).
snp
В давние времена (90-е и ранее) часто использовался немного другой формат From:
From: john@example.com (John Doe)
По-моему, было более логично. Т.к. самое главное (email) идёт вначале, а затем уже менее значимое (ФИО).
z3apa3a
оба формата валидны, в вашем примере John Doe это не отображаемое имя пользователя как в примере выше, а комментарий. В такой форме письма генерировал юниксовый mail (и до сих пор в некоторых системах так делает), комментарий генерируется по GECOS из /etc/passwd, в общем случае это был именно комментарий, он помимо имени может содержать много чего еще.
From: "John Doe" <john@example.com> (John Doe, system administrator, 712345678901 some street)
В целом формат подразумевался примерно такой
ifap
Сложно сказать, не знаю какой "бэкграунд" приходилось учитывать при разработке. С другой стороны, учитывая что в каждом втором RFC присутствует оговорка Errata Exists, их тоже пишут не безгрешные люди. Но кто мешал разрабам почтовиков на этапе разработки RFC встрять с Вашим вопросом?
z3apa3a
Кого-то просто не было, кому-то мешал юный возраст, кому-то отсутствие допусков к военной сети США, поэтому "разрабов почтовика" на тот момент было человек 5, каждый со своим стандартом и нужен был стандарт который был бы обратно совместим со всеми. RFC 724 где фиксируется примерно такой формат заголовков для ARPA написан в 1977м году , более новые RFC писались (в основном) с обратной совместимостью с предшественниками, в т.ч. и первый стандарт для интернет RFC 822 в 1982м, потому что одномоментно переключить всех на новый стандарт невозможно.
Тогда письмо показывалось в текстовой форме и заголовки показывались "как есть", поэтому стандарт в основном определял как сгенерировать заголовки чтобы они были более-менее унифромными и читаемы для человека, а не как их машинно-распарсить + было несколько почтовых сетей со своими стандартами и нужен был стандарт который был бы обратно совместим со всеми.
ifap
RFC 724 заменен "свеженьким" RFC 5322 от 2008 года, так что могли бы уж встрять заинтересованные лица...
savostin
Мне кажется пока будет использоваться "парсинг текста регулярными выражениями", проблем будет только больше. Пора уже переходить на что-то более надежное.