Qualys identificou uma vulnerabilidade (CVE-2021-4034) no componente do sistema Polkit (anteriormente PolicyKit) usado em distribuições para permitir que usuários sem privilégios executem ações que exigem direitos de acesso elevados. A vulnerabilidade permite que um usuário local sem privilégios aumente seus privilégios para root e obtenha controle total do sistema. O problema recebeu o codinome PwnKit e é notável por produzir uma exploração funcional que é executada na configuração padrão na maioria das distribuições Linux.
O problema está presente no utilitário pkexec do PolKit, que vem com o sinalizador root SUID e foi projetado para executar comandos com privilégios de outro usuário de acordo com as regras especificadas do PolKit. Devido ao tratamento incorreto dos argumentos de linha de comando passados para pkexec, um usuário sem privilégios poderia ignorar a autenticação e executar seu código como root, independentemente das regras de acesso definidas. Para um ataque, não importa quais configurações e restrições sejam especificadas no PolKit, basta que o atributo raiz SUID seja definido para o arquivo executável com o utilitário pkexec.
Pkexec não verifica a validade da contagem de argumentos da linha de comando (argc) passada ao iniciar um processo. Os desenvolvedores do pkexec presumiram que a primeira entrada no array argv sempre contém o nome do processo (pkexec), e a segunda um valor NULL ou o nome do comando iniciado via pkexec. Como a contagem de argumentos não foi verificada em relação ao conteúdo real do array e foi considerada sempre maior que 1, se um processo recebesse um array argv vazio, como a função execve do Linux permite, pkexec trataria NULL como o primeiro argumento ( o nome do processo) e o próximo como fora da memória buffer, como o conteúdo subsequente da matriz. |———+———+——+————|———+———+——+————| | argv[0] | argv[1] | ... | argv[argc] | ambiente[0] | ambiente[1] | ... | envp[envc] | |—-|—-+—-|—-+——+——|——|—-|—-+——+——|——| VVVVVV "programa" "-opção" NULL "valor" "PATH=nome" NULL
O problema é que após o array argv existe um array envp na memória contendo variáveis de ambiente. Assim, se o array argv estiver vazio, pkexec extrai dados sobre o comando executado com privilégios elevados do primeiro elemento do array com variáveis de ambiente (argv[1] tornou-se idêntico a envp[0]), cujo conteúdo pode ser controlado pelo atacante.
Tendo recebido o valor de argv[1], pkexec tenta, levando em consideração os caminhos dos arquivos em PATH, determinar o caminho completo para o arquivo executável e grava um ponteiro para a string com o caminho completo de volta para argv[1], que leva à substituição do valor da primeira variável de ambiente, uma vez que argv[ 1] é idêntico a envp[0]. Ao manipular o nome da primeira variável de ambiente, um invasor pode substituir outra variável de ambiente no pkexec, por exemplo, substituir a variável de ambiente “LD_PRELOAD”, que não é permitida em programas suid, e fazer com que sua biblioteca compartilhada seja carregada no processo.
A exploração funcional envolve a substituição da variável GCONV_PATH, que é usada para determinar o caminho para a biblioteca de transcodificação de símbolos, carregada dinamicamente ao chamar a função g_printerr(), cujo código usa iconv_open(). Ao redefinir o caminho em GCONV_PATH, um invasor pode garantir que não é a biblioteca iconv padrão que está sendo carregada, mas sua própria biblioteca, cujos manipuladores serão executados quando uma mensagem de erro for exibida no estágio em que o pkexec ainda está em execução com direitos de root e antes que as permissões de inicialização sejam verificadas.
Observa-se que, apesar do problema ser causado por corrupção de memória, ele pode ser explorado de forma confiável e repetida, independentemente da arquitetura de hardware utilizada. A exploração preparada foi testada com sucesso no Ubuntu, Debian, Fedora e CentOS, mas também pode ser usada em outras distribuições. A exploração original ainda não está disponível publicamente, indicando que é trivial e pode ser facilmente recriada por outros pesquisadores, por isso é importante instalar a atualização do patch o mais rápido possível em sistemas multiusuários. Polkit também está disponível para sistemas BSD e Solaris, mas não foi estudado para uso neles. O que se sabe é que o ataque não pode ser realizado no OpenBSD, pois o kernel do OpenBSD não permite que um valor argc nulo seja passado quando execve() é chamado.
O problema está presente desde maio de 2009, desde a adição do comando pkexec. A correção para a vulnerabilidade do PolKit está atualmente disponível como patch (nenhuma versão de patch foi lançada), mas como os desenvolvedores da distribuição foram notificados do problema com antecedência, a maioria das distribuições publicou a atualização simultaneamente com a divulgação de informações sobre a vulnerabilidade. O problema foi corrigido no RHEL 6/7/8, Debian, Ubuntu, openSUSE, SUSE, Fedora, ALT Linux, ROSA, Gentoo, Void Linux, Arch Linux e Manjaro. Como medida temporária para bloquear a vulnerabilidade, você pode remover o sinalizador raiz SUID do programa /usr/bin/pkexec (“chmod 0755 /usr/bin/pkexec”).
Fonte: opennet.ru