Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2022-41218 — Détails de la vulnérabilité pour CVE-2022-41218 | Kitploit
Outils/GitHubGitHub/tobey123/cve-2022-41218
Analyse des VulnérabilitésExploitationExploitation de Binaires
GitHubtobey123/cve-2022-41218

CVE-2022-41218

Détails de la vulnérabilité pour CVE-2022-41218

Voir le dépôt
4il y a 4 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Introduction

Cette vulnérabilité est une vulnérabilité de type course (race condition) qui se produit dans drivers/media/dvb-core/dmxdev.c. Par conséquent, une condition de course peut survenir dans le pilote de périphérique USB utilisant ce dmxdev.

Cette vulnérabilité pourrait être utilisée pour déclencher 3 UAFs.

Vulnérabilité

1. Écriture UAF dans vmalloc

Tout d'abord, l'ordre de l'exploit est le suivant(j'ai débogué en utilisant 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!!

Le flux d'exploitation détaillé est le suivant :

1. open() dvr0 parmi les nœuds de périphérique. Cela appelle dvb_dvr_open() pour provoquer l'exécution de `dvbdev->users++`.
Dans ce cas, lorsque ttusb_dec_disconnect() est exécutée en retirant le périphérique USB, la condition `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)` est capturée.

2. Retirez physiquement le périphérique USB.
Dans ce cas, pendant que la fonction ttusb_dec_disconnect() est en cours d'exécution, elle attend au niveau de `wait_event(dmxdev->dvr_dvbdev->wait_queue, …)`.

3. open() le nœud demux0 pour que la fonction dvb_demux_open() soit appelée.
Cette fonction exécute également `dvbdev->users++` de la même manière que la fonction dvb_dvr_open() à l'étape 1.
Cependant, ce comptage de références incorrect se produit parce que la fonction dvb_dmxdev_release() qui est actuellement en attente a déjà passé la vérification 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);
}

Il appelle ensuite ioctl() sur demux0. Lors de l'appel, le 3ème argument soumet l'adresse en espace utilisateur définie par userfaultfd(or FUSE fs). Maintenant, pendant que ioctl est en cours d'exécution, il se bloquera sur 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() the fd in the thread that open()ed the dvr0 node.  
Ensuite, `dvb_dvr_release()` est appelée, et `dvbdev->users--` ainsi que `wake_up(&dvbdev->wait_queue)` sont exécutés pour réveiller la fonction `dvb_dmxdev_release()`, qui correspond au flux .disconnect.

5. Dans le flux .disconnect, la fonction `dvb_dmxdev_release()` exécute `vfree(dmxdev->filter)`.

6. Relâchez l’userfaultfd depuis le thread ioctl demux0 qui a configuré l’userfaultfd.  
Cela provoquera une UAF en lisant l’adresse `dmxdev->filter` que vous venez de libérer depuis .disconnect.  
L’UAF peut désormais être utilisée dans tous les cas de `dvb_demux_do_ioctl()`, et même une escalade de privilèges (LPE) est possible lorsqu’elle est associée à eBPF.
Télécharger l’outil