SQL Injection - Um pouco Sobre!

Ver o tópico anterior Ver o tópico seguinte Ir em baixo

SQL Injection - Um pouco Sobre!

Mensagem por Robson Alves em Ter Nov 03 2009, 09:07

SQL Injection, para o português Injeção de SQL.
Este trabalho consiste em mostrar de forma um pouco detalhada as formas que
ocorrem os ataques, alguns porquês e como corrigir tanto na aplicação quanto no
banco de dados para que tenha este tipo de ataque sobre controle.

Como todos nós sabemos, este assunto é muito antigo e já rendeu páginas e mais
páginas de noticias num passado próximo quando este tipo de ataque foi
explorado.

A idéia deste ataque é manipular todo o banco de dados pela aplicação utilizando
os objetos input do formulário.

Objetos INPUT em um formulário geralmente são Caixas de Textos. Porém existem
possibilidades de utilizar formas de ataque pela URL, que na programação é conhecido como Querystring.

O atacante geralmente não faz idéia de qual é a estrutura do banco de dados que
ele está acessando e para isso o mesmo deve ter conhecimentos aprofundados na
linguagem SQL.

Alguns sádicos dizem que basta assegurar-se que o Banco de Dados ou a Aplicação
esteja seguro que nenhum atacante terá sucesso ao manipular as informações,
porém isto é comprovado que não é verdade.

Vamos a Prática:

ASP.Net

xmlns=”http://www.w3.org/1999/xhtml”> runat=”server”>
<title>Untitled Pagetitle>
<form id=”form1″ runat=”server”>
<div>
<asp:TextBox runat=”server” ID=”txtEmail”>asp:TextBox>
<asp:TextBox runat=”server” ID=”txtSenha”>asp:TextBox>
<asp:Button runat=”server” Text=”Entrar” ID=”btnEntrar” />
div>
form>

C#


protected void Page_Load(object sender, EventArgs e){
string e_mail = txtEmail.text;
string senha = txtSenha.text;
string sql = “SELECT * FROM TAB_USUARIOS WHERE E-MAIL =’” + txtEmail.Text +
“‘ and senha =’” + txtSenha.Text + “‘”; }

Então temos nosso super formulário de Login, possuímos o campo email e senha!

Então chega aqui aqueles espertinho que assistiu uma video-aula “MASSA” sobre
SQL Injection e ele resolve testar sua aplicação, digitando no campo senha a
seguinte sequência!

‘ or 1=1

Formando assim a seguinte Query para
conversar com o SQL!


SELECT * FROM TAB_USUARIOS WHERE E-MAIL = ” OR 1=1

O SQL retornará todos os usuários desta tabela e assim validando o acesso. Caso
este sistema não valide nenhum caracter enviado ou até mesmo quem está acessando
(Acreditem existe), você estará acessando o sistema. (e nem suou).

Agora não sabemos quais tabelas fazem parte desta Banco de Dados. E nem com qual usuários estamos logados lá no SQL da Empresa, que tal descobrirmos isso?

Procure algum campo de consulta que você possa realizar a seguinte Query.

Para isso tome nota do seguinte, tente verificar quais tipos de valores a
aplicação retorna para você em uma possível consulta, após feita esta análise
digite a query:

Imaginando que esta consulta retorna para nós uma coluna numérica outra texto e
outra numérica.


C%’ UNION SELECT 1,SUSER_SNAME() ,1 –

Ao clicar na consulta teriamos o seguinte resultado;

Select * From tab_consulta
where resultado=’c%’ UNION SELECT 1,SUSER_SNAMES(),1 –

O comando simplificado é:

SELECT SUSER_SNAME()

Ou seja, retornar qualquer coisa que comece com C, e faça o UNION trazendo o
número 1, O Usuário que você está Logado,1.

Quer saber quais tabelas o banco de dados possui??

SELECT OBJECT_ID,NAME FROM sys.objects

Este select retornar uma coluna chamada OBJECT_ID e outra Name, onde o OBJECT_ID
estará referenciando o nome de uma tabela!

Neste momento temos em poder todas as tabelas do banco de Dados, para facilitar
esta triagem e não retornar as tabelas que pertencem ao MASTER, acrescente a
clausula Where da seguinte forma:

SELECT OBJECT_ID,NAME FROM sys.objects WHERE OBJECT_ID > 20

Anote em algum lugar o retorno destas informações!

E utilize os valores da coluna OBJECT_ID da tabela que te interessa para ver-mos
quais são as colunas desta tabela, para tal utilize a seguinte sintaxe:

SELECT name, max_length,is_nullable, system_type_id FROM sys.columns where OBJECT_ID = 3

O retorno deste são as colunas ta tabela (OBJECT_ID) que você colocou na sua Clausula Where!

Você é capaz também de visualizar a versão do SQL
Server utilizado pelo servidor, assim como os Services Packs instalados
na instância que você acessou,

para tal utilize o comando: SELECT @@VERSION

Além
disso tudo, caso a aplicação não trate nenhuma exceção de erro, você
também tem a possibilidade de visualizar quais as tabelas que retornam
no erro de SQL que você vai forçar, outra forma interessante para
detectar o nome das colunas e da tabela do banco de dados.


Para isso
utilize o comando HAVING, onde este comando necessita ser utilizado em
conjunto com o GROUP BY, e para tal o SQL informará quais tabelas
pertencem ao HAVING porém, não constam no GROUP BY.




Para não estender muito, Vemos que aqui o controle sobre o banco de dados e suas informações é total…

Porém, toda a didática de como fazer o Mal é linda e maravilhosa, más imagina um
espertinho desses brincando com uma aplicação sua? Arriscando sua reputação
naquela multinacional que você tanto lutou para entrar?

A solução é mais simples que todo esse drama que foi relatado acima, é claro que
a solução é, e será simplesmente para “Tapar” este buraco.

Para tal então utilizaremos as Famosas Stored Procedures para realizar nossas
Querys, e toda a passagem de parâmetros para o SQL será feito no C#. Veja o
Código como Ficou abaixo:

C#

public
void validaLogin(string
e_mail, string senha)
{
// Instância da Classe SqlCommand;
SqlCommand comando = new SqlCommand();
// Informando o nome da Procedure
comando.CommandText = “STP_VALIDA_LOGIN”;
// Informando o Tipo de Comando a ser utilizado
comando.CommandType = CommandType.StoredProcedure;
// Passando os Atributos do Parâmetros que são declaradas na Procedure

comando.Parameters.Add(“@EMAIL”,SqlDbType.VarChar,20);
comando.Parameters.Add(“@SENHA”,SqlDbType.VarChar,10);

// Passando os valores para os parâmetros
comando.Parameters["@EMAIL"].Value = e_mail;
comando.Parameters["@SENHA"].Value = senha;
// Executando a Conexão com O Banco de Dados, utilizando um usuário
// com acesso limitado a base de dados
// e efetuando os comandos acima.
Conexao.ExecutarProcedure(comando);
}

Os comentários a partir o código, creio eu, que já seja auto-explicativo.

Agora vemos como ficará nossa Procedure de Login, atente-se que existem outras
formas de fazer esta Stored Procedure.

SQL para MS SQL Server

SET ANSI_NULLS ON

SET QUOTED_IDENTIFIER ON

GO CREATE PROC STP_VALIDA_LOGIN



@EMAIL VARCHAR(20) = ,

@SENHA VARCHAR(10) =

AS

DECLARE @QUERY VARCHAR(8000) =

SET @QUERY = ‘ SELECT * FROM TAB_USUARIOS WHERE EMAIL = ‘ + @EMAIL + ‘ AND SENHA = ‘ + @SENHA

EXEC @QUERY



Desta
forma a passagem de parâmetros entre banco de dados e aplicação
possuirá maiores controles que negarão de forma natural os tipos de
ataques geralmente lançados!


Está um pouco sem formatação, depois eu dou uma limpada!
Dúvidas posta ae!!


_________________
As palavras movem, mas são os exemplos que inspiram atitude e comportamento semelhante.

Administrador do Fórum
Analisa/Programador at Senior Solution
http://RobsonAlves.Net
avatar
Robson Alves
Iniciante

Mensagens : 133
Data de inscrição : 10/10/2009
Idade : 28
Localização : São Paulo

http://robsonalves.net

Voltar ao Topo Ir em baixo

Ver o tópico anterior Ver o tópico seguinte Voltar ao Topo

- Tópicos similares

 
Permissão deste fórum:
Você não pode responder aos tópicos neste fórum