Class: Metasploit::Framework::PasswordCracker::Wordlist

Inherits:
Object
  • Object
show all
Includes:
ActiveModel::Validations
Defined in:
lib/metasploit/framework/password_crackers/wordlist.rb

Constant Summary collapse

MUTATIONS =

A mapping of the mutation substitution rules

{
    '@' => 'a',
    '0' => 'o',
    '3' => 'e',
    '$' => 's',
    '7' => 't',
    '1' => 'l',
    '5' => 's'
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}) ⇒ Wordlist

Returns a new instance of Wordlist.

Parameters:

  • attributes (Hash{Symbol => String,nil}) (defaults to: {})


92
93
94
95
96
97
98
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 92

def initialize(attributes={})
  attributes.each do |attribute, value|
    public_send("#{attribute}=", value)
  end
  @appenders  ||= []
  @prependers ||= []
end

Instance Attribute Details

#appendersArray

Returns an array of strings to append to each word.

Returns:

  • (Array)

    an array of strings to append to each word



23
24
25
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 23

def appenders
  @appenders
end

#custom_wordlistString

Returns the path to a custom wordlist file to include.

Returns:

  • (String)

    the path to a custom wordlist file to include



27
28
29
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 27

def custom_wordlist
  @custom_wordlist
end

#mutateTrueClass, FalseClass

Returns:

  • (TrueClass)

    if you want each word mutated as it is added

  • (FalseClass)

    if you do not want each word mutated



32
33
34
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 32

def mutate
  @mutate
end

#prependersArray

Returns an array of strings to prepend to each word.

Returns:

  • (Array)

    an array of strings to prepend to each word



36
37
38
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 36

def prependers
  @prependers
end

#use_common_rootTrueClass, FalseClass

Returns:

  • (TrueClass)

    if you want to use the common root words wordlist

  • (FalseClass)

    if you do not want to use the common root words wordlist



41
42
43
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 41

def use_common_root
  @use_common_root
end

#use_credsTrueClass, FalseClass

Returns:

  • (TrueClass)

    if you want to seed the wordlist with existing credential data from the database

  • (FalseClass)

    if you do not want to seed the wordlist with existing credential data from the database



46
47
48
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 46

def use_creds
  @use_creds
end

#use_db_infoTrueClass, FalseClass

Returns:

  • (TrueClass)

    if you want to seed the wordlist with looted database names and schemas

  • (FalseClass)

    if you do not want to seed the wordlist with looted database names and schemas



51
52
53
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 51

def use_db_info
  @use_db_info
end

#use_default_wordlistTrueClass, FalseClass

Returns:

  • (TrueClass)

    if you want to use the default wordlist

  • (FalseClass)

    if you do not want to use the default wordlist



56
57
58
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 56

def use_default_wordlist
  @use_default_wordlist
end

#use_hostnamesTrueClass, FalseClass

Returns:

  • (TrueClass)

    if you want to seed the wordlist with existing hostnames from the database

  • (FalseClass)

    if you do not want to seed the wordlist with existing hostnames from the database



61
62
63
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 61

def use_hostnames
  @use_hostnames
end

#workspaceMdm::Workspace

Returns the workspace this cracker is for.

Returns:

  • (Mdm::Workspace)

    the workspace this cracker is for.



65
66
67
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 65

def workspace
  @workspace
end

Instance Method Details

#each_appended_word(word = '') {|word| ... } ⇒ void

This method returns an undefined value.

This method takes a word, and appends each word from the appenders list and yields the new words.

Yield Parameters:

  • word (String)

    the expanded word



105
106
107
108
109
110
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 105

def each_appended_word(word='')
  yield word
  appenders.each do |suffix|
    yield "#{word}#{suffix}"
  end
end

#each_base_word {|word| ... } ⇒ void

This method returns an undefined value.

This method checks all the attributes set on the object and calls the appropriate enumerators for each option and yields the results back up the call-chain.

Yield Parameters:

  • word (String)

    the expanded word



118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 118

def each_base_word
  # Make sure are attributes are all valid first!
  valid!

  # Yield the expanded form of each line of the custom wordlist if one was given
  if custom_wordlist.present?
    each_custom_word do |word|
      yield word unless word.blank?
    end
  end

  # Yield each word from the common root words list if it was selected
  if use_common_root
    each_root_word do |word|
      yield word unless word.blank?
    end
  end

  # If the user has selected use_creds we yield each password, username, and realm name
  # that currently exists in the database.
  if use_creds
    each_cred_word do |word|
      yield word unless word.blank?
    end
  end

  if use_db_info
    each_database_word do |word|
      yield word unless word.blank?
    end
  end

  if use_default_wordlist
    each_default_word do |word|
      yield word unless word.blank?
    end
  end

  if use_hostnames
    each_hostname_word do |word|
      yield word unless word.blank?
    end
  end

end

#each_cred_word {|word| ... } ⇒ void

This method returns an undefined value.

This method searches all saved Credentials in the database and yields all passwords, usernames, and realm names it finds.

Yield Parameters:

  • word (String)

    the expanded word



169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 169

def each_cred_word
  # We don't want all Private types here. Only Passwords make sense for inclusion in the wordlist.
  Metasploit::Credential::Password.all.each do |password|
    yield password.data
  end

  Metasploit::Credential::Public.all.each do |public|
    yield public.username
  end

  Metasploit::Credential::Realm.all.each do |realm|
    yield realm.value
  end
end

#each_custom_word {|word| ... } ⇒ void

This method returns an undefined value.

This method reads the file provided as custom_wordlist and yields the expanded form of each word in the list.

Yield Parameters:

  • word (String)

    the expanded word, and the word itself



189
190
191
192
193
194
195
196
197
198
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 189

def each_custom_word
  ::File.open(custom_wordlist, "rb") do |fd|
    fd.each_line do |line|
      yield line.chomp
      expanded_words(line) do |word|
        yield word unless line.chomp == word
      end
    end
  end
end

#each_database_word {|word| ... } ⇒ void

This method returns an undefined value.

This method searches the notes in the current workspace for DB instance names, database names, table names, and column names gathered from live database servers. It yields each one that it finds.

Yield Parameters:

  • word (String)

    the expanded word



207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 207

def each_database_word
  # Yield database, table and column names from any looted database schemas
  workspace.notes.where('ntype like ?', '%.schema%').each do |note|
    expanded_words(note.data['DBName']) do |word|
      yield word
    end

    note.data['Tables'].each do |table|
      expanded_words(table['TableName']) do |word|
        yield word
      end

      table['Columns'].each do |column|
        expanded_words(column['ColumnName']) do |word|
          yield word
        end
      end
    end
  end

  # Yield any capture MSSQL Instance names
  workspace.notes.where(['ntype=?', 'mssql.instancename']).each do |note|
    expanded_words(note.data['InstanceName']) do |word|
      yield word
    end
  end
end

#each_default_word {|word| ... } ⇒ void

This method returns an undefined value.

This method yields expanded words taken from the default john wordlist that we ship in the data directory.

Yield Parameters:

  • word (String)

    the expanded word



240
241
242
243
244
245
246
247
248
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 240

def each_default_word
  ::File.open(default_wordlist_path, "rb") do |fd|
    fd.each_line do |line|
      expanded_words(line) do |word|
        yield word
      end
    end
  end
end

#each_hostname_word {|word| ... } ⇒ void

This method returns an undefined value.

This method yields the expanded words out of all the hostnames found in the current workspace.

Yield Parameters:

  • word (String)

    the expanded word



255
256
257
258
259
260
261
262
263
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 255

def each_hostname_word
  workspace.hosts.all.each do |host|
    unless host.name.nil?
      expanded_words(host.name) do |word|
        yield nil
      end
    end
  end
end

#each_mutated_word(word = '') {|word| ... } ⇒ void

This method returns an undefined value.

This method checks to see if the user asked for mutations. If mutations have been enabled, then it creates all the unique mutations and yields each result.

Yield Parameters:

  • word (String)

    the expanded word



271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 271

def each_mutated_word(word='')
  mutants = [ ]

  # Run the mutations only if the option is set
  if mutate
    mutants = mutants + mutate_word(word)
  end

  mutants << word
  mutants.uniq.each do |mutant|
    yield mutant
  end
end

#each_prepended_word(word = '') {|word| ... } ⇒ void

This method returns an undefined value.

This method takes a word, and prepends each word from the prependers list and yields the new words.

Yield Parameters:

  • word (String)

    the expanded word



290
291
292
293
294
295
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 290

def each_prepended_word(word='')
  yield word
  prependers.each do |prefix|
    yield "#{prefix}#{word}"
  end
end

#each_root_word {|word| ... } ⇒ void

This method returns an undefined value.

This method reads the common_roots.txt wordlist expands any words in the list and yields them.

Yield Parameters:

  • word (String)

    the expanded word



302
303
304
305
306
307
308
309
310
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 302

def each_root_word
  ::File.open(common_root_words_path, "rb") do |fd|
    fd.each_line do |line|
      expanded_words(line) do |word|
        yield word
      end
    end
  end
end

#each_word {|word| ... } ⇒ void

This method returns an undefined value.

This method wraps around all the other enumerators. It processes all of the options and yields each word generated by the options selected.

Yield Parameters:

  • word (String)

    the word to write out to the wordlist file



318
319
320
321
322
323
324
325
326
327
328
329
330
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 318

def each_word
  each_base_word do |base_word|
    each_mutated_word(base_word) do |mutant|
      each_prepended_word(mutant) do |prepended|
        yield prepended
      end

      each_appended_word(mutant) do |appended|
        yield appended
      end
    end
  end
end

#expanded_words(word = '') {|expanded| ... } ⇒ void

This method returns an undefined value.

This method takes a string and splits it on non-word characters and the underscore. It does this to find likely distinct words in the string. It then yields each ‘word’ found this way.

Parameters:

  • word (String) (defaults to: '')

    the string to split apart

Yield Parameters:

  • expanded (String)

    the expanded words



339
340
341
342
343
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 339

def expanded_words(word='')
  word.split(/[\W_]+/).each do |expanded|
    yield expanded
  end
end

#mutate_word(word) ⇒ Array<String>

This method takes a word and applies various mutation rules to that word and returns an array of all the mutated forms.

Parameters:

  • word (String)

    the word to apply the mutations to

Returns:

  • (Array<String>)

    An array containing all the mutated forms of the word



350
351
352
353
354
355
356
357
358
359
360
361
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 350

def mutate_word(word)
  results = []
  # Iterate through combinations to create each possible mutation
  mutation_keys.each do |iteration|
    next if iteration.flatten.empty?
    intermediate = word.dup
    subsititutions = iteration.collect { |key| MUTATIONS[key] }
    intermediate.tr!(subsititutions.join, iteration.join)
    results << intermediate
  end
  results.flatten.uniq
end

#mutation_keysArray<Array>

A getter for a memoized version fo the mutation keys list

Returns:

  • (Array<Array>)

    a 2D array of all mutation combinations



366
367
368
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 366

def mutation_keys
  @mutation_keys ||= generate_mutation_keys
end

#to_file(max_len = 0) ⇒ Rex::Quickfile

This method takes all the options provided and streams the generated wordlist out to a Rex::Quickfile and returns the Rex::Quickfile.

Parameters:

  • max_len (Integer) (defaults to: 0)

    max length of a word in the wordlist, 0 default for ignored value

Returns:

  • (Rex::Quickfile)

    The Rex::Quickfile object that the wordlist has been written to



375
376
377
378
379
380
381
382
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 375

def to_file(max_len = 0)
  valid!
  wordlist_file = Rex::Quickfile.new("jtrtmp")
  each_word do |word|
    wordlist_file.puts max_len == 0 ? word : word[0...max_len]
  end
  wordlist_file
end

#valid!void

This method returns an undefined value.

Raise an exception if the attributes are not valid.

Raises:

  • (Invalid)

    if the attributes are not valid on this scanner



388
389
390
391
392
393
# File 'lib/metasploit/framework/password_crackers/wordlist.rb', line 388

def valid!
  unless valid?
    raise Metasploit::Framework::PasswordCracker::InvalidWordlist.new(self)
  end
  nil
end