Você está na página 1de 13

Tolerância a Falhas em sistemas distribuídos (programação)

Arthur Zavattieri Cano Lopes

Curso de Redes e Segurança de Sistemas


Pontifícia Universidade Católica do Paraná

Curitiba, Maio de 2009.

Resumo

Cada vez mais somos dependentes de sistemas distribuídos, seja para operações
bancárias, compras em sites online ou mesmo por lazer. O que não sabemos muitas vezes é
o risco que corremos ao digitar informações pessoais nesses sistemas, isso porque muitos
deles não são seguros. Até os bancos que investem muito dinheiro em pesquisa e
desenvolvimento estão sujeitos a esse tipo de falha.
No decorrer desse documento estarei descrevendo algumas (as mais relevantes) falhas
descobertas em sistemas distribuídos. Existem muitas outras falhas em sistemas distribuídos,
sejam elas por arquitetura de rede, sistemas operacionais ou mesmo escolha de tecnologia
inadequada. Estarei focando esse trabalho em falhas de programação e sua implicação em
sistemas distribuídos.

Índice
Introdução ........................................................................................................................... 2
SQL...................................................................................................................................... 2
Comando Básico ............................................................................................................... 2
Comando Igual(=) ......................................................................................................... 3
Comando Diferente <> .................................................................................................. 3
Comando de Negação (NOT) ........................................................................................ 3
Comando de Filtro ............................................................................................................ 3
Comando de Ordenação .................................................................................................... 4
Filtro de textos e dadas...................................................................................................... 4
Comando de seleção especial ............................................................................................ 4
Comando TOP............................................................................................................... 4
Comando Like............................................................................................................... 5
Comando IN / NOT IN.................................................................................................. 5
Cenários............................................................................................................................... 5
Validação de Senhas .......................................................................................................... 5
Algoritmo A – Concatenação de instrução ..................................................................... 5
Algoritmo B – Manipular resultado ............................................................................... 6
Algoritmo C – Manipular resultado. Cenário 2 .............................................................. 7
Considerações ............................................................................................................... 7
Validação de Entrada de Dados ......................................................................................... 7
Validação em site de RH................................................................................................ 7
Mensagem de Validação ................................................................................................ 8
Considerações ............................................................................................................... 8
Falta de configuração do MaxLength................................................................................. 8
Considerações ............................................................................................................. 10
Mensagem de Erro do Banco de Dados ........................................................................... 10
Considerações ............................................................................................................. 10

1
Mensagem de arquitetura do servidor .............................................................................. 10
Considerações ............................................................................................................. 11
Passagem de parâmetro via post ...................................................................................... 11
Sintaxe em PHP e ASP ................................................................................................ 11
Automatização da Aplicação............................................................................................. 12
Conclusão .......................................................................................................................... 13
Bibliografia........................................................................................................................ 13

Introdução
Atualmente os sistemas distribuídos são usados por milhões de pessoas para executar as
mais diversas atividades. Sistemas esses que, em sua grande maioria estão conectadas a
Internet.
Todo o sistema tem falhas, mais um sistema conectado a Internet, sem dúvida está mais
susceptível a exploração dessas falhas. Conforme a tecnologia evolui e corrige problemas
antigos, novos problemas aparecem. Logo se faz necessário uma constante correção de
problemas a fim de evitar problemas maiores.
Nesse documento estarei montando cenários e explicando algumas falhas de segurança
conhecidas em sistemas on-line. Existem muitas outras, mas estarei focado em falhas
explorando algoritmos de programação.
Vamos ver também como se comporta a interação entre o algoritmo e o sistema
armazenamento dos dados.
Para isso, farei uma pequena explicação sobre SQL-ANSI 92 usado pela maior parte dos
sistemas.

SQL
Nesse tópico serão explicados brevemente os comandos SQL mais utilizados em sites e
sistemas distribuídos.[8]
A linguagem SQL é usada basicamente para extrair informações de um banco de dados.
Seja ele SQL Server, ORACLE ou FIREBIRD. Todos eles têm seus comandos proprietários,
mais agora serão abordados apenas os comuns, para melhor entendimento.
Estarei explicando apenas os comandos que uso dentro dos tópicos. É muito importante
entender os comandos SQL e a forma que a seleção é feita. Isso porque nos próximos tópicos
será demonstrado como manipular a linguagem para conseguirmos o resultado esperado.
Para maiores informações sobre os comandos, pesquise no site do fabricante, que consta no
final desse documento (referencia oito e nove).

Comando Básico
Os dois comandos mais básicos de uma seleção ou query no SQL são; SELECT / FROM
Um exemplo que podemos usar é uma query na tabela com nome usuário selecionando os
campos nome e senha. A query seria:
SELECT Nome, Senha
FROM usuario
O resultado da query seria:
Nome Senha
---------- ------------
alopes senha123

2
aisidro senha123

Veja que no exemplo acima, não foi usado nenhum critério de filtro.

Comando Igual(=)
No SQL, usamos o comando “=” para igualar a sentença. Vamos fazer uma query de
exemplo, pegando apenas o nome = ‘alopes’;

SELECT Nome, Sexo


FROM usuario
WHERE nome = 'alopes'

Comando Diferente <>


Usaremos o comando “<>” (Direfente) para pegar todos os registros, menos esse que está na
sentença após o comando <>. Vamos fazer uma query de exemplo, pegando apenas o nome
direfente de alopes (nome<>’alopes’);
SELECT Nome, Sexo
FROM usuario
WHERE nome <> 'alopes'

Comando de Negação (NOT)


Usaremos o comando “NOT” para negar ou inverter a lógica da sentença. Vamos fazer um
exemplo pegando o os nomes que estão dentro do grupo: alopes, aisidro e lsegalin.

SELECT Nome, Sexo


FROM usuario
WHERE nome IN( 'alopes', 'aisidro, 'lsegalin)

Para negar essa expressão, colocamos o comando NOT antes da palavra IN. Isso quer dizer
que agora não queremos os nomes que estão dentro da sentença: Vejamos o exemplo:

SELECT Nome, Sexo


FROM usuario
WHERE nome NOT IN( 'alopes', 'aisidro, 'lsegalin)

Comando de Filtro
Os comandos de filtros são usados para refinar a seleção de dados.
Para isso, podemos usar os comandos; WHERE / AND
Vamos dizer que você tenha uma tabela com 4000 usuários e que você queira selecionar
apenas os usuários do sexo masculino. A query seria:
SELECT Nome, Sexo
FROM usuario
WHERE sexo = 'M'
AND nome = 'alopes'

O resultado da query seria:


Nome Sexo

3
---------- ------------
alopes M

Sempre que for o primeiro parâmetro de filtro, deve-se utilizar o comando WHERE. Caso
exista mais de um parâmetro de filtro, o segundo e os demais deverão usar o comando AND.

Comando de Ordenação
O comando de ordenação é usado para ordenar o resultado de uma query. Para isso vamos
usar o comando; ORDER BY
Vamos agora selecionar na tabela com nome usuário os campos nome e senha ordenada por
nome. A query seria:
SELECT Nome, Senha
FROM usuario
ORDER BY 1
OU
SELECT Nome, Senha
FROM usuario
ORDER BY Nome

O resultado seria:
Nome Senha
---------- ------------
aisidro senha123
alopes senha123

Filtro de textos e dadas


Quando vamos selecionar ou comparar um texto ou uma data, devemos usar o caractere ‘
(aspas simples) indicando que o campo é um texto.
Por exemplo, quero selecionar o nome alopes, então devo passar o filtro entre aspas simples.
A query seria:

SELECT Nome, Senha


FROM usuario
WHERE nome = 'alopes'

Comando de seleção especial


Existem alguns comandos que cada banco de dados implementa da sua forma. Basicamente
eles fazem a mesma coisa, mais utilizam notações diferentes.

Comando TOP
No SQL, para selecionar os primeiros registros, usamos o comando TOP.
Vamos agora selecionar na tabela com nome usuário os campos nome e senha pegando
apenas os cinco primeiros registros:

SELECT TOP 5 Nome, Senha


FROM usuario

Como resultado, teríamos os cinco primeiros registros da tabela, mesmo que ela tenha 4000
registros.

4
Comando Like
O comando Like é usado para fazer buscar por partes do texto resultante. Para isso, deve-se
usar a notação [campo like ‘%%’] onde o símbolo percentual é usado para dizer em que parte
do texto você quer selecionar.
Vamos agora selecionar na tabela com nome usuário os campos nome e senha pegando
apenas nomes começando com a parte “al”.
SELECT Nome, Senha
FROM usuario
WHERE nome like 'al%'

Vamos agora pegar os nomes que tem em qualquer lugar escrito ‘alopes’. A query seria:
SELECT Nome, Senha
FROM usuario
WHERE nome like '%alopes%'

Comando IN / NOT IN
O comando IN/NOT IN é usado para passar como filtro um grupo de filtro. Ele é usado no
lugar do símbolo “=”.
Vamos agora selecionar na tabela com nome usuário os campos nome e senha pegando os
nomes alopes e/ou aisidro.
O comando SQL seria:

SELECT Nome, Senha


FROM usuario
WHERE nome IN ('alopes', 'aisidro')

Cenários
Validação de Senhas
Vamos efetuar uma compra em site e-commerce. O processo que faremos será escolher um
produto na loja virtual e coloca-lo na “cesta” de compras.[3]
Após isso, o site solicita um cadastro com seus dados pessoais bem como a forma de
pagamento.
É criada então a “conta” com login e senha informada.
Vamos efetuar o “login” conforme dados da conta acima criada.
O problema nesse cenário é que vários sites de e-commerce não se preocupam em retirar
caracteres reservados informados pelo operador.
Como resultado, temos três algoritimos falhos:

Algoritmo A – Concatenação de instrução


O sistema vai até o banco de dados pesquisando pelo login e senha. Caso exista um registro
de retorno, o nome e a senha são válidos e o usuário entra.
Esse é o algoritimo de validação mais falho e fácil de burlar.

5
Figura 1: Tela de Login

Como podemos ver na figura acima, o operador informa qualquer coisa no nome, seguido de
uma “’” para fechar a sentença SQL.

Figura 2: Query executada no banco de dados

Após isso, ele coloca uma condição redundante “1=1” o que garante que sempre irá retornar
todos os registros da tabela. Isso faz com que o servidor crie uma sessão segura para o
primeiro usuário que retornar na busca.
Como a sessão já está ativa, o operador poderia efetuar uma compra, alterar dados cadastrais,
emitir uma compra com endereço de entrega diferente do cadastrado, etc...

Algoritmo B – Manipular resultado


O sistema vai até o banco de dados pesquisando pelo login e senha, caso exista um registro
de retorno, o operador entra.
Isso ocorre porque a comparação do login e senha é feito no banco de dados. Nesse caso seria
necessário criar uma condição redundante para o campo “login”. Para isso, podemos colocar
no campo login a sentença ‘ OR Senha = ‘123’.
Nesse caso, o operador precisa necessariamente saber uma senha válida. Descobrir uma
senha é mais fácil do que se pensa. Pois muitos sites quando são criados, utilizam logins de
teste e com senhas como: “teste”, “123”, “1234”, “12345”.
Muitas vezes o contexto do site também ajuda na “adivinhação” da senha.
Novamente o operador está logado e tem acesso a conte de outra pessoa.
Exemplo:
SELECT Nome, Senha
FROM dbo.usuario
WHERE clogin = '' OR Senha = '123'
AND Senha = '123'

6
Algoritmo C – Manipular resultado. Cenário 2
O sistema vai até o banco de dados pesquisando pelo login. Caso exista um registro de
retorno e a senha for igual à senha digitada, o usuário entra.
Esse algoritmo também é um pouco mais seguro, e segue a mesma linha de raciocínio do
Algoritmo B.
A diferença entre o Algoritmo B e o C é que no primeiro caso, a query é feita utilizando
ambos os campos (login e senha), já na segunda situação é passado apenas o campo login e a
senha é comparada na aplicação.
Segue exemplo de query abaixo:

SELECT Nome, Senha


FROM dbo.usuario
WHERE clogin = '' OR Senha = '123'

Considerações
A regra geral é jamais fazer pesquisa no banco sem tratar caracteres especiais. Dessa forma,
fica um pouco mais difícil de quebrar os algoritmos. Outros utilitários podem ser usados para
evitar esse tipo de problema, como objetos de acesso a dados. Por exemplo, MDAC que é um
objeto responsável por fornecer o acesso entre o solicitante e o repositório de dados.
Esse tipo de objeto permite que qualquer informação digitada pelo operador seja tratada
como texto, ou seja, o próprio objeto se encarrega de converter e tratar a entra de dados. Para
mais informações sobre o MDAC, acesse a referência bibliográfica quatro.

Validação de Entrada de Dados


Algumas validações, indiretamente, dão ao operador informações indevidas que podem ser
usadas para “quebrar” a segurança da aplicação.

Validação em site de RH

Figura 3: Campo limitado;

Na tela mostrada na Fig. 3, o campo de Matrícula é “limitado” pelo programador quanto a


quantidade de caracteres de entrada. O tipo do campo é alfanumérico e aceita no máximo sete
posições. Ao entrar na tela de login, e selecionar o campo Matrícula.
Ao tentar digitar texto, as letras digitadas não aparecem e uma mensagem de alerta
informando o operador: “O campo login deve conter a mátricula do operador composta por
números”.
Com isso o operador já sabe que o campo é numérico, de no máximo sete posições.
Coletar informações sobre o sistema facilita muita a quebra do algoritmo. Mesmo assim
colocar a quantidade máxima de caracteres impede um problema maior que descobrir o tipo e
tamanho do campo. Eu explico melhor no tópico “Falta de configuração do MaxLength”.

7
Mensagem de Validação
Na tela mostrada na Fig. 4, o operador informa um login que não existe. O sistema emite um
alerta informando: “ O login informado não existe.”
O Operador informa um login válido e a senha errada. O sistema emite um alerta informando:
“ A senha informada está incorreta.”.

Figura 4: Mensagem de erro informativa.

Nesses dois casos, o sistema está afirmando que o login não existe e que a senha informada
não está correta. Novamente o sistema informando ao operador informações que vão facilitar
a quebra do algoritmo.
Outro ponto importante na validação de entrada de dados é ser feito sempre no servidor. Isso
parece uma consideração simples, mas muitos programadores não levam em consideração. O
fato é que existem muitos sites que fazem validação de entrada de dados apenas no cliente
usando, por exemplo, javaScript. Isso ocorre porque esse recurso evita que a requisição vá até
o servidor para fazer a validação. Nesse caso, o mais indicado seria colocar a validação no
cliente e no servidor.
Fazer validação apenas no cliente é o mesmo que não fazer validação alguma.

Considerações
Nos casos apresentados acima, o indicado seria o sistema sempre tratar as mensagens de erro
de forma mais genérica.
Poderia por exemplo exibir a mensagem “Dados do Login inválido”.
Dessa forma, o operador não receberia informações detalhadas sobre o erro que ocorreu no
sistema. Caso fosse um erro de negócio, deveria ter um tratamento específico para facilitar o
entendimento do operador.

Falta de configuração do MaxLength


O Maxlength é uma propriedade que controla a quantidade máxima de caracteres que podem
ser digitados dentro de um controle.
Podemos usar como exemplo a figura 3, cujo campo matrícula está configurado com
maxlength igual a sete caracteres numéricos.
Nesse caso, a falta de configuração da propriedade implica na invasão do banco utilizando a
página de Internet para fazer querys no banco de dados;
Será demonstrado com mais detalhes através da figura abaixo:

8
Figura 5: Falta de Maxlength.

Vamos considerar que a query enviada ao banco seja essa:

SELECT Nome, Senha


FROM dbo.usuario
WHERE clogin = “’ & campoLogin & ‘”
AND senha = “’ & campoSenha & ’”

Essa query vai ao banco, concatena o valor digitado nos campos login e senha e retorna os
campos nome e senha.
Bom, agora vamos considerar que o operador entre na janela de login e no primeiro campo
seja digitado: ‘ or 1=1
No campo senha, vamos digitar o valor ‘ or 1=1 UNION SELECT NAME, TYPE FROM
SYS.SYSOBJECTS

Abaixo segue o comando que irá ser enviado ao banco dados:

SELECT Nome, Senha


FROM dbo.usuario
WHERE clogin = '' OR 1=1
AND Senha = '' OR 1=1
UNION
SELECT NAME, TYPE
FROM SYS.SYSOBJECTS

Esse comando vai concatenar no final da query uma consulta com todas as tabelas do banco
de dados.
Como resultado, teremos todos os usuários e tabelas do banco de dados. Segue exemplo
abaixo:

Nome Senha
---------- ------------
alopes senha123
aisidro senha123
dbo.usuario U
dbo.perfil U
dbo.mensagem U
dbo.itemMSG U
dbo.legendas U

9
Considerações
A falta de configuração do tamanho do campo permitiu que o exemplo acima fosse realizado.
Dessa forma, utilizamos o campo senha para criar uma outra query e enviar ao banco junto
com a validação do login. Assim como foi criado uma query, poderia ter sido enviado um
comando DELETE ou UPDATE apagando ou alterando os dados do banco.
A recomendação nesse caso é sempre configurar os campos de entrada para que o operador
não possa informar algo diferente do previsto.

Mensagem de Erro do Banco de Dados


Como o titulo já diz, esse é outro erro cometido com freqüência em sistemas distribuídos.
Nesse caso, o programador não fez o tratamento de erro adequadamente e acaba “passando” a
mensagem de erro que foi levantada no banco direto para o cliente.

Figura 6: Erro do Banco de Dados

Conforme ilustrado na Fig.6, o sistema está exibindo que o banco de dados é MySQL e os
detalhes do erro. Isso facilita muita a invasão do servidor, pois com essa mensagem o
operador mal intencionado já sabe qual banco está rodando e quais as falhas que ele pode
explorar.
Esse tipo de erro é muito freqüente em sistemas web, pois normalmente o servidor de Internet
retorna a mensagem de erro diretamente ao cliente.

Considerações
A melhor forma para resolver esse problema é tratar os erros que vem do banco de dados.
Se não for possível retornar uma explicação detalhada do que aconteceu, levantar um erro
genérico, como por exemplo: “Ocorreu um erro no banco de dados. Seus dados não foram
salvos. Por favor, contate o administrador do sistema”.
Dessa forma o operador não saberia qual banco de dados está sendo utilizado pela aplicação.

Mensagem de arquitetura do servidor


Na tela mostrada na Fig. 1, o operador informa uma Apóstrofos no campo Login, informa a
senha e clica no botão “Entrar”;

10
Figura 6: Detalhe do servidor

O sistema retorna uma mensagem interna de erro, informando dados detalhados sobre a
arquitetura usada na aplicação.

Considerações
No exemplo acima, é um servidor Apache, versão 2.2.3 rodando PHP versão 5.2.0. Veja que a
mensagem de erro dá informações tão detalhadas como a versão do PHP. Com isso em mãos,
o operador mal intencionado já consegue saber quais falhas existem nessa versão de
linguagem.
O que muitos programadores de software desconhecem, é o fato do servidor de Internet
conter uma configuração para exibir uma mensagem de erro padrão sempre que um erro
ocorrer e que não for tratado.
Com essa configuração ativa, fica um pouco mais difícil do operador descobrir detalhes sobre
a arquitetura da aplicação.

Passagem de parâmetro via post


Muitos sites utilizam parâmetros para passar informações de uma página para outra e também
para passar parâmetro de consulta no banco de dados.
Primeiro vou dar dois exemplos em linguagens como asp e php.

Sintaxe em PHP e ASP


A passagem de parâmetros via POST nas duas linguagens acima deve usar como separador o
símbolo“?”. Isso indica que após esse caracter existe um parâmetro. Após isso deve vir o
nome do parâmetro, depois o símbolo”=” e por ultimo o valor.
Para passar dois ou mais parâmetros deve-se usar o símbolo “&” que significa que após esse
símbolo existe outro parametro.
A sintaxe deve ser:
www.site.com.br/ index.php?nomeparametro1=valor&nomeparametro2=valor

11
Figura 7: Site usando PHP

Figura 8: Site usando ASP

Vamos imaginar agora, um e-commerce que faz o login do operador, Fig 1, passando os
parâmetros login e senha.
Nos dois casos, o usuário pode trocar os parâmetros do site e visualizar o comportamento do
mesmo.

Automatização da Aplicação
Como pudemos ver, existem diversas formas de identificar problemas no desenvolvimento de
sistemas distribuídos. Para automatizar a busca por falhas, podemos criar uma aplicação que
ficasse trocando os parâmetros até que conseguisse logar.
Fazendo essa aplicação em Visual basic, utilizaríamos o objeto INET que gera um post para
determinado endereço.
Agora iremos analisar como é simples fazer tal aplicação.
Então o site usa o algoritmo B, passando o usuário e a senha para que seja feita uma consulta
no banco de dados.
Já tentamos as senhas “padrões” que normalmente alguém usaria, mas não tivemos sucesso
para entrar no site.
Logo poderíamos desenvolver essa aplicação que pegaria cada palavra do dicionário e
colocaria como a senha, mandando um post para a APP.
Normalmente, as senhas utilizadas pela grande maioria das pessoas são palavras que existem
no dicionário. Logo esse ataque demoraria algum tempo, mais seria bem sucedido.

12
Existem outras variáveis que devo citar para esse tipo de “ataque”.
Existem vários firewall que derrubam a conexão do solicitante se o mesmo estiver fazendo
várias solicitações em um período constante de tempo.
Em alguns sites existe também um mecanismo que bloqueia o login do usuário, por um
determinado tempo, caso ele tenha tentado digitar a senha mais de 3 vezes.
Ou seja, existem outros fatores externos aos que eu expliquei aqui que podem interferir nos
exemplos acima.

Conclusão
Sempre irá existir falhas em softwares, sejam elas por culpa de arquitetura ou por
desenvolvimento inadequado.
O primeiro passo para solucionar o problema, é assegurar que cada programador saiba como
escrever códigos sem incorrer nesses casos que citei acima e então assegurar que todas as
equipes de programação disponham de meios para encontrar, consertar ou evitar esses
problemas.

Bibliografia
[1] Tolerância a falhas: conceitos e exemplos, Taisy Silva Weber1, Programa de Pós-
Graduação em Computação - Instituto de Informática – UFRGS;

[2] Tolerância a falhas: conceitos e exemplos, Larry Greenemeier, reportagem,


http://www2.uol.com.br/sciam/noticias/seguranca_virtual_alerta_para_25_maiores_falhas_de
_programacao.html;

[3] Falhas de Segurança de Programação , Dennes Torres,


http://www.msdnbrasil.com.br/docs/net ;

[4] Microsoft Data Access Component , Microsoft, http://www.microsoft.com/mdac;

[5] Truques e dicas, http://www.truquesedicas.com, Exemplo usado nas figuras 7;

[6] Magazine Luiza, http://www.magazineluiza.com.br, Exemplo usado nas figuras 8;

[7] Marcoratti, http://www.macoratti.net

[8] Microsoft SQL Server, http://www.microsoft.com/sqlserver;

[9] Oracle Database Server, http://www.oracle.com/;

[10] Invasão de WebSite, HackerTeen, http://www.hackerteen.com/pt-br/ht-posts/invasao-


website.html

[11] Ataques por injeção de encomendas SQL, Kioskea,


http://pt.kioskea.net/contents/attaques/injection-commandes-sql.php3

[12] New Defenses for automated SQL Injection Attacks, Michael Cobb, Contributor,
http://searchsecurity.techtarget.com/loginMembersOnly/1,289498,sid14_gci1317069,00.html

13

Interesses relacionados