Module: CMSScanner::Finders::Finder::BreadthFirstDictionaryAttack

Defined in:
lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb

Overview

Module to provide an easy way to perform password attacks

Instance Method Summary collapse

Instance Method Details

#attack(users, wordlist_path, opts = {}) {|CMSScanner::User| ... } ⇒ Object

Due to Typhoeus threads shenanigans, in rare cases the progress-bar might be incorrectly updated, hence the ‘rescue ProgressBar::InvalidProgressError’

TODO: Make rubocop happy about metrics etc

rubocop:disable all

Parameters:

Options Hash (opts):

  • :show_progression (Boolean)

Yields:

  • (CMSScanner::User)

    When a valid combination is found



21
22
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
66
67
68
69
70
71
72
73
74
# File 'lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb', line 21

def attack(users, wordlist_path, opts = {})
  wordlist = File.open(wordlist_path)

  create_progress_bar(total: users.size * wordlist.count, show_progression: opts[:show_progression])

  queue_count         = 0
  # Keep the number of requests sent for each users
  # to be able to correctly update the progress when a password is found
  user_requests_count = {}

  users.each { |u| user_requests_count[u.username] = 0 }

  File.foreach(wordlist, chomp: true) do |password|
    remaining_users = users.select { |u| u.password.nil? }

    break if remaining_users.empty?

    remaining_users.each do |user|
      request = (user.username, password)

      user_requests_count[user.username] += 1

      request.on_complete do |res|
        progress_bar.title = "Trying #{user.username} / #{password}"

        progress_bar.increment unless progress_bar.progress == progress_bar.total

        if valid_credentials?(res)
          user.password = password

          begin
            progress_bar.total -= wordlist.count - user_requests_count[user.username]
          rescue ProgressBar::InvalidProgressError
          end

          yield user
        elsif errored_response?(res)
          output_error(res)
        end
      end

      hydra.queue(request)
      queue_count += 1

      if queue_count >= hydra.max_concurrency
        hydra.run
        queue_count = 0
      end
    end
  end

  hydra.run
  progress_bar.stop
end

#errored_response?(response) ⇒ Boolean

Returns Whether or not something wrong happened other than wrong credentials.

Parameters:

Returns:

  • (Boolean)

    Whether or not something wrong happened other than wrong credentials



96
97
98
# File 'lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb', line 96

def errored_response?(response)
  # To Implement in the finder related to the attack
end

#login_request(username, password) ⇒ Typhoeus::Request

param [ String ] password

Parameters:

  • username (String)

Returns:

  • (Typhoeus::Request)


81
82
83
# File 'lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb', line 81

def (username, password)
  # To Implement in the finder related to the attack
end

#valid_credentials?(response) ⇒ Boolean

Returns Whether or not credentials related to the request are valid.

Parameters:

Returns:

  • (Boolean)

    Whether or not credentials related to the request are valid



88
89
90
# File 'lib/cms_scanner/finders/finder/breadth_first_dictionary_attack.rb', line 88

def valid_credentials?(response)
  # To Implement in the finder related to the attack
end