Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
CVE-2022-41218 — Detalles de vulnerabilidad para CVE-2022-41218 | Kitploit
Herramientas/GitHubGitHub/tobey123/cve-2022-41218
Análisis de VulnerabilidadesExplotaciónExplotación de Binarios
GitHubtobey123/cve-2022-41218

CVE-2022-41218

Detalles de vulnerabilidad para CVE-2022-41218

Ver Repositorio
413hace 4 añosAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

Introducción

Esta vulnerabilidad es una vulnerabilidad de condición de carrera que ocurre en drivers/media/dvb-core/dmxdev.c. Por lo tanto, puede ocurrir una condición de carrera en el controlador del dispositivo usb que utiliza este dmxdev.

Esta vulnerabilidad podría usarse para desencadenar 3 UAFs.

Vulnerabilidad

1. Escritura UAF en vmalloc

Primero, el orden del exploit es el siguiente(depuré usando 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!!

El flujo detallado de explotación es el siguiente:

1. open() dvr0 entre los nodos del dispositivo. Esto llama a dvb_dvr_open() para que se ejecute `dvbdev->users++`.
En este caso, cuando se ejecuta ttusb_dec_disconnect() al eliminar el dispositivo usb, se captura la condición `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

2. Retirar físicamente el dispositivo USB.
En este caso, mientras se ejecuta la función ttusb_dec_disconnect(), espera en `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

3. open() el nodo demux0 para que se llame a la función dvb_demux_open().
Esta función también ejecuta `dvbdev->users++` similarmente a la función dvb_dvr_open() en el paso 1.
Sin embargo, este conteo de referencias incorrecto ocurre porque la función dvb_dmxdev_release() que está esperando ya ha pasado la comprobación de `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);
}

Luego llama a ioctl() en demux0. Al llamar, el tercer argumento envía la dirección del espacio de usuario establecida por userfaultfd (o FUSE fs). Ahora, mientras ioctl se está ejecutando, se detendrá en copy_from_user() de 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() el fd en el hilo que abrió el nodo dvr0.
Luego se llama a dvb_dvr_release(), y se ejecutan `dvbdev->users--` y `wake_up(&dvbdev->wait_queue)` para despertar a la función dvb_dmxdev_release(), que es el flujo .disconnect.

5. En el flujo .disconnect, en la función dvb_dmxdev_release(), se ejecuta `vfree(dmxdev->filter)`.

6. Libera userfaultfd desde el hilo ioctl de demux0 que configuró userfaultfd.
Esto provocará que ocurra el UAF al leer la dirección `dmxdev->filter` que acabas de liberar desde .disconnect.
Ahora se puede usar UAF en todos los casos de dvb_demux_do_ioctl(), e incluso es posible LPE cuando se vincula con eBPF.
Descargar herramienta