Skip to content
KitploitKITPLOIT
FerramentasExploitsBlog
Log in
Enviar
FerramentasExploitsBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2022-41218 — Detalhes da Vulnerabilidade para CVE-2022-41218 | Kitploit
Ferramentas/GitHubGitHub/tobey123/cve-2022-41218
Análise de VulnerabilidadesExploraçãoExploração de Binários
GitHubtobey123/cve-2022-41218

CVE-2022-41218

Detalhes da Vulnerabilidade para CVE-2022-41218

Ver Repositório
4há 4 anosAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

Introdução

Esta vulnerabilidade é uma vulnerabilidade de condição de corrida que ocorre em drivers/media/dvb-core/dmxdev.c. Portanto, uma condição de corrida pode ocorrer no driver de dispositivo usb que usa este dmxdev.

Esta vulnerabilidade pode ser usada para desencadear 3 UAFs.

Vulnerabilidade

1. vmalloc UAF write

Primeiro, a ordem do exploit é a seguinte(depurei 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!!

O fluxo detalhado de exploração é o seguinte:

1. open() dvr0 entre os nós de dispositivo. Isso faz com que dvb_dvr_open() seja chamada, executando `dvbdev->users++`.  
   Nesse caso, quando ttusb_dec_disconnect() é executada ao remover o dispositivo USB, a condição `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)` é capturada.

2. Remova fisicamente o dispositivo USB.  
   Nesse caso, enquanto a função ttusb_dec_disconnect() está sendo executada, ela aguarda em `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

3. open() o nó demux0 para que a função dvb_demux_open() seja chamada.  
   Esta função também executa `dvbdev->users++` de forma semelhante à função dvb_dvr_open() no passo 1.  
   Porém, essa contagem de referência incorreta ocorre porque a função dvb_dmxdev_release(), que está atualmente em espera, já passou pela verificação 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);
}

Em seguida, chama ioctl() em demux0. Ao chamar, o terceiro argumento submete o endereço do espaço do usuário definido por userfaultfd(ou FUSE fs). Agora, enquanto ioctl está em execução, ele irá travar em 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() o fd na thread que open() o nó dvr0.
Em seguida, dvb_dvr_release() é chamada, e `dvbdev->users--` e `wake_up(&dvbdev->wait_queue)` são executados para despertar a função dvb_dmxdev_release(), que é o fluxo .disconnect.

5. No fluxo .disconnect, na função dvb_dmxdev_release(), `vfree(dmxdev->filter)` é executado.

6. Libere o userfaultfd da thread ioctl do demux0 que configurou o userfaultfd.
Isso fará com que o UAF ocorra ao ler o endereço `dmxdev->filter` que você acabou de liberar do .disconnect.
O UAF agora pode ser usado em todos os casos de dvb_demux_do_ioctl(), e até mesmo LPE é possível quando vinculado ao eBPF.
Baixar ferramenta