Automatizando o Brute Force com Python
- Francisco Junior
- Programação , Segurança da informação
- 14 de abril de 2021
Sempre imaginou como ferramentas de brute force funcionam, ou sempre quis montar sua ferramenta, mas nunca soube por onde começar? Aprenda agora na Iron Linux, como fazer um simples programa de força bruta para adivinhar usuário e senha utilizando um dicionário.
Não preciso nem dizer que o conteúdo de hoje, tem fins didáticos, e não nos responsabilizamos por usos inadequados do código.
O código utilizado neste tutorial pode ser encontrado no final deste post.
O que é brute-force?
O brute force, ou ataque de força bruta, segundo a criptografia, é um ataque critoanalítico, cujo objetivo é descobrir uma chave que se encontra escondida, ou fora de nosso conhecimento. Resumindo, o ataque de força bruta, utiliza de combinações alfa-numéricas para descobrir senhas, chaves criptografadas ou dados encodados.
No assunto de ataque de força bruta, podemos utilizar 2 categorias de ataque para descobrir uma senha, sendo eles:
- Ataque de força bruta - Onde o computador vai tentar bit por bit para achar o dado correto em que desejamos encontrar. Geralmente esses ataques são bastantes assertivos, porém costumam demorar muito tempo, a depender da configuração do computador.
- Ataque de Dicionário - Onde um computador vai testar palavras em um dicionário para encontrar o dado correto. As buscas em dicionários podem vir a ser falho, já que a senha ou dado pode não estar no dicionário. O tempo para achar uma chave, pode depender de dois fatores, do tamanho do dicionário e também da configuração do computador.
Para o tutorial de hoje, utilizaremos um ataque de dicionário com uma lista previamente montada, utilizando o programa Cupp.
Entendendo a Aplicação
Para realizar a sua ferramenta de brute force, primeiramente é necessário entender como a aplicação que você vai querer realizar o ataque de força bruta funciona.
O sistema utilizado é o Hack_Me, uma aplicação vulnerável, que eu desenvolvi para a faculdade. Ela se encontra no meu Github. Vou assumir que vocês já saibam subir uma aplicação no seu computador e vamos para o que importa. Descobrir qual a senha de algum usuário.
Primeiro, mesmo sem sabermos, vamos simular uma tentativa de login. O importante desse passo é entender que categoria de protocolo HTTP a aplicação está utilizando para enviar a informação para o servidor. E quais são os parâmetros passados, para assim então simular um envio.
Para isso, podemos abrir as opções de desenvolvedor do navegador que você está utilizando e ir na aba network antes de fazer o login. Após ter concluído o passo anterior, vamos clicar em Login, para vermos os dados da requisição.
Podemos ver pela imagem abaixo algumas informações importantes dos dados enviados, que sempre é importante olhar para entender a requisição.
Pontos a se olhar:
- Request URL: É responsável pelo endpoint, o local para onde a informação irá ser enviada. Neste caso, podemos ver que o servidor recebe essa informação no “/api/Login.php”
- Request Method: É responsável por padronizar a forma que os dados vão ser transmitidos para o servidor. Observando a requisição, vemos que ele utiliza o método POST. Caso queiram se aprofundar mais nos tipos de requisições HTTP, vou deixar um link para darem uma lida sobre o assunto.
- Status Code: É responsável para retornar para o navegador o resultado da requisição. Nesse caso, recebemos como resposta um 302. Significa que foi encontrado a informação e receberemos um redirecionamento. Em outros termos, achamos o login correto.
E por último, e mais importante, temos que entender como os parâmetros são passados. Nesse caso, pode ser utilizado um bom e velho JSON. Passando por parâmetro o nome e senha.
Gerando um dicionário customizado
Para este tutorial, utilizei o CUPP (Common User Passwords Profiler), para gerar a nossa lista customizada. Outra ferramenta muito boa para geração de dicionários customizados, pode ser utilizado o Cewl. Para instalação dele é bem simples, apenas use:
sudo apt install cupp
Após instalação, é necessário rodar o comando:
sudo cupp -i
Ele irá gerar uma interface igual a abaixo, na qual basta somente completar com as informações que você deseja.
Para este caso, utilizei o primeiro e ultimo campo apenas, colocando informações de First Name e outra palavras.
No final, ele vai gerar uma lista chamada “junior.txt”, onde iremos utilizar no nosso script de python.
Escrevendo nosso script de brute force
O primeiro passo é criar um arquivo python chamado, brute-force.py, na qual nele iremos escrever nosso brute force. A primeira coisa que devemos fazer é importar a biblioteca requests, responsável por fazer as requisições HTTP dentro de nosso código.
Você pode instalar a biblioteca no seu computador caso não tenha, utilizando o comando:
sudo pip install requests
import requests
url = "http://localhost/Hack_Me"
login_url = url+"/api/Login.php"
arquivo = "junior.txt"
usuario = "junior"
Agora que temos instalado a biblioteca para fazer a requisição, vamos setar algumas constantes que iremos utilizar durante a nossa aplicação.
- url : Responsável por apontar o local para onde a requisição irá. Basicamente, podemos trocar a variável url, para apontar para um dominio.
- login_url : Responsável por juntar o domínio que vamos tentar o brute force, e o endpoint do servidor, onde ele irá receber a informação.
- arquivo : Colocamos nessa variável o caminho do arquivo que foi gerado com o CUPP anteriormente, basicamente a nossa lista de dicionário que criamos. Esse valor pode ser alterado por qualquer outra wordlist.
- usuario : Nesse tutorial, vamos supor que já sabemos qual é o usuário de login. Ele pode ser alterado pelo seu usuário.
def request(user, password):
data = {"nome": user, "senha": password}
r = requests.post(login_url, data=data)
if "Logue novamente" in r.text:
print("Nao foi possivel achar a senha!!")
else:
print("A senha e: "+user + " | "+ password)
Para podermos fazer a requisição, simulando a página de login do site, vamos realizar um método chamado request, que recebemos como parâmetro o usuário e a senha.
Na primeira linha, construímos nossos dados que vamos enviar ao servidor. Lembra aquela hora que visualizamos na aba network quais os dados eram passados para o servidor, essa é a hora que devemos utilizar.
Então basicamente, a nossa variável data recebe o objeto JSON com o parâmetro nome recebendo o nosso user passado junto do método, e recebe o parâmetro senha recebendo a variável password passado no momento que chamamos o método.
Após isso, colocamos que nossa variável r irá receber a resposta da requisição POST, que passamos o endpoint, aonde o servidor irá receber a requisição e processará a informação que passamos na variável data.
E por último temos a nossa condição para verificar se a senha foi achada de fato ou não.
Podemos analisar no primeiro passo, que quando não conseguimos locar, a nossa tela retorna “Logue Novamente”, na qual podemos perceber que isso ocorre quando não conseguimos logar.
Então basicamente, nessa estrutura de condição, verificamos se temos essa String em nossa resposta da requisição, e caso tenhamos, sabemos que não é o usuário e senha correta.
wordlist = open(arquivo, "r")
for i in wordlist:
print("Testando "+ usuario + " || " + i)
request(usuario,i)
print("===============================")
E por último temos a variável wordlist onde recebe o nosso arquivo de dicionário. Onde open recebe por parâmetro o arquivo e “r” que significa read.
Após isso, realizamos uma estrutura de repetição para ler todas as linhas do arquivo. Utilizamos a estrutura for, para ler linha por linha do arquivo e chamar nosso método anteriormente declarado.
E rodando esse script, podemos ver o seguinte resultado.
Conclusão
Podemos fazer com poucas linhas um script para poder realizar brute force em uma aplicação web. O passo mais importante é sempre analisar a aplicação seja utilizando um proxy para interceptar as requisições ou olhando para aba de network nas opções de desenvolvedor de um navegador. O script busca replicar isso de forma dinâmica de acordo com a wordlist, para diminuir o tempo do ataque e testes de possíveis senhas.
Para trabalhos futuros, para melhorar a eficiência do script será acrescentado o modelo de threads.
Links
https://github.com/Hornegam/Python_Pentest/blob/master/BruteForce-Thread/super_simple_brute_force.py
https://github.com/Hornegam/Hack_Me
https://developer.mozilla.org/pt-BR/docs/Web/HTTP
https://github.com/Mebus/cupp
https://github.com/digininja/CeWL
https://www.devmedia.com.br/o-que-e-json/23166