|
|
 |
| Arquitetura de Software |
 |
|
| |
|
| Construindo e configurando sites mais seguros |
Autores:
Timothy Bollefer, Girish Chander, Jesper Johansson, Mike Kass, Erik Olson - Microsoft Corporation.
Scott Stanfield, James Walters - Vertigo Software, Inc. |
Boas práticas de segurança para Windows 2000 Advanced Server, Internet Information Services 5.0, SQL Server 2000 e .NET Framework
Dezembro de 2002
Resumo: Um site criado por engenheiros da Microsoft usando Microsoft .NET Framework, Microsoft Windows 2000 Advanced Server, Internet Information Services 5.0 e Microsoft SQL Server 2000 resistiu com sucesso a mais de 82.500 tentativas de ataque e terminou a competição eWeek OpenHack 4 incólume. Este artigo explica como a solução foi construída e configurada, e descreve boas práticas para que desenvolvedores de software e administradores de sistemas possam proteger suas soluções.
Conteúdo
Introdução
Em outubro último, o eWeek Labs lançou sua 4ª competição anual de segurança on-line, a chamada OpenHack. A competição deste ano, a terceira com participação da Microsoft®, visou testar a segurança corporativa expondo sistemas aos rigores do mundo real da web. Tanto a Microsoft quanto a Oracle receberam da eWeek uma amostra de aplicação web e foram solicitadas a redesenvolvê-la usando suas respectivas tecnologias. Indivíduos espalhados pelos Estados Unidos foram, então, convidados a tentar comprometer a segurança dos sites resultantes em troca de prêmios em dinheiro. As brechas aceitáveis consistiam em ataques cruzados com scripts, exposição de código fonte de página web dinâmica, desfiguração de página web, postagem de comandos SQL mal intencionados nas bases de dados e roubo de dados de cartões de crédito das bases de dados utilizadas.
A Microsoft desenvolveu sua aplicação usando o Microsoft® .NET Framework, um componente integrante do Windows que suporta construção e execução de aplicações e serviços web XML de última geração. A aplicação foi hospedada em Microsoft® Internet Information Services (IIS) 5.0 e a base de dados usada foi Microsoft® SQL ServerTM 2000. Todos os servidores rodaram no sistema operacional Microsoft® Windows® 2000 Advanced Server. (Deve-se notar que o Microsoft® Windows Server 2003 com IIS 6.0 teria sido usado se este tivesse sido lançado a tempo para a competição. No Windows Server 2003, diversos passos tomados para a "proteção" do sistema operacional e do servidor web já existem por padrão.)
Os resultados da competição podem ser encontrados em http://www.eweek.com/category2/1,3960,600431,00.asp. No total, a solução Microsoft resistiu a mais de 82.500 ataques. A Microsoft emergiu do OpenHack 4 incólume, como aconteceu em ocasiões anteriores, na primeira e segunda competição OpenHack. Este artigo discute cada uma das tecnologias usadas para explicar como a solução foi construída e configurada e como os desenvolvedores e administradores que protegem suas soluções podem aplicar essas boas práticas.
Aplicação web
A aplicação propriamente dita foi modelada com base no site eWeek eXcellence Awards, em que indivíduos podem indicar os produtos e serviços de suas empresas para um prêmio. Usando o site, pode-se definir uma conta para indicar um produto ou serviço para julgamento, submetendo um número de cartão de crédito para pagar a inscrição e coletar informações sobre o prêmio. A Microsoft construiu sua solução usando o .NET Framework, um componente integrante do Windows para a criação e execução de aplicações. A maior parte do desenvolvimento centrou-se em bibliotecas de classe de criptografia, ADO.NET e ASP.NET do Framework, que provêm, respectivamente, criptografia, descriptografia e garantia da integridade dos dados, acesso e manipulação de dados e funcionalidade para construir aplicações baseadas na web.
Autenticação de formulários
As classes Microsoft® ASP.NET fornecem diversas opções para a autenticação de usuários (i.e. usando algumas credenciais - nome de usuário e senha, por exemplo - para confirmar a identidade de determinado usuário). Essas opções incluem autenticação integrada do Windows, basic, digest, Microsoft® .NET Passport, certificados de cliente, etc. Por solicitação da eWeek, autenticação baseada em formulário ou personalizada foi selecionada para a solução OpenHack.
Quando um usuário faz login através de autenticação de formulário, é criado um cookie criptografado usado para monitorar o usuário através do site. (Tecnicamente, um cookie é uma seqüência de texto gerada por um site incluído na memória do navegador do usuário para fins de identificação desse usuário à medida que ele navega através do site.)
Se o usuário não tiver feito login e solicitar uma página protegida, ele será direcionado à página de login. Tudo isso pode ser configurado simplesmente usando o arquivo Web.config baseado em XML do aplicativo, que é gerado automaticamente pelo Microsoft® Visual Studio® .NET - um ambiente de desenvolvimento integrado para a criação de aplicações baseadas no .NET Framework - para armazenar configurações para aplicações web ASP.NET.
Na pasta raiz de nossa aplicação, adicionamos as linhas abaixo à seção do arquivo Web.config para solicitar autenticação baseada em formulários e especificar a localização da página de login.
<authentication mode="Forms">
<forms loginUrl="Login.aspx" name="OPSAMPLEAPP"/>
</authentication>
|
Este arquivo de configuração de alto nível aplicou-se a todas as páginas da aplicação. Criamos, então, um subdiretório com o segundo arquivo Web.config. Esse arquivo aplicou-se apenas a umas poucas páginas selecionadas da aplicação e destinava-se a impedir usuários não autenticados (ou seja, anônimos) de acessá-los. Esse segundo arquivo .config herdou as informações de autenticação do arquivo .config de alto nível.
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.web>
<authorization>
<deny users="?" />
</authorization>
</system.web>
</configuration>
|
Usando os dois arquivos .config desta forma, os usuários não autenticados só podiam acessar a página principal e algumas outras páginas, enquanto os usuários autenticados receberam acesso adicional às páginas que exigiam uma conta de usuário no site.
A própria página de login continha campos que aceitavam nome de usuário e senha do usuário e enviavam-nos ao servidor web via SSL (Secure Sockets Layer), que impedia que alguém interceptasse as credencias quando estas passavam pela rede. Quando um usuário criava uma nova conta, essa nova senha era criptografada com o algoritmo "Triple DES", conforme explicado na seção Armazenando informações secretas, e era armazenada na base de dados juntamente com o nome de usuário. Nos logins futuros, a senha enviada da página de login seria criptografada com o Triple DES pela aplicação web sendo, então, comparada com a senha criptografada armazenada na base de dados. Se as senhas coincidissem, a aplicação web geraria um cookie criptografado contendo o nome de usuário e o nome completo do usuário que estava usando a classe System.Web.Security.FormsAuthentication da biblioteca ASP.NET. O cookie seria transmitido ao usuário e armazenado no navegador até que ocorresse a temporização. Seria, então, enviado junto com solicitações futuras daquele usuário ao site. Todas as transmissões envolvendo o cookie eram conduzidas via SSL para impedir ataques "reprisados", nos quais um atacante intercepta um cookie fora da rede e o usa para fazer-se passar pelo usuário. O SSL é altamente recomendado em qualquer situação em que informações ou credenciais confidenciais que poderiam ser usadas para acessar informações confidenciais estão sendo enviadas através de uma rede pública.
Validação de entrada
A OpenHack implementou diferentes tipos de validação em diferentes níveis dentro da aplicação para assegurar que as entradas vindas externamente ao código (ou seja, entrada do usuário) não pudessem ser usadas para alterar o comportamento da nossa aplicação. A validação de entrada é uma das principais boas práticas de segurança, e ajuda a proteger contra saturação do buffer, ataques cruzados via scripts e outras tentativas potenciais de executar códigos mal-intencionados dentro do contexto da aplicação. Prover várias camadas de proteção, como fizemos aqui, é outra importante boa prática conhecida como "defesa em profundidade". É sempre essencial planejar para o pior cenário, como fizemos, e supor que há possibilidade de uma ou mais camadas da solução ficarem comprometidas.
Nossa primeira linha de defesa eram os controles de validação providos por ASP.NET, especificamente as classes RegularExpressionValidator e RequiredFieldValidator, que garantiam que todas as entradas necessárias estivessem presentes e fossem dados válidos para os fins específicos. Permitimos apenas caracteres que eram necessários para oferecer a experiência desejada ao usuário, o que, no nosso caso, era um conjunto bastante estreito. Por exemplo, alguns campos permitiam apenas "[ ',\.0-9a-zA-Z_]*", equivalência aos espaços, apóstrofos, vírgulas, pontos, letras e números. Outros caracteres, que poderiam ser usados para enviar scripts mal intencionados ao site, não eram permitidos.
Além das caixas de texto, nossa aplicação aceitava algumas entradas através de uma seqüência de caracteres de consulta, a parte de um URL dinâmico que contém parâmetros usados para gerar uma página. Esses dados eram validados com expressões comuns usando a funcionalidade fornecida pela classe System.Text.RegularExpressions.Regex, conforme mostrado abaixo:
Regex isNumber = new Regex("^[0-9]+$");
if(isNumber.Match(inputData) ) {
// use it
}
else {
// discard it
}
|
Expressões comuns são conjuntos de símbolos e elementos sintáticos usados para combinar padrões de texto. No caso da aplicação OpenHack, eram usadas para assegurar que o contexto da seqüência de consulta era apropriado e não mal intencionado.
Todo o acesso aos dados na aplicação era feito através de stored procedures parametrizados, desenvolvidos na linguagem T-SQL e que, por definição, vivem dentro da própria base de dados. Limitar a interação com a base de dados a stored procedures é sempre uma boa prática. Na falta de stored procedures, as consultas SQL teriam de ser dinamicamente construídas pela aplicação web. Se a camada web ficasse comprometida, um atacante poderia, então, injetar comandos mal intencionados na consulta da base de dados para recuperar, alterar ou excluir dados armazenados na base de dados. Com stored procedures, a aplicação web é limitada, nessa interação com a base de dados, a alguns parâmetros fortemente tipados específicos que pode enviar via stored procedures. Sempre que um desenvolvedor invoca um stored procedure usando o .NET Framework, os parâmetros enviados àquele stored procedure são verificados para assegurar que sejam dos tipos (isto é, número inteiro, seqüência de 8 caracteres, etc.) esperados pelo stored procedure. Trata-se de uma outra camada de proteção além da validação da camada web, assegurando que todos os dados de entrada tenham o formato apropriado e não possam ser percebidos como uma declaração SQL acionável independentemente.
Antes que qualquer dado seja retornado ao usuário, ele é codificado em HTML. Isso é feito simplesmente usando o método HtmlEncode da classe System.Web.HttpServerUtility, conforme mostrado abaixo:
SomeLabel.Text = Server.HtmlEncode(username);
|
A codificação em HTML ajuda a impedir ataques cruzados com scripts. No caso de um atacante vir a comprometer a base de dados, ele poderia incluir um script nos registros, que seria retornado ao usuário e executado no navegador. Com a codificação em HTML, a maioria dos comandos do script são traduzidos automaticamente na forma de texto inofensivo.
Armazenando informações secretas
É essencial armazenar informações secretas - como a seqüência de conexão à base de dados que fornece informações de login à base de dados - de forma segura para impedir que atacantes acessem e usem essas informações secretas para ler e manipular os dados e reconfigurar O valor das seqüências de conexão para os atacantes foi grandemente reduzido nesta solução devido ao fato de usarmos a autenticação integrada do Windows para acessar a base de dados; a seqüência continha somente o local do servidor e o nome da base de dados ao invés de credenciais especificas, como senha.
Por padrão, os assistentes de conexão a bases de dados do Visual Studio .NET armazenam a seqüência de conexão com um valor de propriedade no arquivo "com código por trás" (code-behind) - o arquivo que contém a lógica central da aplicação e não o arquivo que fornece a definição da interface de usuário.
Dessa maneira, oferece acesso conveniente à seqüência para os desenvolvedores. Porém, se um atacante conseguir fazer login no próprio computador que contém o código fonte e o arquivo .config, a seqüência de conexão poderá ser lida e usada para acessar a base de dados para fins mal intencionados.
Em ambientes de produção, sempre recomendamos proteger a seqüência de conexão e quaisquer outras credenciais que sejam necessárias. Um dos enfoques da proteção de credenciais é aquele que escolhemos no OpenHack 4: criptografar a seqüência de conexão, armazená-la no Registry e usar as listas de controle de acesso (ACLs, Access Control Lists) para assegurar que apenas os administradores e o processo de trabalho ASPNET (definido na seção IIS) tenham acesso à chave do registro.
Criptografamos a seqüência de conexão à base de dados usando as funções da API de proteção de dados (DPAPI) CryptProtectData e CryptUnprotectData do Windows 2000/XP, que nos provêem a capacidade de criptografar informações secretas sem precisar gerenciar (nem armazenar) diretamente as chaves necessárias para acessar essas informações secretas.
Embora o DPAPI seja excelente para criptografar dados específicos do usuário ou do equipamento, é menos eficaz como forma de criptografar informações armazenadas em uma base de dados compartilhada, como números de cartões de crédito ou senhas. Isso se dá porque as funções do DPAPI criam e armazenam internamente chaves criptografadas baseadas nas informações do usuário e/ou do computador local. No cenário de web farms, os servidores web teriam, portanto, suas próprias chaves de criptografia, impedindo-os de serem capazes de acessar esses mesmos dados criptografados.
Portanto, para demonstrar as práticas que seriam usadas em um cenário de web farm, geramos um vetor de inicialização e uma chave de criptografia Triple DES aleatória. Essa funcionalidade foi provida usando a classe TripleDES das classes System.Security.Cryptography do .NET Framework. As chaves foram usadas para criptografar simetricamente informações sobre cartões de crédito e senhas que estavam armazenadas na base de dados. Para armazenar informações de cartão de crédito, um primeiro bloco aleatório fortemente criptografado foi escolhido para diferenciar a solução.
Depois de fazer uma cópia de backup das chaves, criptografamos as próprias chaves usando a DPAPI e as armazenamos no Registry, usando novamente as ACLs para limitar o acesso aos administradores e ao processo de trabalho ASPNET. A criptografia das chaves assegura que, se um atacante conseguir realmente localizar e acessar os dados, não poderá descriptografá-los sem primeiro descriptografar as chaves. Este é outro bom exemplo da "defesa em profundidade".
Internet Information Services (IIS) 5.0
Fizemos diversas mudanças moderadas no servidor web Internet Information Services (IIS) 5.0, incluído no Windows 2000 Advanced Server, para ajudar a impedir ataques dirigidos ao próprio servidor web. Para começar, instalamos todas as correções de segurança públicas listadas no site TechNet para assegurar os mais recentes aprimoramentos. A instalação dos mais recentes Service Packs e correções é uma prática de segurança essencial quando se executa qualquer software.
Em seguida, mudamos o local padrão do site em disco do local padrão em c:\inetpub\ para outro volume. Assim, se o sistema ficasse comprometido de alguma forma, o atacante teria dificuldade de navegar na árvore de diretórios sem vê-la - o atacante não poderia simplesmente acessar a unidade C digitando ..\ como descrição do local.
Em seguida, executamos a ferramenta IIS Lockdown usando o modelo incluído para um servidor web estático. Isso removeu todos os demais tipos de conteúdo dinâmico não usados nessa aplicação. É sempre uma boa prática reduzir desta maneira a área de superfície exposta a um atacante potencial. A ferramenta IIS Lockdown está disponível gratuitamente. Trata-se de um recurso muito eficaz que deve ser usado por todos os administradores que usam IIS.
Neste ponto, instalamos o .NET Framework Redistributable, exigido para executar aplicações do .NET Framework, o .NET Framework Service Pack 2, o mais recente hotfix do .NET Framework e o MDAC 2.7, um componente necessário para o .NET Framework.
Neste cenário, nossa aplicação só usou arquivos dinâmicos com a extensão .aspx e uns poucos tipos de conteúdo estático para folhas de estilo e imagens. Como não precisávamos dos outros mapeamentos de aplicação do IIS instalados pelo .NET Framework, revinculamos essas extensões à extensão 404.dll incluída na ferramenta IIS Lockdown. Novamente, isso foi feito para reduzir a área de superfície exposta da solução.
A aplicação usou a conta de serviço local padrão de baixo privilégio (a conta ASPNET) para executar o código ASP.NET. O princípio do "menor privilégio" é importante para todos os administradores - nunca dê a uma conta mais privilégios do que absolutamente necessário. Esta proteção da solução é análoga à redução da área de superfície exposta.
(A conta ASPNET é criada como uma conta local depois da instalação do .NET Framework Redistributable e pertence apenas ao grupo "Usuários" daquele computador. Tem, portanto, todos os privilégios associados ao grupo "Usuários" e pode interagir com qualquer recurso cujo acesso tenha sido concedido ao grupo. Além disso, recebe, por padrão, permissões específicas de acesso pleno ao diretório Temporary ASP.NET Files e a %windir%\temp, bem como uma permissão de leitura ao diretório de instalação do Framework.)
Incluímos essa conta ASPNET no "grupo de aplicação web" local criado pela ferramenta IIS Lockdown para impedir que o processo rodasse no caso de invasão executáveis de linha de comando não autorizados.
Modificamos, então, as permissões para esse grupo e permitimos aos usuários do grupo executar o conversor de recursos (Csc.exe and Cvtres.exe) e o compilador C# do .NET Framework requeridos pela aplicação.
A ferramenta IIS Lockdown instalou o URLScan 2.5, um filtro ISAPI que monitora e filtra todas as solicitações de entrada do servidor web IIS baseado em regras como comprimento da seqüência de consulta e conjuntos de caracteres. Configuramos o URLScan para permitir apenas o conjunto de extensões usadas na aplicação e bloqueamos, assim, solicitações longas. Trata-se de outro exemplo de defesa em profundidade - uma camada extra de proteção contra tentativas de inserção de códigos mal intencionados via entrada do usuário. O URLScan, como também a ferramenta IIS Lockdown, está disponível gratuitamente no site TechNet. Como a ferramenta IIS Lockdown mencionada antes, o URLScan é um recurso excelente e deve ser usado por todos os administradores de IIS.
Definimos as permissões apropriadas para os diretórios de conteúdo web, o que concedeu ao processo ASP.NET acesso de leitura aos arquivos e conteúdo e a usuários anônimos o apropriado acesso somente leitura ao conteúdo servido.
Restringimos o acesso aos diretórios de logs do IIS e URLScan à conta Sistema e aos membros do grupo Administradores. A restrição do acesso aos arquivos log é sempre uma boa idéia, dificultando aos atacantes alterá-los para cobrir suas pistas e esconder qualquer informação potencialmente útil sobre uma vulnerabilidade explorada.
Sistema operacional Windows 2000 Advanced Server
Todos os servidores usados na competição executavam o sistema operacional Windows 2000 Advanced Server com Service Pack 3, que era o último Service Pack disponível na época. Todas as correções de segurança lançadas desde o Service Pack 3 e no site TechNet foram instaladas. Novamente, a instalação das últimas correções de segurança é a boa prática mais crítica para os administradores de sistema.
Uma vez instaladas essas atualizações, várias alterações de configuração foram feitas para melhorar ainda mais o nível de integridade do sistema. Primeiro, todos os serviços desnecessários do sistema operacional foram desabilitados. Esta é, também, sempre uma boa prática. Desativando esses serviços, pudemos liberar recursos do sistema e reduzir a área de superfície exposta a ataques. Os serviços específicos que podem ser desabilitados irão variar dependendo das necessidades de cada solução individual. Messenger, Alerter e ClipBook são alguns exemplos de serviços desabilitados.
Recomendamos a leitura do Windows 2000 Server Resource Kit para ajudar a determinar os serviços dos quais você não necessita. Faça, em seguida, testes adequados para garantir que sua aplicação possa funcionar perfeitamente sem eles. Finalmente, desative esses serviços mudando seu status, na inicialização, para desabilitado.
Em nossa aplicação, também usamos o Editor do Registry (Regedit.exe) para mudar quatro configurações do Registry e reforçar ainda mais a segurança. Recomendamos todas estas boas práticas, desde que não se exija a desabilitação da funcionalidade.
- Create Registry Key: nolmhash
(É importante notar que esta é uma chave no Windows 2000 e um valor no Windows XP e no Windows Server 2003.)
- Local: HKLM\Software\CurrentControlSet\Control\LSA
- Finalidade: Impede que o sistema operacional armazene senhas do usuário no formato de hash de LM. Esse formato existe para ser usado apenas com clientes Windows 3.11 que não suportam NTLM nem Kerberos. O risco da criação e retenção desse hash de LM é que, se um atacante conseguisse descriptografar as senhas armazenadas dessa forma, poderia reutilizar essas senhas em outros computadores da rede.
- Create Registry Value: NoDefaultExempt
- Local: HKLM\System\CurrentControlSet\Services\IPSEC
- Finalidade: Por padrão, o IPSec permite o tráfego de entrada com uma porta fonte de 88 para consultar o serviço IPSec em busca de informações sobre conexão com o computador, independentemente das diretivas do IPSec que você estabelece. Definindo esse valor, não se permite comunicação entre portas, exceto como permitido pelos filtros do IPSec que definimos, como descreve a seção Diretivas do IPSec.
- Create Registry Value: DisableIPSourceRouting
- Local: HKLM\System\CurrentControlSet\Services\Tcpip\Parameters
- Finalidade: Impede os pacotes de TCP de determinar explicitamente a rota até o destino final, exigindo que o servidor determine a melhor rota. Esta é uma camada de proteção contra ataques convergentes, nos quais o atacante roteia pacotes através de seus servidores que interceptam o conteúdo à medida que atravessam esses locais.
- Create Registry Value: SynAttackProtect
- Local: HKLM\Software\CurrentControlSet\Services\Tcpip\Parameters
- Finalidade: Esta chave protege o sistema operacional de determinados ataques de sobrecarga de sincronização limitando os recursos alocados às solicitações de entrada. Ou seja, isso ajuda a bloquear as tentativas de usar solicitações de sincronização entre um cliente e um servidor para ataques de negação de serviço.
Além disso, embora não diretamente relacionado a prevenção de um ataque, habilitamos diversos logs de auditoria para cobrir eventos de login e logoff, gerenciamento de contas, alterações de diretivas e eventos do sistema. Isso nos ajudou a monitorar melhor os servidores durante a competição.
Diretivas do IPSec (IP Security Standards)
Começando com o Windows 2000, a Microsoft ofereceu suporte para gerenciamento de autenticação e criptografia do tráfego de IP (protocolo Internet) usando o IPSec (IP Security Standards), uma extensão do protocolo IPv4. A Figura 1 abaixo mostra a diretiva padrão para a caixa de diálogo Server (Request Security). Criamos uma diretiva especificamente para a competição.
Figura 1. Caixa de diálogo Server (Request Security)
As regras do IPSec foram configuradas usando o snap-in Local Security Settings do MMS (Microsoft Management Console) - acima. Essas diretivas tiveram papel importante no reforço e na segurança da comunicação permitida entre os servidores do OpenHack. Essas regras nos permitiram implementar a boa prática do menor privilégio por meio de:
- Exigir que todo o tráfego necessário para executar e administrar a aplicação seja explicitamente e exclusivamente especificado na diretiva de IPSec de cada sistema.
- Exigir que as comunicações entre sistemas sejam autenticadas usando certificados.
- Exigir que as comunicações para fins administrativos seja autenticadas com certificados e criptografadas.
- Negação de todo o tráfego não expressamente permitido para a aplicação ou administração do sistema, incluindo tráfego IP e ICMP (a regra de "negação padrão").
As regras de IPSec têm três componentes principais: o filtro que identifica o tráfego a ser manipulado pelo IPSec, a ação a ser realizada quando esse tráfego for encontrado por um filtro e o mecanismo de autenticação usado para estabelecer uma associação de segurança. Se dois sistemas que tentam se comunicar não têm regras que identifiquem o tráfego nem um mecanismo de autenticação comum entre eles, não podem estabelecer uma conexão.
O primeiro passo em direção ao bloqueio da solução com IPSec era entender plenamente os caminhos de comunicação entre os diferentes sistemas de forma que filtros IPSec pudessem ser construídos. O servidor web tinha de poder se comunicar com a base de dados SQL Server, o servidor de acesso remoto tinha de permitir aos administradores usar uma rede virtual privada (VPN) para acessar o segmento de gerenciamento da rede; o servidor de gerenciamento tinha de conceder aos clientes da VPN a capacidade de criar sessões de cliente do Windows 2000 Terminal Services - que permitem o acesso a aplicações executadas na área de trabalho de um computador remoto - além de acessar e copiar arquivos para compartilhamentos no servidor de gerenciamento; todos os sistemas tinham de permitir ao servidor de gerenciamento gerar uma sessão administrativa do Terminal Services para sua interface privada; e, finalmente, todos os sistemas tinham de ter acesso a compartilhamentos de arquivos específicos no sistema de gerenciamento. Uma vez mapeada a conectividade necessária entre os sistemas por portas, criamos filtros de IPSec em cada sistema específico.
Em seguida, precisamos determinar como o tráfego seria manipulado conforme era identificado pelos filtros do sistema. Para o OpenHack 4, definimos quatro ações possíveis a tomar (conhecidas como "ações de filtragem"):
- Bloquear o tráfego.
- Permitir o tráfego.
- "Autenticar e assinar" - autenticar a origem do tráfego usando certificados e estabelecer uma associação de segurança usando assinatura de pacotes.
- "Autenticar, assinar e criptografar" - autenticar a origem do tráfego usando certificados e estabelecer uma associação de segurança usando criptografia e assinatura de pacotes.
A regra de bloqueio simplesmente solta o pacote. Essa regra funcionava como a regra de "negação padrão", que significa "Se não permitirmos expressamente o tráfego, não se deve permiti-lo". A regra de permissão permite que tráfego chegue independentemente da origem. Foi usada para permitir o acesso público à aplicação web.
Embora a autenticação do tráfego com certificados nos exigisse a geração e distribuição de certificados IPSec de uma autoridade emissora de certificados (CA, Certificate Authority) comum, essa prática acrescentou grande integridade à capacidade de o sistema comunicar-se de forma segura. É importante notar que usamos um CA autônomo. Depois de concedidos todos os certificados, o CA foi removido da rede. Se o CA não for mais necessário em tempo de produção, é aconselhável seguir este enfoque - trata-se de outra excelente maneira de reduzir a área de superfície da solução.
Usando certificados de IPSec, conseguimos garantir a identidade dos sistemas de origem e destino, incluindo administradores remotos acessando o servidor de acesso remoto. Configurando as diretivas de modo que todas as transmissões fossem assinadas usando um hash SHA1, garantimos que os pacotes não pudessem ser modificados com sucesso por atacantes quanto em trânsito entre sistemas back-end.
Criptografamos as comunicações do servidor de gerenciamento usando o algoritmo de criptografia MDS. Desta forma, mesmo que os atacantes fossem capazes de romper a segurança em um dos sistemas frente à Internet, não poderiam ter acesso ao tráfego da rede privada. Isso permitiu aos administradores conectar-se de forma segura ao site ao vivo para executar atualizações da aplicação.
O IPSec processa regras de forma que as regras mais específicas tenham a maior precedência. Portanto, cada sistema era iniciado com as duas regras a seguir:
- Bloquear todo o tráfego IP.
- Bloquear todo o tráfego ICMP.
Construímos, então, as regras específicas a cada sistema. As comunicações entre o servidor web e o servidor de base de dados receberam uma ação de filtragem "Autenticar e Assinar", comunicações com o servidor de gerenciamento receberam uma ação de filtragem "Autenticar, Assinar e Criptografar" e o acesso público ao site foi definido para permitir acesso.
A conectividade lógica de nossa aplicação no OpenHack 4 conforme estabelecida com IPSec é mostrada abaixo.
Figura 2. Conectividade lógica da aplicação usando IPSec
Monitoração e gerenciamento remoto
Parte dos requisitos para o OpenHack 4 era ser capaz de atualizar a aplicação durante a vigência da competição. Conseguimos isso usando o L2TP (Layer 2 Tunneling Protocol) para criar nossos compartilhamentos de arquivos restritos, Terminal Services e VPN.
Figura 3. L2TP usado para criar VPN (Terminal Services)
Primeiro, o L2TP requer certificados IPSec para estabelecer uma conexão. Configuramos diversos computadores de administração remota com certificados apropriados. Criamos, então, contas habilitadas por acesso remoto para os administradores remotos.
Para que um administrador estabeleça uma conexão VPN, deve ter tanto o certificado IPSec instalado no sistema quanto as credenciais de conta de acesso remoto. Em suma, um certificado IPSec incorpora uma porção privada do certificado no armazenamento de certificados do computador local em uma forma não-exportável. Isso significa que o certificado não pode ser portável e usado em outro sistema. De fato, pudemos assegurar que os administradores pudessem usar apenas a conta de cliente VPN a partir de estações de trabalho de administração remota permitidas, minimizando o acesso administrativo à solução.
Uma vez autenticada a sessão L2TP, a estação de trabalho de administração recebia um endereço IP na rede de gerenciamento. Depois de estabelecer um túnel VPN para a rede de gerenciamento, os administradores podiam abrir uma sessão do Terminal Services para o servidor de gerenciamento, OHTS, além de usar os compartilhamentos de arquivo "caixa de entrada" e "caixa de saída" do servidor de gerenciamento para descarregar o conteúdo alterado do site ou recuperar arquivos para análise. Todos os sistemas eram autônomos (isto é, não faziam parte de um domínio); portanto, o acesso aos compartilhamentos e as sessões do Terminal Services eram configuradas para usar contas locais nos sistemas com senhas fortes e não óbvias conforme é explicado na sessão Senhas. Os compartilhamentos usados foram restringidos para permitir apenas operações de leitura da "caixa de saída" e operações de gravação na "caixa de entrada".
A maior parte da administração ocorreu na sessão do Terminal Services do servidor de gerenciamento. Dessa sessão, os administradores conectavam-se a qualquer sessão do Terminal Services de administração remota de qualquer outro sistema essencialmente "aninhando" sessões do Terminal Services. Eles podiam, então, conectar-se aos compartilhamentos "caixa de entrada" e "caixa de saída" do servidor de gerenciamento e descarregar ou recuperar arquivos conforme necessário para os sistemas servidos. Todo o tráfego que suporta essas funções administrativas exigia o uso de IPSec, como explicado acima.
SQL Server 2000
A base de dados SQL Server 2000 do OpenHack foi executada em um computador dedicado como medida de "defesa em profundidade". Mesmo que a camada web fosse burlada, a base de dados e todas as informações contidas ali permaneceriam isoladas e protegidas.
Conforme mencionado antes, nossa solução usou a autenticação integrada do Windows para conexão com a base de dados. Esta é uma boa prática a ser seguida, pois elimina a necessidade de desenvolver e armazenar de forma segura uma senha para acesso à base de dados.
Para compatibilidade com versões anteriores, Windows 2000 e Windows XP suportam alguns tipos de protocolo de autenticação. Como nosso servidor de base de dados só é acessível através de computadores que implementam autenticação NTLMV2, é altamente recomendável mudar o nível de autenticação do LAN Manager para NTLMv2 only. Note que, com configuração adicional, o Windows 95, o Windows 98 e o Windows NT Server 4.0 com Service Pack 4 e acima também podem suportar o NTLMv2. Restringindo o número de protocolos de autenticação suportados, os administradores minimizam a área de superfície exposta aos atacantes.
Figura 4. Definindo o nível de autenticação do LAN Manager
Com o SQL Server, bem como com o Windows, tivemos o cuidado de instalar, configurar e executar apenas os serviços necessários para restringir a área de superfície da base de dados aberta a ataques potenciais. Para o OpenHack, não instalamos os componentes Upgrade Tools, Debug Symbols, Replication Support, Book Online e Dev Tools.
A instalação foi feita em uma partição NTFS pois isso permitiu uma segurança extra baseada em ACL dos arquivos e pastas que usam SQL Server. A próxima etapa, sempre crítica, era instalar o SQL Server 2000 Service Pack 2 e todas as correções mais recentes.
É bastante comum encontrar instalações do SQL Server onde a conta de serviço é localSystem. Embora em uma rede privada e muito protegida isso possa ser aceitável, possui muito mais privilégios do que o serviço do SQL Server realmente necessita, sendo uma conta administrativa do computador subjacente. Se houver um requisito para a conta de serviço ter acesso a recursos da rede - por exemplo, ao fazer backup em uma unidade de rede, ao usar expedição de logs ou ao usar suporte de replicação - a escolha de uma conta de domínio com baixo privilégio é uma boa idéia. Porém, se o seu ambiente não tiver necessidade desses recursos, a escolha de uma conta local com baixo privilégio funcionará igualmente bem. Para fins desta competição, como não estávamos usando esses recursos e atendendo ao princípio do "menor privilégio", usamos uma conta de usuário local.
Criamos uma nova conta de usuário local do NT com as seguintes configurações:
- Criamos uma senha muito forte, conforme descreve a sessão Senhas.
- Removemos a capacidade de o usuário trocar sua senha.
- Removemos o acesso via Terminal Services.
Depois de criar uma nova conta de usuário, usamos o SQL Server Enterprise Manager para mudar as informações de conta de serviço de inicialização, forçando o serviço de base de dados a ser executado como esse usuário.
Figura 5. Alterando as informações de conta de serviço de inicialização
De acordo com a filosofia e as boas práticas de segurança de executar apenas serviços necessários, usamos o snap-in Serviços, do MMC, para parar o serviço Distributed Transaction Coordinator (MSDTC) e defini-lo como manual, pois a base de dados do OpenHack não executava transações e nem o próprio servidor executava aplicações COM+. Aqui vemos outra vantagem de executar o servidor de base de dados em um computador dedicado: maior capacidade de reduzir a área de superfície circundante que existiria se o servidor estivesse sendo executado lado a lado com outros servidores e serviços.
Conseguimos reduzir ainda mais a área de superfície desabilitando os serviços SQL Server Agent and Microsoft Search, pois nossa solução de base de dados não exigia essas funcionalidades.
Como próximo passo e mais devido à confiabilidade do que à segurança, aumentamos as propriedades do serviço Microsoft SQL Server propriamente dito e alteramos as ações de recuperação para reiniciar o serviço após uma falha. Isso foi feito para manter o tempo de interrupção em nível mínimo em caso de falha.
Figura 6. Mudando as ações de recuperação para reiniciar o serviço após uma falha
Nós, então, usamos o utilitário Server Network e mudamos as propriedades de rede para ocultar o SQL Server das transmissões diretas de clientes. Também removemos o protocolo Named Pipes pois só precisávamos de TCP/IP.
Como parte desta configuração, voltamos e definimos uma senha muito forte para a conta de SA. Isso é recomendável mesmo quando se roda o modo Windows Authentication - se, mais tarde,o modo de autenticação for mudado para modo misto através da ferramenta Enterprise Manager ou diretamente via Registry, você deve garantir que o sistema esteja segura mesmo que o administrador esqueça de definir a senha SA naquele momento. É sempre bom prever o pior cenário nesses casos.
Mudamos a configuração de auditoria de login padrão para Failure. Com isso, o log de erros e o log de eventos registrariam todas as tentativas de login falhas na base de dados SQL Server - informações que poderiam ser úteis na identificação de tentativas de invasão da base de dados.
Em seguida, removemos as bases de dados padrão Northwind e Pubs como parte de nosso esforço para reduzir a área de superfície para ataques potenciais.
Quando todas essas etapas estavam concluídas, criamos a base de dados Awards usada na solução final. Percorremos, então, tabelas e stored procedures e garantimos que a conta associada à aplicação tivesse de executar apenas permissões de execução em stored procedures, e que não houvesse nenhuma permissão nas tabelas propriamente ditas. Isso nos permitiu controlar o acesso e restringir as ações aos stored procedures e não nos preocuparmos com consultas improvisadas ao SQL atuando diretamente nas tabelas. Além disso, garantimos que essa conta não teria outros privilégios ou permissões específicas dentro do SQL Server.
Senhas
Uma etapa essencial na proteção de qualquer servidor é a seleção de senhas longas e complexas que não possam ser facilmente descobertas. Idealmente, uma boa senha deve incluir caracteres de pelo menos três dos quatro grupos a seguir: letras minúsculas 'a' a 'z', letras maiúsculas 'A' a 'Z', números 0 a 9 e caracteres não-alfanuméricos ('>', '*', '&', etc.). Para máxima segurança, as senhas devem ser compostas de caracteres dos quatro grupos além de caracteres gerados com a tecla ALT. Criando senhas desses conjuntos com um comprimento mínimo de oito caracteres, você minimiza as chances de que um atacante seja capaz de adivinhar suas credenciais de login. Trata-se de um enfoque que adotamos em cada um dos servidores de nossa solução OpenHack e que consideramos altamente recomendável.
Conclusão
Nem todas as medidas que adotamos para proteger a solução OpenHack aplicam-se a todas as soluções web. Essas medidas também não representam tudo aquilo que os desenvolvedores e administradores devem fazer para proteger suas soluções específicas. Cada projeto é único e exige uma análise tanto por parte de desenvolvedores quanto de administradores para definir os vetores potenciais de ataque e como a proteção contra eles deve ocorrer. As recomendações acima foram valiosas para nós no OpenHack 4. Mesmo que nem todas se apliquem diretamente à nossa solução, existem certas boas práticas importantes que devem ser abstraídas e aplicadas de uma forma ou de outra sempre que se decide construir uma solução segura.
1. Planeje segurança no projeto original. Isso inclui o desenvolvimento de processos para acompanhar os mais recentes Service Packs e correções.
2. Instale sempre os mais recentes Service Packs e correções.
3. Use sempre senhas complexas e não-óbvias.
4. Reduza a área de superfície exposta a ataques desativando todas as funcionalidades desnecessárias.
5. Exercite o princípio do "menor privilégio". Nunca conceda mais privilégios do que absolutamente necessário.
6. Planeje possíveis falhas e pratique sempre a "defesa em profundidade" para minimizar seu impacto.
7. Ao usar o IIS, rode a ferramenta IIS Lockdown e URLScan.
8. Valide todos os dados de entrada.
9. Use stored procedures parametrizados em vez de gerar consultas dinâmicas na base de dados.
Para mais informações
|
| |
|
 |