Критические уязвимости telnetd: root-доступ через переменные окружения в 2026

Серия критических уязвимостей в telnetd: как через переменные окружения получить root-доступ и почему это всё ещё актуально в 2026 году

Сервер telnetd из состава GNU InetUtils снова оказался в центре внимания специалистов по безопасности. После обнаруженной в конце января уязвимости, позволявшей подключаться к системе под пользователем root без ввода пароля, исследователи нашли ещё несколько сценариев повышения привилегий. Общая причина - давняя, но так и не до конца исправленная проблема, тянущаяся с конца 90‑х годов (уязвимость CVE-1999-0073).

Все новые методы атак основаны на одном механизме - передаче клиентом переменных окружения на сервер через опцию ENVIRON протокола Telnet. Эти переменные попадают в окружение процесса telnetd, а затем наследуются всеми запущенными им дочерними процессами, включая /bin/login, работающий с правами суперпользователя. Именно здесь и открывается простор для эксплуатации.

Как всё начиналось: старая уязвимость CVE-1999-0073

Исторически первой проблемной точкой была возможность передачи переменной окружения LD_LIBRARY_PATH от telnet-клиента на сервер. Эта переменная управляет путём поиска разделяемых библиотек в Unix-системах. Если процесс login запускается с выставленным LD_LIBRARY_PATH, он может подгрузить библиотеку из указанного атакующим каталога.

В результате злоумышленник, имеющий хоть какую-то возможность загружать файлы в систему (через FTP, файловый шаринг, уязвимое веб-приложение и т.п.), мог поместить туда специально подготовленную библиотеку, а затем, подключившись по telnet, заставить /bin/login, работающий от имени root, подгрузить и выполнить этот код. Так появлялась прямая дорога к полному захвату системы.

В telnetd из GNU InetUtils эту уязвимость попытались закрыть радикально: ввели фильтрацию "опасных" переменных окружения. В чёрный список попали маски "LD_", "LIBPATH", "ENV", "IFS" и "_RLD_". Предполагалось, что запрет на передачу таких переменных полностью обезопасит процесс login от манипуляций с загрузкой библиотек и окружением.

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

Новая дыра: CREDENTIALS_DIRECTORY и вход без пароля

Исследователи обнаружили, что в GNU InetUtils никак не блокируется переменная окружения CREDENTIALS_DIRECTORY, хотя она непосредственно влияет на поведение /usr/bin/login. Эта переменная указывает каталог, в котором находятся настройки, связанные с учётными данными пользователей.

При запуске login, если в указанном через CREDENTIALS_DIRECTORY каталоге существует файл login.noauth со значением "yes", процесс login воспринимает это как разрешение на вход без пароля - фактически аналог передачи ему параметра командной строки "-f". И, что особенно опасно, такая настройка срабатывает для всех учётных записей, включая root.

Сценарий атаки выглядит следующим образом:

1. Непривилегированный пользователь в своей домашней директории создаёт подкаталог, например, `~/creds/`.
2. В этот каталог он кладёт файл login.noauth с содержимым "yes".
3. При подключении по telnet он передаёт переменную окружения
`CREDENTIALS_DIRECTORY=путь_к_созданному_каталогу`.
4. Одновременно через механизм автоматической авторизации telnet указывает переменную окружения `USER=root` (в telnet предусмотрен режим, когда имя пользователя не вводится в явном виде, а передаётся именно через переменную USER).

В результате /usr/bin/login видит изменённый каталог с "настройками" и включает режим входа без пароля, а переданное имя пользователя root позволяет получить доступ с максимальными привилегиями. Таким образом, обычный пользователь системы, имеющий возможность подключиться по telnetd, способен за несколько шагов повысить свои права до уровня суперпользователя.

Ещё один вектор атаки: OUTPUT_CHARSET, LANGUAGE и GCONV_PATH

На этом исследование не остановилось. Была обнаружена ещё одна цепочка эксплуатации, уже не напрямую связанная с каталогами учётных данных, но также использующая переменные окружения.

В данном случае в ход идут:

- OUTPUT_CHARSET и LANGUAGE - переменные, которые обрабатываются библиотекой GNU gettext и отвечают за локализацию и преобразование кодировок;
- GCONV_PATH - переменная из glibc, определяющая путь к модулям преобразования кодировок.

Механика следующая:

1. Атакующий устанавливает переменные OUTPUT_CHARSET и LANGUAGE таким образом, чтобы активировать функциональность gettext по преобразованию кодировок. Это заставляет библиотеку вызывать функцию iconv_open().
2. В ходе работы iconv_open() загружаются модули преобразования символов. Конфигурация этих модулей хранится в файле gconv-modules.
3. Путь к этому файлу (и, как следствие, к библиотекам модулей) вычисляется с учётом значения переменной GCONV_PATH.
4. Если подменить gconv-modules в каталоге, указанном через GCONV_PATH, то можно заставить glibc загрузить произвольную разделяемую библиотеку, содержащую вредоносный код.

Поскольку весь этот процесс происходит при вызове локализованных функций вывода в контексте /bin/login, запущенного от имени root, злоумышленник снова получает возможность исполнения кода с максимальными привилегиями.

То есть, по сути, атака строится на том, что на первый взгляд сугубо "языковые" и "кодировочные" настройки превращаются в удобный канал для незаметной подгрузки доверяемых системой модулей из контролируемого атакующим места.

Статус уязвимостей и текущая ситуация

На момент описания проблемы упомянутым уязвимостям дополнительные CVE‑идентификаторы ещё не были присвоены, хотя фактическая критичность у них крайне высокая: повышение привилегий до root без знания пароля - это классический пример полного компрометационного сценария.

Все подтверждённые проблемы касаются именно реализации telnetd из пакета GNU InetUtils. Этот сервер активно использовался и продолжает ставиться по умолчанию или по выбору администратора в ряде дистрибутивов, в том числе:

- Debian,
- Ubuntu,
- производные от них системы.

На момент описания исправлений для GNU InetUtils не было, что оставляет администраторов перед выбором: либо срочно ограничивать или отключать telnetd, либо самостоятельно внедрять дополнительные меры защиты.

При этом важно, что не все реализации telnetd одинаково уязвимы:

- В Rocky Linux 9 используется модифицированный telnetd, в котором вместо блокировки опасных переменных по маскам применяется принцип белого списка. Это позволяет существенно сократить поверхность атаки.
- Аналогичный подход реализован в telnetd из состава FreeBSD - там также важна не фильтрация "плохих" переменных, а строгий перечень допустимых.
- В OpenBSD вопрос решили ещё радикальнее: telnetd был исключён из базовой системы ещё в 2005 году, что хорошо иллюстрирует отношение разработчиков к устаревшим и опасным протоколам.

Белый список как основной метод защиты

В качестве базового механизма защиты сегодня рассматривается именно белый список переменных окружения. Логика проста: передавать от клиента к процессу login можно только строго определённый набор параметров, а всё остальное - безоговорочно отбрасывать.

Типичный допустимый набор переменных окружения:

- TERM - тип терминала;
- DISPLAY - дисплей для графических приложений (актуально для X11);
- USER - имя пользователя;
- LOGNAME - логин пользователя;
- POSIXLY_CORRECT - настройка поведения некоторых утилит по стандарту POSIX.

Остальные переменные окружения не нужны для корректной работы авторизации и, в то же время, регулярно становятся источником сложных, цепочных уязвимостей. Такой подход давно реализован, например, в OpenSSH: только строго определённый список переменных может "переехать" из клиентской сессии в серверную; всё прочее - блокируется.

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

Почему telnet всё ещё жив в 2026 году

Вопрос, который неизбежно возникает: кто вообще в 2026 году продолжает пользоваться telnet, да ещё и в таком виде, чтобы ему понадобился полноценный telnetd из GNU InetUtils?

На уровне общих рекомендаций уже много лет советуют:

- не использовать telnet в открытых или недоверенных сетях;
- не давать через telnet доступ к критичным серверам;
- заменить telnet на SSH везде, где это возможно.

Однако в реальности всё сложнее:

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

2. Старое промышленное и телеком-оборудование
В ряде отраслей до сих пор эксплуатируются системы, разработанные десятки лет назад, где telnet является единственным или "официально поддерживаемым" способом удалённого доступа. Обновлять их дорого, рискованно или вообще невозможно.

3. Ограниченные по ресурсам платформы
На очень слабых микроконтроллерах или старых SoC полноценная реализация SSH может быть слишком тяжёлой по требованиям к памяти и CPU, тогда как telnet и минимальный набор утилит занимают считанные сотни килобайт.

4. Консервативные инфраструктуры
Где-то используются старые скрипты автоматизации, интеграции с мониторингом и управления, завязанные именно на telnet-интерфейс. Переход на другие протоколы требует как минимум переработки значительной части инфраструктуры.

Поэтому ответ на вопрос "Кто этим ещё пользуется?" прост: да, пользователи есть - и порой это крупные организации, где от правильной настройки сетевого оборудования зависит работоспособность целых сегментов инфраструктуры.

Телнет и криптография: можно ли "прикрутить защиту"?

Справедливый аргумент, который часто всплывает: если уж не получается отказаться от telnet совсем, нельзя ли просто "обернуть" его в какой-то шифрованный туннель или встроить простую криптографию даже на очень слабых устройствах?

С точки зрения симметричной криптографии (salsa, chacha и другие поточные/блочные алгоритмы) задача действительно решаема даже на микроконтроллерах с очень скромными ресурсами. Простейшие реализации могут быть относительно компактными и достаточно быстрыми.

Но здесь сразу возникает несколько проблем:

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

Фактически, любое серьёзное "наращивание крипто" вокруг telnet неизбежно начинает напоминать по сложности уже существующие защищённые протоколы вроде SSH или TLS. И возникает закономерный вопрос: если мы готовы тратить усилия на реализацию и сопровождение собственного зашифрованного "телнета", не проще ли сразу использовать отлаженный и массово проверенный на практике SSH?

Вопрос реализации: C, Rust и уязвимости стандартных библиотек

Отдельный пласт дискуссии - выбор языка реализации сетевых демонов. Современные языки системного программирования, такие как Rust, предлагают более строгие гарантии безопасности памяти, что частично снижает риск целого класса уязвимостей (переполнение буфера, use-after-free и т.п.).

Однако уязвимости, о которых идёт речь в контексте telnetd, наглядно показывают: даже без типичных для C ошибок управления памятью, остаются логические и архитектурные проблемы:

- небезопасное доверие к переменным окружения;
- сложное взаимодействие между библиотеками (gettext, glibc);
- исторически сложившиеся контракты между программами, которые уже никто не пересматривает.

Даже если переписать telnetd и /bin/login на более безопасном языке, вопросы того, какие переменные окружения разрешать, как организовать безопасную загрузку модулей и библиотек, какие каталоги считать доверенными, никуда не исчезнут. Язык может уменьшить количество багов низкого уровня, но не избавит от необходимости тщательно проектировать всю архитектуру безопасности.

Что делать администраторам прямо сейчас

Для тех, кто по тем или иным причинам продолжает использовать telnetd, особенно из пакета GNU InetUtils, минимальный набор рекомендаций выглядит так:

1. Оценить необходимость telnet вообще
Если есть возможность полностью перейти на SSH - это лучший вариант. Чаще всего именно человеческий фактор ("так всегда делали", "лень менять скрипты") мешает отказаться от telnet.

2. Ограничить область видимости telnetd
Если отключить нельзя - ограничьте доступ к порту telnet:
- только с внутренних, строго контролируемых подсетей;
- через VPN;
- с применением списков контроля доступа и межсетевых экранов.

3. Запретить анонимный и ненужный доступ
Отключите любые гостевые учётные записи, запретите вход под root по telnet, используйте отдельные непривилегированные аккаунты для администрирования с последующим повышением привилегий уже внутри системы (sudo, su).

4. Проверить реализацию telnetd
Узнайте, какой конкретно telnetd используется в вашей системе:
- если это GNU InetUtils без заплат - оцените возможность замены на версию с белым списком переменных или перехода на реализацию из других проектов;
- если используете дистрибутив, где telnetd модифицирован (как в Rocky Linux или FreeBSD), изучите настройки фильтрации окружения.

5. Минимизировать влияние переменных окружения
Там, где возможно, ограничивайте набор передаваемых переменных до безопасного минимума. Любые механизмы, позволяющие пользователю вмешиваться в окружение процесса login, должны рассматриваться как потенциально опасные.

6. Следить за обновлениями безопасности
Поскольку обсуждаемые уязвимости связаны с довольно древними механизмами, велика вероятность, что вокруг них будет ещё не одна волна исправлений и уточнений. Имеет смысл регулярно отслеживать обновления пакетов inetutils и glibc в используемом дистрибутиве.

Итог

История с новыми уязвимостями в telnetd ещё раз показывает: старые и кажущиеся "простыми" протоколы продолжают быть источником серьёзных рисков. Попытки точечной фильтрации опасных переменных окружения в итоге приводят лишь к появлению всё новых обходных путей.

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

- жёстко ограничивать область его применения;
- использовать белый список переменных окружения;
- внимательно следить за обновлениями и рекомендациями по безопасности.

И главное - не считать, что "никому это уже не интересно". Пока telnetd доступен из сети и управляет запуском процессов от имени root, уязвимости в нём будут представлять серьёзную ценность для атакующих, независимо от того, насколько "устаревшим" кажется сам протокол.

Прокрутить вверх