Skip to content
KitploitKITPLOIT
StrumentiBlog
Log in
Invia
StrumentiBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

··Feed·Contatto·Privacy·© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
CVE-2022-41218 — Dettagli della vulnerabilità per CVE-2022-41218 | Kitploit
Strumenti/GitHubGitHub/tobey123/cve-2022-41218
Analisi delle VulnerabilitàExploitBinary Exploitation
GitHubtobey123/cve-2022-41218

CVE-2022-41218

Dettagli della vulnerabilità per CVE-2022-41218

Vedi Repository
44 anni faNon ancora revisionato

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

Introduzione

Questa vulnerabilità è una vulnerabilità di tipo race condition che si verifica in drivers/media/dvb-core/dmxdev.c. Pertanto, una race condition può verificarsi nel driver di dispositivo USB che utilizza questo dmxdev.

Questa vulnerabilità potrebbe essere utilizzata per innescare 3 UAF.

Vulnerabilità

1. Scrittura UAF vmalloc

Innanzitutto, l'ordine dello sfruttamento è il seguente (ho eseguito il debug 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!!

The detailed exploit flow is as follows:

1. `open()` su `dvr0` tra i device node. Questo chiama `dvb_dvr_open()` per causare l'esecuzione di `dvbdev->users++`.
In questo caso, quando `ttusb_dec_disconnect()` viene eseguita rimuovendo il dispositivo USB, viene raggiunta la condizione `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

2. Rimuovere fisicamente il dispositivo USB.
In questo caso, mentre la funzione `ttusb_dec_disconnect()` è in esecuzione, rimane in attesa su `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

3. `open()` sul nodo `demux0` in modo che venga chiamata la funzione `dvb_demux_open()`.
Anche questa funzione esegue `dvbdev->users++`, analogamente alla funzione `dvb_dvr_open()` del passaggio 1.
Tuttavia, questo errato conteggio dei riferimenti si verifica perché la funzione `dvb_dmxdev_release()`, attualmente in attesa, ha già superato il controllo su `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);
}

Poi chiama ioctl() su demux0. Quando chiama, il 3° argomento invia l'indirizzo dello spazio utente impostato da userfaultfd (o filesystem FUSE). Ora, mentre ioctl è in esecuzione, si bloccherà su copy_from_user() di 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. Chiudi il fd nel thread che ha aperto il nodo dvr0.
Poi viene chiamata `dvb_dvr_release()`, e vengono eseguiti `dvbdev->users--` e `wake_up(&dvbdev->wait_queue)` per risvegliare la funzione `dvb_dmxdev_release()`, che è il flusso `.disconnect`.

5. Nel flusso `.disconnect`, nella funzione `dvb_dmxdev_release()`, viene eseguito `vfree(dmxdev->filter)`.

6. Rilascia userfaultfd dal thread ioctl demux0 che ha impostato userfaultfd.
Questo causerà l'UAF leggendo l'indirizzo `dmxdev->filter` appena rilasciato da `.disconnect`.
L'UAF può ora essere usato in tutti i casi di `dvb_demux_do_ioctl()`, ed è persino possibile l'LPE quando è combinato con eBPF.
Scarica lo strumento