Uso de scripts SUID em Perl
Motivação
Há uns tempos atrás, mais ou menos uns 2 ou 3 meses (agosto ou setembro de 2002) tive problemas com a utilização de scripts Perl com o SUID bit ativado.
Minha primeira tentativa foi corrigir as permissões de todos os binários utilizados pelo próprio Perl, pensando que o problema poderia ter sido causado por uma atualização realizada um ou dois dias antes.
Minhas tentativas foram em vão, e então recorri a um grupo de usuários de Perl. Uma das respostas informava-me para recompilar o Perl. Após pensar um pouco, decidi fazê-lo e isto realmente resolveu o problema (minha distribuição de Linux havia desativado esta opção).
O interessante é que uma outra resposta, ao meu post informando que isso tinha resolvido o problema, dizia que eu não deveria usar os binários do Perl para scripts SUID. Devido ao remetente (Randal Schwartz — ou "merlyn", como é conhecido), questionei alguns motivos e as explicações de que era muito fácil explorar alguma vulnerabilidade no sistema foram mais do que suficientes para me convencer a seguir seus conselhos.
Com base nisto, decidi escrever este pequeno tutorial explicando como proceder para, de forma segura, utilizar scripts com o SUID ou SGID (ou ambos!) bit ativado.
Pré-requisitos
- A única exigência deste tutorial é um compilador C
Código C
#define REAL_PATH "/path/to/script"
main(ac, av)
char **av;
{
execv(REAL_PATH, av);
}
Código Perl para testes
#!/usr/bin/perl -w # # Este script está gravado com o seguinte nome: /home/godoy/teste.pl use English; print $EUID, "\n";
O módulo English é usado apenas para evitar o uso de $> no lugar de $EUID. Se não o tiver instalado, efetue a substituição inversa (recomendo ter este módulo; seus programas serão muito mais legíveis e fáceis de manter).
O resultado deste script é, em minha máquina:
[godoy@wintermute ~]$ perl teste.pl 550 [godoy@wintermute ~]$ id godoy uid=550(godoy) gid=550(godoy) grupos=550(godoy),24(cdrom),29(audio),400(desenv),907(ldp),551(cvs) [godoy@wintermute ~]$
Em sua máquina o número do usuário pode ser outro.
Código utilizado
O código C acima é genérico e pode ser modificado rapidamente para a execução de qualquer script. A única exigência é que o script em questão possua o bit de execução ativado ou se defina REAL_PATH de modo a invocar o interpretador perl.
O código C utilizado foi, então, o seguinte:
#define REAL_PATH "/home/godoy/teste.pl"
main(ac, av)
char **av;
{
execv(REAL_PATH, av);
}
Testes e resultados
Um primeiro teste deve ser realizado para que possamos verificar o resultado da execução do programa em C sem nenhuma condição especial, exceto que o usuário que seja seu proprietário (owner) seja o superusuário.
[godoy@wintermute ~]$ ls -l wrapper_teste -rwxrwxr-x 1 godoy godoy 4796 Nov 6 19:04 wrapper_teste [godoy@wintermute ~]$ sudo chown root wrapper_teste [godoy@wintermute ~]$ ls -l wrapper_teste -rwsrwsr-x 1 root godoy 4796 Nov 6 19:04 wrapper_teste [godoy@wintermute ~]$ ./wrapper_teste 550 [godoy@wintermute ~]$
O resultado foi o esperado, ou seja, nenhuma referência ao usuário root como o responsável pela execução do processo.
O próximo passo consiste em ativar o SUID bit no script:
[godoy@wintermute ~]$ sudo chmod +s wrapper_teste [godoy@wintermute ~]$ ls -l wrapper_teste -rwsrwsr-x 1 root godoy 4796 Nov 6 19:04 wrapper_teste [godoy@wintermute ~]$ ./wrapper_teste 0 [godoy@wintermute ~]$
O resultado, novamente, foi o esperado: o script foi executado pelo super usuário, com os acessos e restrições deste.
Considerações sobre segurança
A única coisa deve ser garantida é a segurança aos arquivos que serão executados (assim como deve ser garantida para scripts Perl que usavam os métodos do próprio Perl para obterem privilégios adicionais) já que quem os executará terá permissões de super usuário.
O fato do script ser executado como se o fosse pelo super usuário implica que se alguém substituir o script Perl, ele poderá executar qualquer coisa como se fosse o próprio root.
Mesmo com esta preocupação adicional, este método é bem mais seguro que o via suidperl.
Sobre este documento
Autor: Jorge Godoy
Data: 06 de novembro de 2002
Última atualização: 06 de novembro de 2002