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

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

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

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

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

Категории

Все категории
Loading categories
CVE-2022-41218 — Сведения об уязвимости CVE-2022-41218 | Kitploit
Инструменты/GitHubGitHub/tobey123/cve-2022-41218
Анализ уязвимостейЭксплуатацияЭксплуатация Бинарных Файлов
GitHubtobey123/cve-2022-41218

CVE-2022-41218

Сведения об уязвимости CVE-2022-41218

Репозиторий
44 лет назадЕщё не проверено

Популярное

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

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

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

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

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

Введение

Эта уязвимость представляет собой уязвимость состояния гонки (race condition), возникающую в drivers/media/dvb-core/dmxdev.c. Следовательно, состояние гонки может возникнуть в драйвере USB-устройства, использующем этот dmxdev.

Эта уязвимость может быть использована для инициирования 3 UAF.

Уязвимость

1. vmalloc UAF write

Во-первых, порядок эксплуатации следующий (я отлаживал с использованием drivers/media/usb/ttusb-dec/ttusb_dec.c):``` cpu0 cpu1 cpu 2 1. dvb_dvr_open() 2. ttusb_dec_disconnect() ttusb_dec_exit_dvb() dvb_dmxdev_release() wait_event(dmxdev->dvr_dvbdev->wait_queue, …) 3. dvb_demux_open() dvb_demux_ioctl() dvb_usercopy() copy_from_user() <- userfaultfd stuck 4. dvb_dvr_release() 5. vfree(dmxdev->filter) 6. copy_from_user() <- userfaultfd release dvb_demux_do_ioctl() struct dmxdev *dmxdev = dmxdevfilter->dev; <- UAF!!

Подробный поток эксплуатации выглядит следующим образом:

1. open() dvr0 среди узлов устройства. Это вызывает dvb_dvr_open(), что приводит к выполнению `dvbdev->users++`.
В этом случае, когда ttusb_dec_disconnect() выполняется при извлечении usb-устройства, условие `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)` перехватывается.

2. Физически извлеките USB-устройство.
В этом случае, пока выполняется функция ttusb_dec_disconnect(), она ожидает на `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

3. open() узел demux0, чтобы вызвать функцию dvb_demux_open().
Эта функция также выполняет `dvbdev->users++` аналогично функции dvb_dvr_open() на шаге 1.
Однако это неправильное подсчет ссылок происходит потому, что ожидающая функция dvb_dmxdev_release() уже прошла проверку на `dvbdev->users`:```
void dvb_dmxdev_release(struct dmxdev *dmxdev)
{
        dmxdev->exit = 1;
        if (dmxdev->dvbdev->users > 1) {    // This check is bypassed. improper reference counting.
                wait_event(dmxdev->dvbdev->wait_queue,
                                dmxdev->dvbdev->users == 1);
        }
        if (dmxdev->dvr_dvbdev->users > 1) {
                wait_event(dmxdev->dvr_dvbdev->wait_queue,    // Currently wait()ing here.
                                dmxdev->dvr_dvbdev->users == 1);
        }

        dvb_unregister_device(dmxdev->dvbdev);
        dvb_unregister_device(dmxdev->dvr_dvbdev);

        vfree(dmxdev->filter);
        dmxdev->filter = NULL;
        dmxdev->demux->close(dmxdev->demux);
}

Затем он вызывает ioctl() на demux0. При вызове третий аргумент передаёт адрес пользовательского пространства, установленный с помощью userfaultfd(или FUSE fs). Теперь, пока выполняется ioctl, он зависнет на copy_from_user() из dvb_usercopy():``` int dvb_usercopy(struct file *file, unsigned int cmd, unsigned long arg, int (*func)(struct file *file, unsigned int cmd, void *arg)) { char sbuf[128]; void *mbuf = NULL; void *parg = NULL; int err = -EINVAL;

    /*  Copy arguments into temp kernel buffer  */
    switch (_IOC_DIR(cmd)) {
    case _IOC_NONE:
            /*
             * For this command, the pointer is actually an integer
             * argument.
             */
            parg = (void *) arg;
            break;
    case _IOC_READ: /* some v4l ioctls are marked wrong ... */
    case _IOC_WRITE:
    case (_IOC_WRITE | _IOC_READ):
            if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
                    parg = sbuf;
            } else {
                    /* too big to allocate from stack */
                    mbuf = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
                    if (NULL == mbuf)
                            return -ENOMEM;
                    parg = mbuf;
            }

            err = -EFAULT;
            if (copy_from_user(parg, (void __user *)arg, _IOC_SIZE(cmd)))   // here
                    goto out;
            break;
    }
4. close() файловый дескриптор в потоке, который открыл узел dvr0.
Затем вызывается dvb_dvr_release(), и выполняются `dvbdev->users--` и `wake_up(&dvbdev->wait_queue)`, чтобы разбудить функцию dvb_dmxdev_release(), которая является частью потока .disconnect.

5. В потоке .disconnect, в функции dvb_dmxdev_release() выполняется `vfree(dmxdev->filter)`.

6. Освобождение userfaultfd из потока ioctl demux0, который установил userfaultfd.
Это приведёт к возникновению UAF при чтении адреса `dmxdev->filter`, только что освобождённого из .disconnect.
Теперь UAF можно использовать во всех случаях dvb_demux_do_ioctl(), и даже LPE возможен при связке с eBPF.
Скачать инструмент