
Write-up educacional e PoC em modo de teste para CVE-2026-92162, um path traversal no parâmetro arch do DeployAppstream do Flatpak que permite a criação de diretórios root.
Write-up educacional e prova de conceito em modo de teste para um path traversal no
helper de sistema do Flatpak (flatpak-system-helper). O método D-Bus DeployAppstream
aceita uma string arch que é inserida em um caminho de filesystem e criada
como root, sem nenhuma validação. Um usuário local ativo pode fornecer componentes ../ e
fazer com que o serviço com privilégios de root crie diretórios fora da árvore
appstream pretendida.
Este repositório acompanha a análise técnica completa e o post-mortem da pesquisa. Ele existe para fins educacionais, para defensores que desejam entender o mecanismo e para testes autorizados em sistemas que você possui ou tem permissão por escrito para avaliar.
Este material é publicado após divulgação coordenada e após uma versão corrigida do Flatpak ter sido disponibilizada. Execute a prova de conceito apenas contra uma máquina de laboratório que você possui ou está explicitamente autorizado a testar. Não a execute contra sistemas que você não controla. Você é responsável por permanecer dentro da lei e dentro do escopo de qualquer autorização que possua.
handle_deploy_appstream() no helper de sistema valida o argumento origin
mas não o argumento arch. Para um remote OCI, arch flui para
flatpak_build_file e então g_mkdir_with_parents, que é executado como root e
resolve ../ lexicalmente. A ação polkit para o método é
org.freedesktop.Flatpak.appstream-update, que é allow_active=yes, então uma
sessão local ativa alcança o código sem prompt de senha. Em um sistema que
já possui um remote OCI, como um Fedora Workstation padrão com seu remote fedora,
um usuário com baixos privilégios pode criar diretórios de propriedade do root em um caminho
arbitrário. O payload neste repositório tem como alvo o próprio /root/.ssh.
Esta vulnerabilidade, o Achado A, foi demonstrada como parte de uma cadeia de duas
vulnerabilidades usada para escalar de um usuário local não autenticado para root na
máquina, em um laboratório controlado e autorizado. A cadeia funciona da seguinte forma:
o Achado A cria /root/.ssh como root. O Achado B, uma primitiva de escrita secundária,
pode então escrever conteúdo controlado pelo atacante nesse diretório. Juntos, eles
dão ao atacante um arquivo de propriedade do root em um caminho escolhido pelo atacante. Cada bug sozinho
é limitado: o Achado A apenas cria diretórios, e o Achado B só pode escrever
onde um diretório pai já existe. O Achado A fornece o diretório pai
que o Achado B precisa, e o par se torna escrita de arquivo como root.
O Achado B foi identificado de forma independente por esta pesquisa, mas não é um novo
achado: é a fraqueza conhecida e ainda não corrigida no caminho de escrita de dados extras
do Deploy, documentada no post-mortem da pesquisa. Este write-up, portanto,
cobre e é creditado pelo Achado A, e usa o Achado B apenas como o componente conhecido
e não corrigido no qual a cadeia se apoia.
Este repositório demonstra apenas o Achado A. A metodologia de encadeamento e as lições defensivas estão documentadas no post-mortem da pesquisa.
O projeto já inclui flatpak_is_valid_arch, que restringe um
nome de arquitetura a [A-Za-z0-9_]. A remediação é chamá-lo sobre o argumento arch
na fronteira do handler e dentro dos helpers de construção de caminho. Um valor ../
não pode passar por esse predicado. Atualize para a versão corrigida do Flatpak.
.
├── README.md Este arquivo.
├── requirements.txt Pré-requisitos de pacotes do sistema para o PoC.
└── poc_arch_traversal.sh PoC para o parâmetro arch não validado.
Modo de teste em sandbox por padrão, o modo de produção
tem como alvo /root/.ssh. Apenas para uso educacional.
requirements.txt
presentes.allow_active=yes. Verifique com:
loginctl list-sessions e confirme que sua sessão mostra um seat./usr/libexec/flatpak-system-helper; o
script primeiro procura por um helper recém-compilado em builddir/ ou _build/ da
árvore de código-fonte do Flatpak, e FLATPAK_SYSTEM_HELPER sobrescreve tudo.
Consulte requirements.txt para os pacotes de sistema necessários.O modo de produção detecta automaticamente um remote OCI existente na instalação do sistema e o utiliza. Qualquer remote OCI funciona, mesmo um falso ou inacessível, porque o mkdir acontece antes de o registro ser contatado. Se nenhum remote OCI existir, o script cancela com uma mensagem "No OCI remote found" e não envia nada.
O Fedora Workstation já inclui o remote OCI fedora, então nada precisa ser
feito lá. Verifique o que existe com flatpak remotes --system (um OCI
remote mostra oci em sua coluna de opções).
Este é o único comando em todo o fluxo que precisa de sudo, e o script nunca o executa por você. Adicione um com:
sudo flatpak remote-add --system --no-gpg-verify oci-poc oci+http://127.0.0.1:19876
(o flatpak não tem uma flag --oci, pelo menos até a versão 1.19.0, a versão na qual este trabalho
se baseia; o prefixo de URL oci+ é o que torna o remote um registro OCI.) Uma mensagem "Warning: Could not update extra metadata"
é esperada quando nenhum registro está em execução; o remote ainda é adicionado.
bash poc_arch_traversal.sh
O script inicia um barramento D-Bus privado e um helper em modo --session, tudo
sob um diretório temporário. Ele chama DeployAppstream com o payload
../../../../../root/.ssh e verifica que o diretório escapado foi criado
em <workdir>/root/.ssh, espelhando o alvo real. Espere um erro D-Bus no
meio da saída: é a busca do índice OCI falhando depois que o
diretório já foi criado, e é o comportamento esperado.
bash poc_arch_traversal.sh prod
O script nunca pede uma senha. Ele detecta automaticamente um remote OCI, dispara
DeployAppstream sem autenticação com o payload de traversal, e imprime a
resposta do helper. O helper root cria /root/.ssh e então falha no
registro inacessível, o que imprime o erro D-Bus esperado. Se a resposta
for um erro de autenticação, você não está em uma sessão local ativa;
execute-o a partir do console da máquina. Um remote específico pode ser forçado com
bash poc_arch_traversal.sh prod <remote>.
O gatilho em si é executado sem privilégios, mas confirmar o resultado precisa de root, então o script deixa isso para você. Após a execução, na mesma máquina:
sudo ls -laR /root/.ssh
sudo stat -c '%U:%G' /root/.ssh
O diretório deve existir e pertencer a root:root. O erro D-Bus na
saída do script não é uma falha: ele prova que o mkdir foi executado antes da busca, já que
o diretório escapado existe mesmo que a chamada do método tenha falhado.
Se /root/.ssh já existia antes da execução (por exemplo, em um host com um
sshd em execução), a execução é um no-op nesse caminho e não deixa nada para trás: o arquivo lock
do helper é transitório e é removido quando o método retorna, e
icons só é escrito após uma busca de índice bem-sucedida. Para uma verificação
limpa, execute contra um caminho que ainda não existe.
sudo rm -rf /root/.ssh # apenas se não existia antes da execução
sudo flatpak remote-delete --system oci-poc
Pesquisa e write-up por Yehia Ali Mohamed Ezzat.
A documentação e o código neste repositório são fornecidos para fins educacionais. Use por sua conta e risco e apenas onde você estiver autorizado.