Module: WpUser::BruteForcable
- Included in:
- WpUser
- Defined in:
- lib/common/models/wp_user/brute_forcable.rb
Class Method Summary (collapse)
-
+ (Array<String>) passwords_from_wordlist(wordlist)
Load the passwords from the wordlist, which can be a file path or an array or passwords.
Instance Method Summary (collapse)
-
- (void) brute_force(wordlist, options = {}, redirect_url = nil)
Brute force the user with the wordlist supplied.
- - (Typhoeus::Request) login_request(password, redirect_url)
-
- (ProgressBar) progress_bar(passwords_size, options)
:nocov:.
- - (Boolean) valid_password?(response, password, redirect_url, options = {})
Class Method Details
+ (Array<String>) passwords_from_wordlist(wordlist)
Load the passwords from the wordlist, which can be a file path or an array or passwords
File comments are ignored, but will miss passwords if they start with a hash...
134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'lib/common/models/wp_user/brute_forcable.rb', line 134 def self.passwords_from_wordlist(wordlist) if wordlist.is_a?(String) passwords = [] charset = File.charset(wordlist).upcase opt = "r:#{charset}" # To remove warning when charset = UTF-8 # Ignoring internal encoding UTF-8: it is identical to external encoding utf-8 opt += ':UTF-8' if charset != 'UTF-8' File.open(wordlist, opt).each do |line| next if line[0,1] == '#' passwords << line.strip end elsif wordlist.is_a?(Array) passwords = wordlist else raise 'Invalid wordlist, expected String or Array' end passwords end |
Instance Method Details
- (void) brute_force(wordlist, options = {}, redirect_url = nil)
This method returns an undefined value.
Brute force the user with the wordlist supplied
It can take a long time to queue 2 million requests, for that reason, we queue browser.max_threads, send browser.max_threads, queue browser.max_threads and so on.
hydra.run only returns when it has recieved all of its, responses. This means that while we are waiting for browser.max_threads, responses, we are waiting...
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/common/models/wp_user/brute_forcable.rb', line 23 def brute_force(wordlist, = {}, redirect_url = nil) browser = Browser.instance hydra = browser.hydra passwords = BruteForcable.passwords_from_wordlist(wordlist) queue_count = 0 found = false = self.(passwords.size, ) passwords.each do |password| # A successfull login will redirect us to the redirect_to parameter # Generate a random one on each request unless redirect_url random = (0...8).map { 65.+(rand(26)).chr }.join redirect_url = "#@uri#{random}/" end request = login_request(password, redirect_url) request.on_complete do |response| .progress += 1 if [:show_progression] && !found puts "\n Trying Username : #{login} Password : #{password}" if [:verbose] if valid_password?(response, password, redirect_url, ) found = true self.password = password return end end hydra.queue(request) queue_count += 1 if queue_count >= browser.max_threads hydra.run queue_count = 0 puts "Sent #{browser.max_threads} requests ..." if [:verbose] end end # run all of the remaining requests hydra.run end |
- (Typhoeus::Request) login_request(password, redirect_url)
87 88 89 90 91 92 93 |
# File 'lib/common/models/wp_user/brute_forcable.rb', line 87 def login_request(password, redirect_url) Browser.instance.forge_request(login_url, method: :post, body: { log: login, pwd: password, redirect_to: redirect_url }, cache_ttl: 0 ) end |
- (ProgressBar) progress_bar(passwords_size, options)
:nocov:
72 73 74 75 76 77 78 79 80 |
# File 'lib/common/models/wp_user/brute_forcable.rb', line 72 def (passwords_size, ) if [:show_progression] ProgressBar.create( format: '%t %a <%B> (%c / %C) %P%% %e', title: " Brute Forcing '#{login}'", total: passwords_size ) end end |
- (Boolean) valid_password?(response, password, redirect_url, options = {})
103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/common/models/wp_user/brute_forcable.rb', line 103 def valid_password?(response, password, redirect_url, = {}) if response.code == 302 && response.headers_hash && response.headers_hash['Location'] == redirect_url progression = "#{green('[SUCCESS]')} Login : #{login} Password : #{password}\n\n" valid = true elsif response.body =~ /login_error/i verbose = "\n Incorrect login and/or password." elsif response.timed_out? progression = "#{red('ERROR:')} Request timed out." elsif response.code == 0 progression = "#{red('ERROR:')} No response from remote server. WAF/IPS?" elsif response.code.to_s =~ /^50/ progression = "#{red('ERROR:')} Server error, try reducing the number of threads." else progression = "#{red('ERROR:')} We received an unknown response for #{password}..." verbose = red(" Code: #{response.code}\n Body: #{response.body}\n") end puts "\n " + progression if progression && [:show_progression] puts verbose if verbose && [:verbose] valid || false end |