Pentesting - SQL INJECTION [ Em desenvolvimento UPDATE 6 ]
Autor: Ciência da Computação - JokerHat | Publicado: 2016-03-31T22:58:00-03:00


Vamos variar um pouco.

Isso vai complementar seu conhecimento quando passar a desenvolver melhor suas páginas web.


Nenhum sistema é seguro definitivamente ou livre de falhas.




1. LABORATÓRIO







Você poderá escolher o cenário que você quiser para aplicação dos testes.

O meu cenário são dois notebooks: um netbook com o sistema windows 7 x64 como servidor; e um notebook com o sistema live usb da ultima versão do Kali Linux x64 como atacante.



Iremos testar as aplicações utilizando o PHP. Vc poderá incluir outros testes relacionados às suas necessidades com outras linguagens como JSP e ASP por exemplo. O importante é que vc entenda o conceito de forma a ser capaz de aplicar o conhecimento quando necessário.





1.1. CRIANDO O SERVIDOR DE HOSPEDAGEM



Baixe o wampserver [http://www.wampserver.com/en/].&nbsp;

Instale-o normalmente.





O wampserver é apenas uma opção para criarmos um servidor. Devido a sua facilidade de operação, configuração e instalação para ambientes LOCAIS, é o mais indicado para testes de aplicações, principalmente para Pentasting.







Este ambiente de testes é conhecido na área de TI também como Ambiente de Homologação. Onde são feitos testes da aplicação antes da validação final da versão da aplicação. Seria interessante você incluir nos seus testes o Pentasting em termos de testes de segurança ou você contrata alguém do ramo.



Obs: Outra coisa importante, estamos criando um servidor de hospedagem para ambiente LOCAL em sistemas windows. Ainda vou abordar um Post onde criaremos um servidor de hospedagem EXTERNO (e posso abordar o Linux - o mais viável). A partir desse conhecimento você não precisará, necessariamente, pagar por um servidor de hospedagem por mês para ter seu conteúdo no ar. O servidor vai ficar na sua casa. Você só precisará manter a internet paga (risos) e o domínio anual para torná-lo disponível ao mundo.




Para demais informações sobre o wampserver, você poderá encontrar no fórum do próprio aplicativo. Ainda não encontrei uma documentação ou livro a tratar diretamente do wampserver. Contudo, vc encontrará referencias necessárias sobre o PHP [http://php.net/] e o Apache [https://httpd.apache.org/], o qual define suas características.









Obs: Uma saída para quem aumentar a renda, poderia ser escrevendo livros sobre os temas. Afinal, é o mais apropriado do que apenas seguir um tutorial porque você acaba não entendo o conceito, dependendo de quem estiver explicando. Ou quando quer aprofundar no assunto, não possui referencias necessárias.

Ao terminar sua instalação, abra seu browser e acesse o localhost. A página que lhe aparecerá é semelhante a imagem abaixo:













1.1.1. VISUALIZAÇÃO DO WAMPSERVER EM OUTRAS MÁQUINAS&nbsp; (WAMPSERVER EM REDES)



Tenho visto muitas soluções para este assunto na internet durante o levantamento bibliográfico. Cada um aborda de uma forma. A maioria configura o sistema nos arquivos internos do wampserver sendo que para muitas das necessidades de configurações não precisa abrir nenhum arquivo interno basta seguir as opções que ele oferece que facilitam suas configurações.&nbsp;

É importante salientar que a versão que estou usando: wampserver 2.4.9 também é referenciado como wampserver 2.5; com a versão PHP 5.5.12.&nbsp;



Uma das explicações para tanta informação pode ser referente a diferentes versões. Para esta versão (wampserver 2.4.9 ou 2.5) podemos disponibilizar o acesso de outras máquinas ao servidor apenas clicando na opção SERVER ONLINE. Veja:







Para você acessar a página do wampserver em outra máquina você precisa ainda saber o IP da máquina que esta instalada o wampserver (que tem o papel de servidor).

Existem várias formas de saber isso, contudo, para ser mais fácil a todos, acesse Painel de controle/Central de Rede e Compartilhamento, se seu sistema for windows.
Depois clique em alterar as configurações do adaptador.&nbsp;









No meu cenário minha conexão é WI-FI. Ao clicar neste adaptador, outras opções aparecem no canto superior. Clique em Exibir o Status desta Conexão. Depois no botão Detalhes. Então, obtenha o IP.









Obs: Atenção ás redes DHCP, pois o IP que acabou de anotar poderá mudar, de acordo com as conexões presentes na sua rede, e ser necessário fazer a mesma operação para obtenção do IP do servidor. Você poderá solucionar isso em seu roteador deixando um IP apenas para isso, por exemplo. Enfim.&nbsp;





Obtendo o IP, digite-o em outra máquina.Eu acessei no outro computador, voilá:









Note que apenas os dispositivos que estiverem ligados à sua rede, acessarão a página do servidor wampserver. Ou seja, nosso servidor é Local.



Para interromper o acesso basta torná-lo OFFLINE:









E ao tentar acessar em outra máquina, novamente, será esta a mensagem que receberá do Apache:







Note que apenas clicamos em um "botão" para isso. Se quiser visualizar o que acontece (o que não vejo necessidade), basta observar o arquivo C:\wamp\bin\apache\apache2.4.9\conf\http.conf quando deixar o sistema online ou offline, os campos que serão alterados.






Na pasta de c:\wamp\www é onde você irá inserir os projetos.

No meu cenário criei um diretório chamado Pentast/sqli. Dentro dele conterá alguns exemplos para aplicações relacionadas a Pentast e neste caso SQLi (sql injection).



Podemos estar usando qualquer editor ou o bloco de notas, para criarmos as páginas de testes. Fique a vontade. Eu estou usando o Notpad++ além de outros.



Teste uma aplicação com php:
1. Abra seu editor com novo projeto
2. Insira o código que poderá ser obtido aqui : http://php.net/manual/pt_BR/tutorial.firstpage.php

3. Salve como index.php
3. Chame no Browser











1.1.2. CRIANDO BANCO DE DADOS



Na página do wampserver, clicando em phpmyadmin, entramos na pagina do gerenciamento do banco de dados. Você irá criar um banco chamado sqli.















Clique no banco dedados que criou. Crie agora uma tabela chamada users com os campos: id, name e pwd.















Agora insira o conteúdo. Para name insira "admin" e para pwd "admin". 















Depois vamos encriptando. Por enquanto deixe desta maneira.





1.1.3. CREDENCIAL DO PARA ACESSO AO MYSQL



Clique em Utilizadores. E visualize a coluna Palavra-Passe. Estão com NÃO. Isso significa que para acessar o banco dedados não é preciso senha.

Vamos criar uma. Clique em Alterar Privilégios, e role a página que abrir até visualizar Alterar Palavra-Passe. Estarei usando a senha toor. Clique em EXECUTAR (para gravar as alterações). A credencial para acesso ao Phpmyadmin é root/toor.








Agora dê um reflesh (F5) na página e veja:









Este erro ocorre porque a sessão do auth não esta habilitada na configuração default. No erro é descrito o arquivo para alterarmos: config.inc.php.Abra-o:









As duas linhas, demonstrado da figura abaixo, são responsáveis por este acesso:







Mude para:




Agora dê um Reflesh (F5) na página de erro E Insira a credencial: usuário root; e senha toor.







E voilá:







Essa é a credencial que iremos usar nas aplicações. Vc poderá utilizar um outro usuário se quiser.



Se vier a encontrar algum erro de execução como apagar uma base de dados, inserir, etc. Vá até uilizadores/root (que foi o usuario que alterei) e escolha a base de dados em Privilégios Específicos da Base de Dados.













2. TESTES



Vamos criar algumas classes iniciais à aplicação.

Os códigos abaixo são baseados em Programação Orientada a Objeto. Contudo, faz parte do ambiente de desenvolvimento.






Links:

1. Construtores e desconstrutores PHP: http://php.net/manual/pt_BR/language.oop5.decon.php

2. Conexão DBO com PHP: http://wiki.locaweb.com/pt-br/Como_conectar_a_um_banco_MySQL_atrav%C3%A9s_de_script_PHP

3. MYSQLi (PHP 5.5): http://php.net/manual/pt_BR/mysqli.query.php
4. Desing Pattern Singleton: https://pt.wikipedia.org/wiki/Singleton

5. PDO: http://php.net/manual/pt_BR/ref.pdo-mysql.php

6. Conexões: http://www.phpro.org/tutorials/Introduction-to-PHP-PDO.html







2.1. CLASSE DE CONEXÃO COM O BANCO DE DADOS



Eu criei uma classe de conexão com o banco de dados MySql. A conexão é feita por PDO. Sua estrutura segue um padrão chamado Singleton que permite apenas uma instância da classe.



Você poderá visualizá-la aqui -&gt; http://www.programmr.com/embed.php?action=tf&amp;path=lameck/view/temp_1459461385/cDBO/cDBO.php: http://www.programmr.com/embed.php?action=tf&amp;path=lameck/view/temp_1459461385/cDBO/cDBO.php



Na sua index.php, faça um teste, chamando as credenciais do banco de dados utilizando a classe cDBO:







O resultado será este:







Vc vai usar esta classe no seu projeto chamando-a no require. Isso 
para diminuir o numero de códiog na index.php e não "embaralhar" sua 
cabeça.




2.2. IMPLEMENTAÇÃO DA PÁGINA TESTE 



Vamos utilizar a URL para realizar algumas façanhas.&nbsp;

Adicione no código as linhas.







Na URL, você terá um parâmetro de busca que será utilizado na Query. Esse parâmetro e o id usado no método Get em php. Desta forma, informamos o id para a busca ser realizada. Se o id existir é informado os dados, que é uma resposta da URL. Caso não, o retorno será nulo. Veja:













Isso porque no banco de dados esta apenas um cadastro. E o id deste cadastro é 1.







Crie uma outra tabela chamada Post com as flags: id, text







Insira três informações para termos 3 id para pesquisas.











Agora chame a tabela post na página index.php ao invés da tabela user.













3. APLICAÇÃO SQL INJECTION (bypass)



A aplicação da técnica SQLi pode ser realizada manualmente ou por meio de softwares.

Vamos ver os dois conceitos.

O primeiro passo é identificar se EXISTE a vulnerabilidade SQLi no sistema alvo. orque isso pode não existir, desde que o pessoal siga as boas praticas e faça bom uso do conhecimento.


3.1. SQLi DE FORMA MANUAL





3.1. IDENTIFICANDO VULNERABILIDADE DIRETAMENTE NA URL





Para identificarmos se uma URL esta ou não vulnerável à SQLi, inserimos na URL o parâmetro OR 1=1.







&nbsp;Ao inserir no parâmetro or 1=1, para este caso, todo o conteúdo da tabela é informado.

Veja que, ao ser informado o parâmetro na URL é feito uma busca no banco de dados por meio de uma consulta SQL.

Desta forma o id=8, neste caso não existe. O parâmetro or 1=1 vem a dizer que se o primeiro parametro não existir ou se existe é consulta deverá retornar uma informação válida. Assim, todo o conteúdo é retornado.

Este conceito é mesmo para parâmetros que não são variáveis inteiras. Como exemplo, inclua a coluna 'categoria' do tipo TEXT na tabela Post:







&nbsp;Dê dois cliques na tabela e insira os dados como:

&nbsp;



&nbsp;Insira no código a linha:

&nbsp;



Agora vá na sua URL e insira o parâmetro cat='primeiro' or 1=1










Ou um parâmetro nulo ou que não exista na tabela:







Concluímos que a página esta vulnerável ao SQLi.
Alguns retornos, dependendo do desenvolvedor (e os mais comuns) são com erros de retornos do Mysql onde, provavelmente, o desenvolvedor utilizou um TRY CATCH com EXCEMPTION do MYSQL. 

Outro conceito para esta técnica é o Blind SQLi que em outro hora veremos.



O mais temido de todos esta logo abaixo, no item 3.2.





3.2. IDENTIFICANDO VULNERABILIDADE EM CREDENCIAIS



Insira as linhas de código na index.php:





Inserimos um formulário onde o action é enviado para a mesma página. Se o $_Post do envio existir, faremos uma busca pelo usuário e senha no banco de dados. Caso encontrado, retornará boas vindas. Caso não, será enviado um erro.






Para você visualizar o campo pwd (senha), basta inserir o type como text.








Note que no banco de dados inserimos uma flag do tipo varchar (string) com 255 caracteres. Ou seja, é um campo de texto, o armazenamento é por string pois as senhas podem conter diversos caracteres.

Nas entradas dos valores por parâmetro or 1=1 pode variar de inteiro para string.

Neste contexto, considere a possibilidade o nome de algum usuario (por padrão) seja admin (como acontece na maioria das vezes) insira os campos " or "1"="1 em senha e veja o que vai acontecer:







Sim, você estará logado como administrador.



Mesmo se não soubermos o nome de algum usuário, faça o teste:







Vamos visualizar por níveis, para você entender melhor.



Adicione o campo level na tabela user. Adicione outro usuário e dê leveis diferentes a eles:







&nbsp; 

Na classe cDBO, acrescente o método de busca por campo. O anterior retorna um array, por isso trabalharmos com print_r e var_dump. Agora vc irá retornar apenas um campo, este caso o level da credencial que estará logando no sistema.













Agora, adicione o level na index.php.:











Agora teste os usuários e visualize o level:


























Agora teste com o parâmetro " or "1"="1.&nbsp;









E agora? Você entendeu o conteúdo? Consegue explicar agora o que esta acontecendo?



A consulta SQL é trabalhada de tal forma que tanto o nome de usuário quanto a senha não são validados.

Note que conseguimos entrar no sistema sem ser necessário entrar (diretamente) com o usuario cadastrado 9admin ou usuário), mas utilizamos um conceito (digamos boleano) o qual foi possível obter a entrada no sistema no sistema.

Outras possibilidades, sem a necessidade de entrar em conceito são as opções default, como admin admin vc ja esta no sistema. O que geralmente acontece, AINDA, em muitos deles.

Em outros ataques, como o brutal force, por exemplo, as credenciais iniciais do dicionário de palavras sempre correspondem a default como admin admin, admin root, root toor, etc. São senhas padrões que por boas praticas em segurança, incluindo controles que podem ser implementados nas desenvolvedoras, devem ser trocadas. Como exemplo muito comum, é a senha default dos roteadores. Basta uma pesquisa no fabricante para obter a senha padrão de login no rádio. E muitos deles os usuários não mudam.






Vamos testar com o campo senha criptografado.

Entre neste site http://www.agenciamestre.com/ferramentas-seo/md5/ e escolha root como senha para ser criptografada. 



Obs: Existem outras criptografias além do md5. Há artigos que dizem que é possível obter uma assinatura em md5 de um arquivo. Alterar este arquivo e gerar a mesma assinatura. Ou seja, alterar o documento e manter sua assinatura. Ao encriptar este arquivo em md5 irá criar uma chave de caracteres. Logicamente, se vc alterar o texto do arquivo, inserindo ou retirando palavras, esta chave irá mudar. Contudo, inserindo 1bity ao arquivo, é possível gerar a mesma chave e conseguir alterar o documento com a manter&nbsp; mesma assinatura. Bom, este é outro assunto.











Copie e cole a chave na flag password da tabela user:











Logicamente, você terá de adicionar uma linha para encriptar em md5 todo volume que entrar pelo campo pwd:







Na url faça um teste, entre com a credencial correta: admin/root. A mensagem deverá ser de boas vindas.









Tratarmos apenas o campo senha. Usuário não criptografamos. Veja:







Desta forma é possível inibir o conceito tratando, neste caso, as credenciais. Porém ainda é possível quebrar (hack) a senha com brutal force (Hydra). Mas este caso foge do escopo do SQLi.



Ainda não tratamos diretamente as entradas de dados dos campos, o que fizemos foi criptografar a senha. Códigos podem ser inseridos nos campos, não tratamos isso. Dependendo da aplicação outra vulnerabilidade pode ser explorada chamada XSS (cross site scripting). E isso também foge do escopo. 

Em sua maioria, os frameworks ja abordam validações muito eficientes, vc não precisa ficar criando classe para validações, de conexões etc. Infelizmente, nas faculdades estão ainda ENSINANDO sem frameworks. Oh pessoal acordem! O mundo real é outro. Podem começar a dar AULAS COM FRAMEWORKS nas AULAS DE DESENVOLVIMENTO WEB.



Até aqui vimos apenas um teste de como podemos verificar manualmente a vulnerabilidade presente em URL e credenciais. Falar sobre SQLi é muito extenso, há diversas possibilidades de trabalhar com a tecnica numa simples URL vulnerável e se você realmente não entender o conceito, vai ficar difícil principalmente quando for necessário inserir dados hexadecimais nas querys para quebrar (hack) o IPS (risos).

Podemos ainda criar Querys capazes de criar usuários remotos nos servidores, obter arquivos nos servidores (seja ele qual for), instalarmos aplicativos ou seja lá o que for, etc. Sobre isso fizemos uma prova&nbsp; para final de curso em Forense, foi bem legal. O alvo era a máquina do professor e tinhamos que quebrar a senha de usuário no sistema, inserir uma credencial remota no servidor, acessar o serviço por área remota (windows), criarmos um arquivo no servidor e fazermos upload deste arquivo com SQLi, ops, foi LRF. (O.O). Parece complicado, mas quando vc entende o processo fica fácil. A maioria do pessoal usa isso para fazer defacement, eu ja não vejo muita graça nisso.

Bom, ainda veremos muito mais. Não tudo, o necessário para vc apenas entender. O resto é só estudar ou melhor entrar no time de pesquisadores em segurança da informação. Estou falando de eventos importantes na área como a DEFCON, BLACKHAT,&nbsp; H2HC, etc.



Para terminar este tópico, fique de olho neste arquivo:







A maioria dos Script Kids são pegos por este arquivo. 
São os rastros que deixam os usuários sem conhecimento do que a ferramenta faz.

É o primeiro passo para um perito iniciar as investigações SOBRE O ATAQUE e identificar o atacante.
Contudo com o marco civil (só no BRASIL) e&nbsp; o andamento lento dos processos, esse log tb é perdido com o tempo, que segundo a lei, são 6 meses.
Bom, depois agente fala sobre isso


---XXX---


4. EXPLORANDO VULNERABILIDADES SQLi COM KALI