
Reproduz RCE não autenticado no ZendTo via ClamAV e escalada de privilégios para root em laboratório autorizado, com alvo Docker fixado, verificação fail-closed, saída vinculada a nonce e limpeza.
Este diretório é um pacote de reprodução autônomo e de laboratório autorizado para a cadeia de execução de código ZendTo-para-ClamAV sem conta e sua continuação separada Smarty/cron root do perfil padrão. Ele inclui:
O PoC inicial executa um comando selecionado pelo chamador como a conta de serviço clamav padrão. A variante opcional continua essa posição sem conta até um comando selecionado pelo chamador como root. Ambas usam id como padrão, rejeitam o caminho literal /root/flag e retornam saída vinculada a nonce via HTTPS.
As relações vulneráveis de grupo, diretório, Smarty e cron root são padrões do pacote/instalador Debian do ZendTo. A alcançabilidade do root é, no entanto, condicionada ao ambiente: esta montagem positiva exata usa um volume /var/zendto com filesystem ext4, PHP CLI funcional com FFI/POSIX/exec e um processo clamd sem confinamento. A aplicação de AppArmor/SELinux ou de semânticas de filesystem incompatíveis pode bloquear a continuação em outra instalação que seria padrão.
Use isto apenas na montagem descartável incluída ou em outro sistema que você esteja explicitamente autorizado a testar.
O destino exato e autoritativo é um artefato local, intencionalmente sem versionamento, em:
image/zendto-installer-systemd-debian12.tar.zst
O Git ignora arquivos de imagem Docker. Antes de uma regressão exata, coloque uma cópia local autorizada nesse caminho; scripts/setup.sh exige a SHA-256 registrada e o ID da imagem. source-recipe/README.md documenta como a imagem derivada do instalador foi construída e capturada. Uma nova compilação a partir de repositórios de pacotes ativos é útil para testar a topologia, mas não é considerada byte idêntica ao destino fixado.
A configuração e o entrypoint do contêiner rejeitam qualquer divergência do seguinte perfil:
| Componente | Valor testado exato |
|---|---|
| ID da imagem Docker | sha256:de6d2f06ca04943362a9bdec5026e808448953728f31bd926343a4ed2ca2ef7c |
| ZendTo | 6.15-8 |
| Pacote ClamAV/libclamav | 1.4.3+dfsg-1~deb12u2 |
| libclamav | libclamav.so.12.0.3, SHA-256 55e3cd94…027c |
| ID de build do libclamav | e6427ab62146ee3001fe463d12e797e9d25bf81a |
| glibc | 2.36-9+deb12u14, SHA-256 6b4a4535…421 |
| banco de dados main | v63, SHA-256 0b2182d2…365 |
| banco de dados daily | v28082, SHA-256 cddbcccf…906 |
| banco de dados bytecode | v339, SHA-256 6d4aa01f…ffb |
| clamd | MaxThreads 12, IdleTimeout 30, Restart=no |
| ciclo de vida | clamav-daemon.socket habilitado, systemd como PID 1 |
| runtime web | Apache 2.4.68, PHP 8.2.32 |
| postura MAC | montagem Docker privilegiada e sem confinamento |
| ponte para root | clamav padrão em www-data; /var/zendto root:www-data 0775 |
| consumidor root | cron de limpeza root padrão, a cada hora no minuto 25 |
| cache Smarty | zendto.conf compilado determinístico do Smarty 4.5.4 |
| filesystem de troca | volume nomeado /var/zendto com ext4 |
Os valores completos estão em PROFILE.json.
Isso é mais forte do que fixar apenas a versão do pacote ClamAV. A construção do alocador também depende de glibc, tráfego de parser orientado por CVD, configurações de worker e da biblioteca de destino exata. O FreshClam está desabilitado na imagem capturada, e a inicialização falha se daily.cvd tiver sofrido desvio ou se um daily.cld tiver aparecido.
O contêiner de pesquisa atualmente em execução prolongada no workspace pai não é a montagem limpa: testes posteriores desabilitaram sua forma de remetente externo e atualizaram seu banco de dados daily. Essas alterações foram intencionalmente excluídas aqui. Este pacote usa a linha de base limpa contra a qual a execução nativa foi demonstrada.
/sys/fs/cgroupzstd, Python 3 com venv, um compilador C, file e GNU readelfO destino compartilha o kernel do host e a implementação de ASLR. O comportamento de mapeamento dependente do kernel permanece, portanto, uma variável de portabilidade.
Apenas uma montagem systemd deve compartilhar o namespace de cgroup do host por vez. Na máquina de pesquisa original, pare a montagem mais antiga sem excluí-la:
docker stop zendto-installer-systemd-native
Ela pode ser restaurada posteriormente com docker start zendto-installer-systemd-native.
A partir deste diretório:
./scripts/verify-bundle.sh
./scripts/setup.sh
O script de configuração:
.venv com as dependências Python do PoC fixadas;/var/zendto e inicia o systemd;renameat2(RENAME_EXCHANGE) executada como clamav.Os endpoints padrão são somente loopback:
http://127.0.0.1:18084/
https://127.0.0.1:18447/
O certificado é autoassinado. O PoC usa deliberadamente verify=False em toda requisição HTTP. Portas de loopback diferentes podem ser selecionadas antes da configuração:
export ZENDTO_HTTP_PORT=19084
export ZENDTO_HTTPS_PORT=19447
./scripts/setup.sh
Use as mesmas variáveis de ambiente para comandos posteriores de Compose/auxiliares.
Verifique o destino a qualquer momento:
./scripts/verify-target.sh
docker compose ps
A linha de base limpa do instalador tem:
allowExternalUploads = TRUE
confirmExternalEmails = TRUE
captcha = google
Seus valores de CAPTCHA e de e-mail são placeholders do instalador, portanto o arquivo intocado não consegue realmente entregar o e-mail público de verificação. O teste de regressão nativa representou apenas essa etapa concluída do aplicativo com uma linha equivalente de AuthData de remetente externo. O código, os pacotes, o scanner, as permissões e o caminho de exploração do destino não foram corrigidos.
Crie essa única linha de laboratório e um arquivo de token com modo 0600 com:
./scripts/mint-lab-auth.py [email protected]
O valor do token é suprimido e armazenado em:
.lab/upload-auth-token.txt
Este auxiliar local não é uma afirmação de que uma implantação com upload externo desabilitado pode ser explorada remotamente. Se o formulário público de remetente externo estiver desabilitado, o PoC para corretamente antes do ClamAV mesmo quando um arquivo de token é fornecido.
Em uma implantação autorizada configurada normalmente, omita --external-auth-token-file: abra manualmente a página de verificação, resolva o CAPTCHA, receba a mensagem gerada pelo destino em uma caixa de correio controlada pelo atacante e cole sua URL/token no prompt oculto.