Título do Projeto
Gerador de exploit para CVE-2021-3156 sudo
Instalação
- Instala dependências ./install.sh
- Executa gerador de exploit: ./run.sh
- Se a versão do sudo do sistema for vulnerável, é gerado um exploit para a versão instalada
- O exploit é gerado em exploit.c e o binário ./exploit
Requisitos
- gdb gcc make python3 python3-distro
- glibc com tcache
- Atualmente sistemas operacionais Ubuntu, Debian.
Testado
- Ubuntu 20.04.1
- Ubuntu 20.04.2
- Ubuntu 20.10
- Ubuntu 18.04.5
- Debian 10.7.0
Autor
Vulnerabilidade
- sudo escapa metacaracteres na função parse_args em main
- Posteriormente, em set_cmnd, os caracteres de escape que não são seguidos de espaço são eliminados
- sudo assume que parse_args é uma pré-condição de set_cmnd.
- O problema é que as condições são diferentes em cada parser. O primeiro é executado se o modo for (MODE_RUN && MODE_SHELL). O segundo é executado se o modo for (MODE_RUN | MODE_EDIT | MODE_CHECK) E (MODE_SHELL|MODE_LOGIN_SHELL)
- Existe uma forma de não executar o primeiro parser mas sim o segundo: sudoedit -s
- set_cmnd calcula o tamanho dos argumentos e cria um chunk no heap para concatená-los. Depois copia cada argumento até encontrar um byte nulo e continua para o próximo. Se o argumento de entrada terminar com uma '\', set_cmnd pula o caractere de escape, copia o byte nulo mas continua copiando o próximo argumento como se fosse o mesmo. Isso produz um estouro de buffer no heap.
- Portanto, se o último argumento terminar com '\', set_cmnd estoura o buffer com o conteúdo da primeira variável de ambiente. Se esta variável de ambiente terminar em '\', continuará copiando a próxima.
Gerador Exploit
- Usa-se o método 2 descrito em (https://packetstormsecurity.com/files/161160/Sudo-Heap-Based-Buffer-Overflow.html)
- sudo usa glibc nsswitch para ler a base de dados group após o estouro.
- nsswitch cria uma estrutura de dados service_table no heap com todas as bases de dados e serviços de nsswitch.conf.
- Os serviços de group têm o tipo struct service_user.
- A estrutura possui um campo name com o nome do serviço
- nsswitch carrega dinamicamente uma biblioteca libnss_[nome_serviço]_.so.2 de acordo com a configuração de /etc/nsswitch.conf para cada serviço da base de dados group.
- O ponteiro library deve ser sobrescrito com NULL para evitar crash. Além disso, isso faz com que a biblioteca seja recarregada na memória, desta vez uma biblioteca local com a shellcode.
- Usa-se a técnica heap grooming ou feng shui. Criam-se variáveis de ambiente "locais" de tamanho variável para gerar um layout no heap que permita aproximar o chunk no qual set_cmnd copia os argumentos do objetivo que é a estrutura service_user de group.
- Imediatamente antes de executar o malloc de set_cmnd, verifica-se a tcache do heap para ver os primeiros chunks que serão reciclados e seus tamanhos.
- Ordenam-se os chunks que formam as bases de dados e serviços de nsswitch. Percorrem-se de forma ordenada. Armazena-se o endereço de memória do chunk alvo e do anterior.
- Busca-se na tcache bin um chunk dentro desse intervalo.
- Uma vez conhecida a posição do chunk e seu tamanho, gera-se o exploit.
- Usa-se um argumento terminado em '\' e byte nulo do tamanho preciso para que aquele chunk seja reciclado.
- Criam-se as variáveis 'locais' de ambiente necessárias para criar o layout adequado.
- Antes dessas variáveis 'locais', gera-se uma variável de ambiente do tamanho necessário para alcançar a estrutura alvo.
- Sobrescreve-se a estrutura alvo com bytes nulos usando arrays de strings com o caractere de escape '\'; isso faz com que um byte nulo seja escrito em set_cmnd
- Sobrescreve-se o name de service_user com 'x/x' para que posteriormente seja carregada a biblioteca 'libnss_x/x.so.2'
- Na biblioteca, cria-se um construtor que executa uma shellcode.
- Como sudo é executado com bit suid, a shell pertence a root.
Licença
Este projeto está sob a Licença GNU GPL