CVE-2019-10149 в Exim: проверьте забытый почтовый узел
АйТи Фреш
Информационная безопасность

Старый Exim после переезда почты: как проверить CVE-2019-10149

Автор: , директор ООО «АйТи-Фреш» · · ~14 мин чтения
Два почтовых лотка и забытая ветка доставки: старый Exim после переноса почты
Забытый узел продолжает принимать почту.

Чтобы закрыть CVE-2019-10149, я проверяю работающий Exim и исправления его поставщика, затем обновляю нужный узел или отключаю ненужный. Уязвимы исходные версии 4.87–4.91, но дистрибутив мог перенести патч в старую ветку. После переезда почты отдельно ищу резервные MX: смена основного сервера сама по себе старый не выключает.

Чем опасна CVE-2019-10149 и что доказывает открытый SMTP

CVE-2019-10149 — ошибка проверки адреса получателя в Exim, которая может привести к выполнению команд. Это подтверждённая уязвимость почтового агента, а не ошибка CMS и не абстрактный «неконтролируемый доступ». Когда я проверяю безопасность почтовой инфраструктуры, сначала устанавливаю, какой процесс принимает письма и откуда он установлен. Возраст сервера и слово Exim в сетевом ответе дают повод для проверки, но ещё не дают заключения.

Последствия серьёзные: исследователи, обнаружившие ошибку, описали возможность выполнения команд с правами root. Здесь нельзя успокаиваться тем, что на узле больше нет пользовательских ящиков. Старый почтовый шлюз остаётся отдельной системой со своими файлами, учётными данными и доступами. При этом я не приравниваю наличие уязвимости к состоявшемуся взлому: установленный дефект, доступность сервиса и следы эксплуатации — разные результаты проверки.

Уязвимость имеет локальные и удалённые сценарии; условия удалённой эксплуатации зависят от конфигурации. Поэтому фраза «любой Exim с открытым портом уже взломан» неверна. Обратная отговорка «входящую почту не принимаем, значит, исправление не нужно» тоже не работает: локальный способ использования не исчезает из-за сетевого фильтра. Я закрываю подтверждённую ошибку обновлением, а ограничения доступа использую как временную меру.

Открытый SMTP показывает доступность службы, но не наличие именно этой CVE. Закрытое соединение, в свою очередь, не подтверждает установленный патч. В акте проверки я отдельно записываю версию и происхождение программы, статус исправления и доступные сетевые пути. Это позволяет понять, что уже доказано, а что ещё предстоит выяснить. Уязвимость не становится менее опасной от незнания версии; уверенности в отчёте зато обычно прибавляется удивительно много.

Какие версии затронуты и почему старый номер бывает исправленным

В официальном уведомлении Exim указан диапазон 4.87–4.91 включительно. Там же прямо сказано, что Exim 4.92 этой уязвимости не подвержен. Исправление было опубликовано 5 июня 2019 года. Это исторические границы конкретной ошибки, а не рекомендация устанавливать сегодня древний релиз 4.92. Для действующего сервера я выбираю поддерживаемые систему и пакет с актуальными обновлениями, а этот диапазон использую при разборе старого узла.

Поставщик дистрибутива может перенести исправление в пакет с прежним основным номером версии. Например, уведомление USN-4010-1 для Ubuntu 18.04 LTS называет исправленные exim4-daemon-light и exim4-daemon-heavy версии 4.90.1-1ubuntu1.2. Получается важный контрпример: число 4.90.1 меньше 4.92, а пакет уже содержит исправление этой CVE. Я сравниваю полную ревизию в пределах одного дистрибутива и его выпуска; переносить порог на другую систему нельзя.

Для быстрой сверки я держу такую памятку. | Что найдено | Какой вывод допустим | |---|---| | Исходный Exim 4.87–4.91 без патча | Затронут CVE-2019-10149 | | Исходный Exim 4.92 | Эта CVE не затрагивает релиз | | Ubuntu 18.04, пакет 4.90.1-1ubuntu1.2 | Исправление подтверждено USN-4010-1 | | Старая версия без сведений о сборке | Статус пока не установлен | Таблица отвечает только на вопрос об этой уязвимости. Она не удостоверяет общую безопасность сервера и не заменяет проверку более поздних исправлений.

Номера исправлений от другой CVE я сюда не переношу. В частности, объявлять исходный Exim 4.94 уязвимым к CVE-2019-10149 только из-за отсутствия какой-либо пакетной ревизии неправильно. Сначала номер уязвимости, затем уведомление поставщика, затем установленная сборка — именно в таком порядке. Иначе получается ремонт по соседней квитанции: цифры настоящие, адрес чужой.

Отсутствие строки CVE в описании пакета тоже не доказывает уязвимость. Краткое описание вообще не обязано перечислять исправления, а журнал изменений может быть недоступен или неполон. Для дистрибутивного пакета я ищу его статус в официальном уведомлении или трекере поставщика. Для самостоятельной сборки нужны сведения о применённом патче и исходниках. Если этих данных нет, честная запись — «исправление не подтверждено», после чего узел ограничивают и приводят в поддерживаемое состояние.

Сравнение исходных версий Exim и исправленной ревизии пакета Ubuntu для CVE-2019-10149
Нужна полная ревизия пакета.

Как проверить бинарник, пакет и действительно работающий Exim

Для вывода версии у Exim служит ключ -bV. Ключ -v включает подробный вывод работы и для этой задачи не подходит. Я запускаю проверку по абсолютному пути к тому исполняемому файлу, который указан в параметрах запуска службы. Пример ниже предполагает, что команда exim доступна в окружении; в пакетной установке Debian или Ubuntu имя может быть exim4. Подменять проверяемый файл первым совпадением из окружения нельзя.

exim -bV

У -bV есть полезная особенность: он показывает сведения о сборке, доступных возможностях и используемом конфигурационном файле, а также выполняет статическую проверку синтаксиса конфигурации. Но успешный выход команды не означает, что маршрутизация писем работает: значения, вычисляемые во время обработки, такая проверка полностью не проверяет. И ещё: команда запускает новый процесс из файла на диске; старый демон мог остаться в памяти после обновления.

В Debian и Ubuntu я выясняю, какой пакет содержит исполняемый файл. Проверяю пакет с самим демоном: exim4-daemon-light или exim4-daemon-heavy, а не только общий пакет exim4. Для начала можно вывести известные системе пакеты демона; в этом списке нужно учитывать состояние установки, а не просто наличие строки. Затем смотрю версии, предлагаемые настроенными репозиториями.

dpkg-query -l "exim4-daemon-*"
apt-cache policy exim4-daemon-light exim4-daemon-heavy

У dpkg-query -l отметка ii означает, что пакет выбран для установки и установлен. apt-cache policy показывает сведения о выборе версий и источниках пакета; это не журнал изменений. Данные кэша могут устареть, поэтому я отдельно проверяю успешность обновления индексов репозиториев. За журналом обращаюсь отдельной командой. Здесь показан вариант light; если установлен heavy, в запросе указываю его имя.

apt-get changelog exim4-daemon-light

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

Если аудит совпадает с переносом почты, сначала собираю карту почтовых зависимостей. В ней отмечаю шлюзы, приложения с локальной отправкой и резервные машины. Такой список помогает проверить именно используемые процессы, а не ограничиться сервером, который помнят по имени. На выходе нужен воспроизводимый вывод о сборке каждого узла: где подтверждён патч, где требуется обновление, где происхождение программы пока неизвестно.

Проверка Exim: от исполняемого файла и пакета до работающего процесса и доставки
Проверяйте процесс после обновления.

Условный разбор: «Пакетная линия», 12 рабочих мест

Покажу порядок на условном производстве упаковки «Пакетная линия» в Москве: 12 рабочих мест, основная почта перенесена, прежний узел оставлен как резервный. Это учебный сценарий, а не история реального клиента. В исходных условиях старый сервер принимает SMTP, в сведениях о его сборке виден Exim 4.89, подтверждения патча нет. Такая версия попадает в затронутый диапазон, но до проверки происхождения сборки я фиксирую подозрение на уязвимость, а не объявляю доказанный взлом.

Работу начинаю с владельца узла и его зависимостей. Проверяю, остались ли на нём письма в очереди, локальные задания отправки, уведомления производственных программ и резервная доставка. Пометка «не используется» должна выдержать эту проверку. Иначе можно устранить риск старого Exim и одновременно отключить отправку нужных документов. Ошибка здесь в отсутствии учёта зависимостей; количество рабочих мест от неё не защищает.

В сценарии задаю два MX с предпочтениями 10 и 20. Меньшее число означает более предпочтительный маршрут, поэтому старый узел с числом 20 остаётся резервным получателем. Я не делаю вывод, что на него «никогда не приходят письма»: при недоступности основного узла отправители могут попробовать резервный. Для такой роли нужны рабочая пересылка, обновления и ответственный. Сервер не знает, что слово «резерв» в документах означает бессрочный отпуск.

Дальше разделяю два решения. Если резерв нужен, ограничиваю лишний доступ, подтверждаю исправление или обновляю пакет, затем проверяю доставку через этот маршрут. Если роль больше не нужна, переношу оставшиеся задания, разбираю очередь, согласую отключение, убираю резервную запись и сетевые публикации. Для планирования выделяю отдельное окно изменения и отдельную проверку после него. Продолжительность определяю по очереди и зависимостям; универсального срока для такого вывода из эксплуатации нет.

Критерий завершения сценария измеримый: для 12 рабочих мест работает согласованный почтовый маршрут, прежний узел либо обслуживает проверенную резервную роль с исправленной сборкой, либо больше не принимает внешний SMTP. В журнале работ остаются результаты проверки пакета, доставки и сетевой доступности. Пустой журнал атак не позволяет написать «взлома не было», а отключение машины — «мы предотвратили утечку». Я фиксирую действия и наблюдаемый результат. Этого достаточно для честного отчёта.

Мы в «АйТи-Фреш» проверим старый почтовый узел: установим происхождение Exim, сверим исправления и подготовим обновление или отключение с учётом доставки. Обсудить задачу

Где искать забытый MX и почему удаления DNS недостаточно

Я начинаю с MX каждого обслуживаемого домена, а затем проверяю адресные записи A и AAAA имён, на которые эти MX ссылаются. Проверяю и основную, и резервную площадку. Одного домена из памяти мало: в инфраструктуре могут остаться отдельные домены для уведомлений или прежние почтовые имена. Для каждой записи нужен владелец, назначение и фактический получатель соединений. Красивый новый почтовый интерфейс не отвечает на вопрос, куда извне всё ещё можно доставить письмо.

Следом сопоставляю DNS с виртуальными машинами, контейнерами, внешними адресами и правилами сетевой публикации. Отдельно учитываю IPv4 и IPv6: ограничение в одном семействе адресов не описывает доступность в другом. Если сервер выключен на уровне приложения, но правило публикации осталось, отмечаю и его. При следующем запуске старой машины такое правило может снова открыть сервис. Инвентаризация должна объяснять, как соединение доходит до программы, а не просто перечислять знакомые имена.

SMTP между почтовыми серверами обычно использует TCP-порт 25. Его доступность проверяю с внешней точки к своим узлам и сравниваю с назначением машины. Сетевой ответ помогает найти службу, но не удостоверяет версию установленного пакета. Так же и отсутствие имени в MX не делает узел невидимым: к известному адресу можно обратиться напрямую. Удаление DNS-записи меняет обнаружение почтового маршрута, но само по себе не закрывает соединения.

С резервной доставкой нужна особая аккуратность. Я сначала проверяю, куда уходят уже принятые письма, а потом убираю ненужный маршрут. Изменение DNS не применяется мгновенно ко всем отправителям: у них могут оставаться закэшированные ответы. Поэтому при отключении учитываю срок кэширования записей и повторно проверяю доступность самого узла. Если резервный MX остаётся в работе, его обновления и тест доставки включаю в тот же регламент, что и основной шлюз.

Результат поиска оформляю как короткую таблицу учёта: имя, роль, владелец, адресные семейства, доступный сервис, подтверждение исправления и принятое решение. Для небольшой компании этого достаточно, чтобы забытый узел перестал жить между двумя подрядчиками. Повторную сверку назначаю после каждого переноса и изменения сетевой публикации. Регулярную проверку добавляю в обслуживание с понятным ответственным. DNS — адресная книга, а не выключатель; требовать от неё второго назначения бесполезно.

Удаление MX не закрывает сетевой доступ. Проверьте сам узел, публикации IPv4 и IPv6 и оставшиеся задания отправки.
Основной и резервный MX: прямой доступ к старому Exim сохраняется после удаления записи
DNS не отключает старый узел.

Как применить исправление и принять результат работы

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

В Debian и Ubuntu легко перепутать обновление программы с пересборкой конфигурации. Команда update-exim4.conf создаёт конфигурацию из настроек пакетной установки; уязвимый исполняемый файл она не заменяет. Если менялись настройки, применяю предусмотренную пакетом генерацию конфигурации и проверяю её. После установки исправления отдельно убеждаюсь, что служба использует нужную сборку, а старые процессы завершены или корректно заменены.

На приёмке повторяю проверку версии по тому же пути, проверяю работающий процесс и доставляю тестовое письмо через согласованный маршрут. Для резервного узла отдельно проверяю приём и последующую передачу на основной. Слежу за очередью и ошибками после изменения: успешный запуск процесса ещё не означает исправную доставку. Если обновлялся контейнер, подтверждаю также, что следующий запуск использует исправленный образ. Иначе сегодня всё хорошо, а после перезапуска возвращается прежняя сборка.

Если обнаружены признаки компрометации, закрывать задачу одной установкой патча нельзя. Я сохраняю доступные журналы и сведения о состоянии системы, ограничиваю доступ и определяю затронутые учётные данные. При подтверждённом выполнении посторонних команд восстановление из доверенной основы может быть надёжнее ремонта текущей установки. Но сам по себе старый номер версии не доказывает, что такое выполнение произошло. В решении о восстановлении нужны следы и контекст, а не страшная формулировка в заголовке.

После переноса проверяю полноту почтового переезда: оставшиеся очереди, задания приложений, актуальные маршруты и доступность прежних узлов. В итоговом документе оставляю подтверждение исправленной ревизии, результат проверки процесса и доставки, владельца резервного сервера либо запись о его отключении. Критерий простой: следующий администратор сможет повторить проверку без догадок. Закрытая заявка работает лучше, когда к ней приложено что-то весомее фразы «вроде обновилось».

Частые вопросы

Какие версии Exim затронуты CVE-2019-10149?

Исходные версии 4.87–4.91 включительно; Exim 4.92 этой CVE не подвержен. У дистрибутивных пакетов проверяйте полную ревизию: поставщик мог перенести исправление в старую ветку.

Какой командой посмотреть версию Exim?

Используйте ключ -bV у нужного исполняемого файла: например, exim -bV. В пакетной установке имя может быть exim4. Ключ -v включает подробный вывод работы и не заменяет проверку версии.

Если CVE нет в changelog, сервер точно уязвим?

Нет. Сверьте полную установленную ревизию с официальным уведомлением для своего выпуска системы. Отсутствие строки в журнале означает недостаток подтверждения, а не доказанную уязвимость.

Достаточно удалить старый MX или закрыть порт 25?

Удаление MX не закрывает сетевую доступность. Фильтрация SMTP уменьшает удалённую доступность, но не устанавливает патч и не устраняет локальные сценарии. Нужный сервер обновляют, ненужный выводят из эксплуатации с проверкой зависимостей.

Можно ли оставить старый сервер резервным после переноса?

Да, если его роль нужна, исправления подтверждены, доставка проверяется и назначен ответственный. Резервный MX с большим числом предпочтения остаётся возможным получателем почты при проблемах основного маршрута.

Столкнулись с похожей задачей? Обращайтесь — решим

Если у вас происходит что-то из описанного в этой статье — или любая другая проблема с ИТ-инфраструктурой, — обращайтесь в любое время. Мои специалисты и я лично разберём ситуацию, найдём настоящую причину и доведём до решения.

Возьмёмся и за разовую задачу, и за постоянное обслуживание. Первичная консультация — бесплатно и без обязательств.

📞 +7 903 729-62-41 ✈ Telegram @ITfresh_Boss

С уважением, Семёнов Евгений Сергеевич, директор «АйТи Фреш» — IT-аутсорсинг для компаний до 50 рабочих мест, 15+ лет практики

Источники

© ООО «АйТи-Фреш» · Москва · Все статьи