Segurança de Servidores
WWW
Clarissa de Vasconcelos Martins
Fernanda Bezerra Cavalcanti Marques
Suzana de Abreu Accioly Canuto
I - Segurança na Web: uma preocupação geral
Quando se fala em segurança na Web, deve-se condiderar os problemas de segurança relacionados com o servidor Web, as redes locais e os usuários dos Web browsers. Dessa forma, as preocupações com segurança devem ser levadas em consideração pelo webmaster, pelo administrador da rede e pelo usuário final.
Do ponto de vista do Webmaster, os riscos são mais severos, uma vez que, ao instalar um servidor Web em um site, são abertas as janelas da empresa para o mundo (toda a Internet), tornando o site potencialmente vulnerável a ataques. Isso porque, a própria complexidade de uma servidor Web pode, muitas vezes, acarretar em bugas, que por sua vez podem levar a buracos na segurança do site. Além disso, a aqruitetura aberta destes tipos de servidores, permite sua extensão através de scripts CGI, que, uma vez mal escritos ou com permissão indevida, podem são uma das janelas preferidas dos invasores e destruidores de sites.
Do ponto de vista do administrador, é de extrema importância a bos configuração do servidor Web, uma vez que um servidor mal configurado pode abrir buracos na segurança de qualquer sistema protegido por firewalls.
Do ponto de vista do usuário, dois problemas devem ser considerados: apossibilidade de existirem applets ou controles Active X na página, que , ao serem executados causem probelmas na máquina e o fato de que todos os traços da navegação de um determinado usuário podem ser acompanhados por invasores que estudam o perfil dos usuário, seus gostos e costumes, muitas vezes para atacar futuramente fazendo-se passar pelo usuário.
Os ricos de segurança existentes podem ser classificados em três grupos:
Problemas de bug e configuração no servidor web que permite que usuários:
Roubem arquivos confidenciais
Executem comandos na máquina onde estáo servidor
Obtenham informações sobre a maquina servidora para atacar no futuro
Lancem ataques de negação de serviço, deixando a máquina
temporariamente inutilizável.
Riscos do Browser:
Conteúdo ativo, como falado anteriormente, que podem derrubar o browser.
Intercepção de pacotes enviados do cliente para o servidor e vice-versa.
Aspectos que tornam sistemas operacionais e servidores Web mais vulneráveis:
Deve-se também levar em consideração a vulnerabilidade do sistema operacional onde o servidor web irá rodar. De uma maneira geral, quanto mais poderoso e quanto mais flexível for o sistema operacional, mais vulnerável ele é. Os sistemas operacionais Unix, com seu grande número de servidores, serviços e interpretadores é potencialmente mais perigoso do que um sistema MS-Windows, uma vez que este possui menos funcionalidades a serem exploradas pelos hackers.
Em relação aos próprios servidores web também existem características que os tornam potencialmente mais vulneráveis a ataques. Também, de maneira geral, quanto mais funcionalidades o servidor oferecer, maiores são os riscos. Servidores que simplesmente fornecem as páginas estaticamente são provavelmente mais seguros do que aqueles que podem executar scripts CGI ou fornecer listagem de diretórios.
Algumas funcionalidades são particularmente perigosas e, caso não forem realmente necessárias, devem ser desabilitadas, para evitar problemas. São elas:
Listagem automática de diretórios:
Os hackers devem ter o menor acesso possível a qualquer informação sobre o site. Qualquer conhecimento por ele obtido pode ser utilizado para facilitar um ataque futuro. As listagens automáticas de diretórios oferecidas pelo CERN, NCSA, Netscape, Apache e outros são bastante convenientes, mas pode dar acesso ao hacker a informações sensíveis do site, como, por exemplo, arquivos de backup do Emacs contendo os codigos fonte dos scripts CGI, diretórios contendo arquivos temporários.
Seguir links simbólicos:
Alguns servidores permitem que a árvore de documentos seja extendida através de links simbólicos. Apesar de interessante, alguem pode acidentalmente, criar uma link para uma área sensível, como o /etc.
Usuários mantendo os seus próprios diretórios:
Para habilitar essa funcionalidade, é preciso muita confiança no usuário. Isto porque vários são os problemas de segurança que podem decorrer da liberadade do usuário. Alguns desses problemas são: publicação de informações sensíveis e disponibilização de scripts CGI com bugs.
Precauções gerais a serem tomadas:
Abaixo são listadas algumas das principais precauções para se conseguir manter um servidor Web seguro:
Ex: Cops (Unix)
Tiger (Unix)
Ksa (Windows NT)
NAT (Windows NT)
Ex: Tripwire (Unix)
Ex: Satan
ISS
SomarSoft (Windows NT)
Ex: Stalker e WebStalker
NetRanger
Gaunlet ForceField
II - Controlando o Acesso ao Web Server
Estratégias para Controle de Acesso
Dependendo do grau de segurança e do tipo de serviço que um servidor Web vai prover, existem algumas estratégias a serem utilizadas para garantir o controle de acesso a esse servidor. Entre essas técnicas que estao sendo usadas, as mais comumente utilizadas são:
URLs secretas
O meio mais fácil de restringir o acesso a certas informações e serviços é guardar os arquivos HTML e os scripts CGIs em uma localização escondida no servidor Web. O único trabalho a ser feito é informar a URL , apenas para pessoas ou organizaçoes, que realmente de confiança. Ex. Maria poderia informar a seguinte url http://www.di.ufpe.br/~maria/docs apenas para seus colegas de trabalho.
Assim só aqueles que forem informados pelo proprietario dos documentos é que, teoricamente, teriam acesso a eles. Porém na realidade o que ocorre é bem diferente, pois facilmente essas informações sobre a localização da URL se propaga, chegando em mãos que não eram desejadas.
Essa propagação pode ocorrer facilmente por transitividade (um contando para outro usuário). Uma outra forma dessa descoberta da URL é também feita pelas web "spider"- programas de busca, que navegam pela internet visitando os servidores web adicionando palavras chaves de cada página a sua base de dados central. O AltaVista e o Lycos são servidores de busca dos mais conhecidos, que executam essa tarefa. Dessa forma, uma vez que um desses programas localiza a pagina "secreta" e faz um link para essa página, e armazena essa informação na sua base de indexes, qualquer usuário da Internet e capaz de acessar .
Em geral, deve-se evitar o uso de URLs "secretas", se realmente deseja-se ter cuidado com a manutenção na natureza confidencial de certas páginas. Este é o meio menos eficiente de se controlar o acesso a um servidor Web.
Restrição baseada nos Hosts
Muitos servidores permitem a restrição de acesso a certos diretórios por determinadas máquinas, localizadas na Internet, identificadas através do seu número IP ou através seu nome com o uso de DNS.
Restringir o acesso para um dado endereço IP, ou para uma subrede, é uma tecnica relativamente simples, e funciona muito bem para organizações que desejam restringir o acesso apenas para pessoas da sua própria rede interna. Como por exemplo, restringindo o acesso para os enderecos da subrede 204.17.195, e assim se prevenir que pessoas de fora dessa subrede acessem as informações de alguns diretórios escolhidos. O problema neste caso, eh garantir que o IP, que foi liberado o acesso ao servidor, é realmente a máquina que se diz ser, ou seja, que não é nenhum hacker usando um número IP de outra máquina confiável..
Uma outra alternativa, eh restringir o acesso baseado no domínio DNS, podendo assim, por exemplo, configurar o servidor web para permitir livre acesso vindo de maquinas com o nome da forma *.companhia.com.br. Essa opção tem a vantagem, de que pode-se mudar o número IP, sem necessitar alterar o arquivo de configuração do servidor Web. Para garantir essa segurança, é necessário também, que se garanta, que o servidor de DNS também está protegido, caso contrário um hacker pode simplesmente adicionar o número da sua máquina no domínio DNS. Desse modo também, pode-se ter um DNS forjado, da mesma maneira que acontece com os Ips forjados, que foi citado acima.
Além dessas duas formas mencionadas, pode-se também controlar o acesso, baseado nos hosts, através do uso de firewalls, bloqueando todas as conexões http para um servidor Web, em particular, que pode apenas ser usado por algum membro de uma certa organização.
Controle Baseado na Identidade
Ter como base o uso de usernames é uma das mais eficientes técnicas de controle de acesso. Cada usuário, tem um username e uma password. O problema que é necessário ressaltar é que a password, as vezes, não é bem escolhida, pode ser compartilhada, esquecida, pode ser interceptada enquanto é transmitida do browser do cliente até o servido, entre outras. Porém várias técnicas de criptografia pdem ser utilizadas para tentar amenizar parte do problema. A opção do uso de chave publica é bastante usada pelas organizações como alternativa.
Uma das vantagens do controle feito baseado no usuário, sobre o controle baseado no host , é que um usuário autorizado pode acessar o sevidor web, de qualquer lugar na Internet. Dessa forma, um vendedor, por exemplo que esteja viajando pelo mundo pode simplesmente acessar o web site da sua empresa, passar seu nome e sua senha e buscar ou fornecer informações da sua empresa, independente da máquina que estaja utilizando no momento, no lugar de fazer uma ligação telefonica ccm a empresa, como era mais usual tempos atrás.
Implementando o Controle de Acesso - Blocos <Limit> -
Um dos modos mais comuns de se restringir o acesso as informações de um servidor Web, é protegendo-o através de username e password. Apesar de muitos sites terem diferentes meios de proteção baseada em password, uma das mais conmuns técnica é o uso do <LIMIT> nosarqivos de configuração.
Analisando o servidor web da NCSA, podemos ver o uso desse tag, podemos definir quais máquinas podem acessar o servidor web, e por quem essas máquinas pode ser acessadas.
O NCSA oferece dois locais onde se pode controlar o acesso as informações, que são as seguintes:
Em alguns casos pode-se considerar ser mais conviniente ter um arquivo de configuração por diretório. Facilitando assim a movimentação dos diretórios, sem precisar atualizar um arquivo de controle master. Além disso, também não é necessário, reinicializar o servidor, caso tenha-se feito uma modificação na lista de controle de acesso. Isso porque o servidor web, notará que existe um novo .htaccess e se comportará convinientemente.
Por outro lado, ter um arquivo de controle em cada diretório significa que existirão muitos mais arquivos que o servidor terá que checar para constatar se os diretórios estão protegidos ou não.
Para construir um bloco <Limit>, as seguintes palavras chaves são usadas:
order opcoes - determinando a ordem de que as permissões devem ser seguidas( "order deny, alow").
require group group1 group2 - especificando quais os grupos que teram acesso garantido.
No exemplo abaixo, podemos ver algumas linhas do arquivo access.conf da NCSA. Nessas linhas estamos restringindo o acesso a um diretório especificado pelo tag <Directory ...>, apenas para a máquina 204.17.195, apenas para os usuários joao e maria. A opção AuthType especifica o tipode autentificação usada pelo servidor. A maioria dos servidores apenas suportam a opção "basic". A opção de AuthUserFile indica o caminho para o arquivo de password httpd, arquivo auth, onde estão armazenada as passwords dos usários que terão o acessso liberado.
<Directory /usr/local/etc/httpd/htdocs/special>
AuthType Basic
AuthName The-T-Directory
AuthUserFile /etc/web/auth
<Limit Get Post>
order deny, allow
deny from all
allow from 204.17.195
require user joao maria
</Limit>
</Directory>
Criando Usuários e Passwords
Servidores Web baseados em Unix, usam arquivos de password e de grupos semelhantes aos arquivos usados pelo Unix, porém não é nada aconselhável usar o mesmo arquivo do Unix para o servidor Web, uma vez que o um hacker pode mais facilmente violar as restrições de acesso a um servidor Web, e assim ter o acesso liberado a todo o sistema Unix, o que seria extremamente perigoso.
Para a construção do arquivo de password do servidor Web, pode-se no caso de estar usando um servidor NCSA, usar um programa que vem acoplado ao servidor, chamado de ./htpasswd. Então pode-se executar a seguinte linha de comando :
# ./htpasswd -c /usr/local/etc/httpd/pw/auth maria
Feito isso, aparecerá o prompt para maria entrar com a senha e confirmá-la. Para uma possivel mudança de senha pelo usuário, existem alguns scripts CGI já construídos, que permitem essa mudança On-Line, um dos mais utilizados, que é compatível com servidores Apache, NCSA , CERN e Netscape Unix, está disponível no seguinte endereço: http://www.genome.wi.mit.edu/ftppub/software/WWW/passwd/
Gerenciador de Usuário Simples
Concluindo temos basicamente os seguintes passos a serem seguidos, para definição de um gerenciador de usuários simples :
III - CGIs e a Segurança dos Servidores Web
A World Wide Web talvez seja a grande responsável pela enorme popularidade da Internet. Informações de todos os tipos estão espalhadas em diversos lugares do mundo, mas para o usuário a impressão é de que toda a Informação está concentrada numa biblioteca de proporções gigantescas, acessíveis através do Browser.
A Web é praticamente uma unanimidade e já faz parte do cotidiano de um número de pessoas que cresce a taxas cada vez mais elevadas. O que talvez não tenha sido devidamente percebido é a importância da Common Gateway Interface (CGI) para toda esta popularidade da Web, e, conseqüentemente, da própria Internet.
CGIs dão mais dinamismo e funcionalidade à Web e servem com uma interface entre o Browser e o sistema da organização onde roda o servidor. Esta interface permite que os usuários visualizem no Browser informações adquiridas por outros programas que executem no sistema. Uma das grandes utilizações de CGI é disponibilizar na Web informações que podem estar em armazenadas em um banco de dados. Outro exemplo da aplicação de CGIs é na construção de ferramentas de busca, sem as quais a web seria mais ou menos equivalente a uma enciclopédia caótica, que contém tudo que se precisa saber, mas sem que o usuário tenha como achar o que precisa.
Infelizmente, como conseqüência de todo o poder que CGIs proporcionam, a segurança do servidor Web e da própria rede podem estar ameaçadas. Isto se deve ao fato de CGIs serem uma porta aberta para que hackers infiltrem-se no sistema.
Hackers podem usar CGIs para entrar no sistema de duas maneiras: uma é usar as informações que os CGIs disponibilizam (e isto pode ser feito mesmo que o programdor do script não tivesse esta intenção) para aprender sobre o sistema e assim descobrir formas de invadi-lo. A outra maneira é explorar a vulnerabilidade ou possíveis bugs dos scripts e atacar o sistema através deles.
Para limitar o prejuízo que pode ocorrer em tais ataques, duas técnicas podem ser empregadas:
Devido a estas ameaças, verificamos que programas como interpretadores, shells e ferramentas de scripting não devem nunca estar instaladas em diretório como cgi-bin que permita sua invocação a partir do web server, pois eles podem ser utilizados em um ataque de forma a permitir que o invasor execute o que ele quiser no servidor. Assustadoramente, muitos sistemas baseados no Windows estão configurados desta forma, pois é mais fácil de configurar scripts em Perl.
O que piora o problema é o fato de que os admistradores não terem o hábito de apagar arquivos do diretório cgi-bin, de forma que mesmo quando se descobre que um script tem um furo de segurança eles permanecem no diretório durante meses, apenas esperando um ataque.
Como as conseqüências podem ser imensas, existem diversas práticas perigosas que devem ser evitadas e algumas destas práticas serão descritas e exemplificadas abaixo.
Scripts que façam chamadas ao sistema operacional tornam-se mais perigosos, pois hackers podem formatar a entrada e executar no sistema comandos diferentes dos desejados pelo programador. Um exemplo seria um script que poderia ser disparado de uma página para visualizar a saída do finger. O script se fosse escrito em Perl, poderia conter a seguinte linha de código:
print `/usr/bin/finger $entrada`;
Onde entrada é uma variável que o usuário digitou em um form e que foi passada como argumento para o script. O uso de um string entre crases faz com que o string seja passado para a shell. Se um usuário mandar como entrada um simples e inocente endereço eletrônico, o seguinte comando será passado para a shell:
/usr/bin/finger saac@di/ufpe/br
E o resultado será o esperado. Mas, um hacker que tenha conhecimento de que sua entrada será passada para shell poderia entrar com a seguinte string: "saac@di.ufpe.br & /bin/ls -l"
Então, o comando passado para a shell seria o seguinte:
/usr/bin/finger saac@di/ufpe/br & /bin/ls -l
A presença do caracter ‘&’ após o endereço eletrônico fará com que o finger seja rodado em background e o processo que terá sua saída visualizada no browser será o ls. Desta forma, o programador permitiu que um hacker visualizasse informações do seu sistema devido à falta de checagem dos parâmetro de entrada.
Após a observação do exemplo acima, chegamos a regra número 1 de programação de CGIs: Nunca passe para a shell entradas do usuário sem previamente verificar o conteúdo desta entrada. Um script que filtrasse caracteres perigosos como ‘&’ e ‘|’ não permitiria (ou dificultaria) que seu programa fosse explorado de forma a produzir efeitos colaterais. Uma política ainda melhor de verificação da entrada do usuário consiste em só deixar passar para shell caracteres reconhecidos como válidos (no caso do finger estes caracteres seriam ‘@’ e ‘-‘) em vez de filtrar os caracterizados como perigosos. Desta forma, atinge-se um nível de segurança maior sem o perigo de ter esquecido de filtrar algum caractere que pode ser potencialmente perigoso mas que o programador não tenha despertado para o fato.
Regras Genéricas de Codificação
Muitas outras regras além da citada no parágrafo anterior foram identificadas e elas devem ser aplicadas sempre que possível.
Esta recomendação parece banal, visto que os princípios da Engenharia de Software recomendem esta prática em todo e qualquer sistema. Mas esta regra deve ser realmente levada a sério e o programador deve ter em mente que um pequeno descuido pode significar em prejuízo para usuários de todo o sistema. O ambiente e suas permissões devem ser observados, os formatos de entrada e saída devem ser bem estudados, bem como os possíveis erros.
Muito cuidado na hora de abrir e escrever em arquivos, os parâmetros das funções devem ser checados antes de serem passados para função de forma a verificar se seus valores são os que deveriam ser.
A técnica de especificação POSIX, que é seguida por linguagens como C e Perl, determina que toda chamada ao sistema retorn um código indicando o status da chamada. Desta forma, na ocorrência de um erro, pode-se saber que aconteceu e porque. Esta prática pode ser de grande ajuda na debugação de um script
É sempre melhor ter logs demais que de menos. Um arquivo de log exclusivo facilita a tarefa de identificar problemas. Algumas informações relevantes para log são:
Um dos truques preferidos de hackers é mudar a variável de ambiente PATH de forma a apontar para um diretório que contém programas mal-intencionados.
Normalmente, terceiros estão mais suscetíveis a achar falhas no código que a pessoa que escreveu
Esta regra é para aqueles que acreditam que um programa já testado e debugado por outras pessoas anteriormente é menos vulnerável. Deve-se ter cuidado, obviamente, para adquirir este códigos de fonte segura para não colocar no sisstema cavalos-de tróia.
O ideal é que o script rode como nobody, mas algumas aplicações requerem maiores privilégios. Nestes casos, evitar ao máximo seta SUID de root, pois em caso de furo, o estrago pode ter proporções gigantescas.
Além destas regras gerais existem algumas regras que são peculiares a determinadas lingugens de programação. Citamos abaixo algumas regras para as duas lingugens mais utilizadas na programação de scriptss CGI.
Regras para Perl
"Tainting" é uma facilidade de perl para ajudar no trabalho do usuário de checagem das entradas dos usuários. Variáveis entradas pelo usuário são marcadas como Taint e não podem ser usadas como parâmetro para abrir arquivos ou para realizar chamadas ao sistema. Variáveis "untainted"so podem ser obtidas de variáaveis tatintes após um casamento de padrão.
Esta prática vai evitar que o programador tenha surpresas ao descobrir que o ls que ele executou não estava fazendo exatamente o que devia...
Bibliotecas modificadas podem mudar o comportamento do seu programa sem o seu conhecimento.
Regras para C
A declaração char buffer[1024] pode ser perigosa pois um hacker pode arrumar uma maneira de estourar este buffer e derrubar seu prograna.
Evitar Preferir
gets( ) fget( )
strcpy( ) strncpy( )
strcat( ) strncat( )
Estar rotinas abrem e deletam o arquivo além de não pemitir que o arquivo seja lido por nenhum outro processo em execução.
Outras Dicas
Nunca confie que as entradas do seu script estão vindo do form que você mesmo escreveu. Os scripts CGI podem ser disparados de qualquer canto desde que se forneça sua URL. Hackers podem forjar uma entrada e passar parâmetros completamente diferentes daqueles descritos pelo form. Se estas entradas de fom não forem devidamente inspeciondas um efeito colateral como ilustrado anteriormente no exemplo do finger, possa ser explorado.