A empresa Qualys identificou uma vulnerabilidade (CVE-2021-4034) no componente do sistema Polkit (antigo PolicyKit), utilizado em distribuições para gerenciar a execução de ações que exigem privilégios elevados por usuários não privilegiados. A vulnerabilidade permite que um usuário local não privilegiado eleve seus privilégios para os de um usuário root e obtenha controle total sobre o sistema. O problema recebeu o nome de código PwnKit e se destaca pela disponibilidade de um exploit funcional que opera na configuração padrão da maioria das distribuições Linux.
A questão está presente na ferramenta pkexec que faz parte do PolKit, fornecida com a flag SUID root e destinada a executar comandos com os privilégios de outro usuário, de acordo com as regras estabelecidas no PolKit. Devido ao manuseio inadequado dos argumentos da linha de comando passados para o pkexec, um usuário não privilegiado poderia contornar a autenticação e fazer com que seu código fosse executado com privilégios de root, independentemente das regras de acesso configuradas. Para a realização do ataque, não importa quais configurações e restrições estejam definidas no PolKit, basta que o executável da ferramenta pkexec tenha a flag SUID root.
O pkexec não verifica a validade do contador de argumentos da linha de comando (argc) ao iniciar o processo. Os desenvolvedores do pkexec pressupunham que a primeira entrada do array argv sempre conteria o nome do processo (pkexec) e a segunda entrada seria nula ou o nome do comando a ser executado via pkexec. Como o contador de argumentos não era validado em relação ao conteúdo real do array e acreditava-se que ele sempre era maior que 1, na hipótese de um array argv vazio ser passado ao processo, o que é permitido pela função execve no Linux, o pkexec interpretava o valor nulo como o primeiro argumento (nome do processo) e a memória além do buffer, como o conteúdo subsequente do array.
O problema é que, logo após o array argv na memória, há um array envp que contém as variáveis de ambiente. Assim, com um array argv vazio, o pkexec extrai os dados do comando que está sendo executado com privilégios elevados do primeiro elemento do array de variáveis de ambiente (argv[1] se torna idêntico a envp[0]), cujo conteúdo pode ser controlado pelo atacante.
Ao obter o valor de argv[1], o pkexec tenta, levando em conta os caminhos de arquivos em PATH, determinar o caminho completo para o arquivo executável e gravar um ponteiro para a string com o caminho completo de volta em argv[1], o que leva à sobrescrita do valor da primeira variável de ambiente, uma vez que argv[1] é idêntico a envp[0]. Através da manipulação do nome da primeira variável de ambiente, o atacante pode realizar a substituição de outra variável de ambiente no pkexec, por exemplo, substituindo a variável de ambiente 'LD_PRELOAD', que não é permitida em programas suid, e possibilitar o carregamento de sua própria biblioteca compartilhada no processo.
No exploit funcional, há a substituição da variável GCONV_PATH, que é usada para determinar o caminho da biblioteca de conversão de caracteres, carregada dinamicamente durante a chamada da função g_printerr(), cujo código utiliza iconv_open(). Ao redefinir o caminho em GCONV_PATH, o atacante pode fazer com que uma biblioteca iconv não padrão seja carregada, ao invés de sua biblioteca, cujos manipuladores serão executados durante a saída de mensagens de erro na fase em que o pkexec ainda está sendo executado com privilégios de root e antes da verificação das credenciais de execução.
Observa-se que, embora o problema seja causado por uma falha de memória, ele pode ser explorado de forma confiável e repetível, independentemente da arquitetura de hardware utilizada. O exploit preparado foi testado com sucesso no Ubuntu, Debian, Fedora e CentOS, mas pode ser usado em outras distribuições. O exploit original ainda não está disponível publicamente, o que indica que é trivial e pode ser facilmente recriado por outros pesquisadores, portanto, em sistemas multiusuário, é importante aplicar a atualização com a correção o mais rápido possível. O Polkit também está disponível para sistemas BSD e Solaris, mas a possibilidade de exploração neles não foi estudada. Sabe-se apenas que o ataque não pode ser realizado no OpenBSD, uma vez que o núcleo do OpenBSD não permite a passagem de um valor nulo em argc ao chamar execve().
O problema está presente desde maio de 2009, desde a adição do comando pkexec. A correção da vulnerabilidade no PolKit está disponível como um patch (a versão corrigida ainda não foi gerada), mas como os desenvolvedores das distribuições foram avisados sobre o problema com antecedência, a maioria das distribuições publicou uma atualização simultaneamente com a revelação da vulnerabilidade. O problema foi resolvido 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, é possível remover a flag SUID root do programa /usr/bin/pkexec ("chmod 0755 /usr/bin/pkexec").
Fonte: opennet.ru
