Module: Msf::Auxiliary::PasswordCracker

Includes:
Report
Defined in:
lib/msf/core/auxiliary/password_cracker.rb

Overview

This module provides methods for working with a Password Cracker

Instance Method Summary collapse

Methods included from Report

#active_db?, #create_cracked_credential, #create_credential, #create_credential_and_login, #create_credential_login, #db, #db_warning_given?, #get_client, #get_host, #inside_workspace_boundary?, #invalidate_login, #mytask, #myworkspace, #myworkspace_id, #report_auth_info, #report_client, #report_exploit, #report_host, #report_loot, #report_note, #report_service, #report_vuln, #report_web_form, #report_web_page, #report_web_site, #report_web_vuln, #store_cred, #store_local, #store_loot

Methods included from Metasploit::Framework::Require

optionally, optionally_active_record_railtie, optionally_include_metasploit_credential_creation, #optionally_include_metasploit_credential_creation, optionally_require_metasploit_db_gem_engines

Instance Method Details

#already_cracked_pass(hash) ⇒ Object


123
124
125
126
127
128
129
130
131
132
# File 'lib/msf/core/auxiliary/password_cracker.rb', line 123

def already_cracked_pass(hash)
  framework.db.creds({:pass => hash}).each do |test_cred|
    test_cred.public.cores.each do |core|
      if core.origin_type == "Metasploit::Credential::Origin::CrackedPassword"
        return core.private.data
      end
    end
  end
  nil
end

#initialize(info = {}) ⇒ Object

Initializes an instance of an auxiliary module that calls out to John the Ripper (jtr)


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
# File 'lib/msf/core/auxiliary/password_cracker.rb', line 24

def initialize(info = {})
  super

  register_options(
    [
      OptPath.new('CONFIG',               [false, 'The path to a John config file to use instead of the default']),
      OptPath.new('CUSTOM_WORDLIST',      [false, 'The path to an optional custom wordlist']),
      OptInt.new('ITERATION_TIMEOUT',     [false, 'The max-run-time for each iteration of cracking']),
      OptPath.new('CRACKER_PATH',         [false, 'The absolute path to the cracker executable']),
      OptInt.new('FORK',                  [false, 'Forks for John the Ripper to use',1]),
      OptBool.new('KORELOGIC',            [false, 'Apply the KoreLogic rules to John the Ripper Wordlist Mode(slower)', false]),
      OptBool.new('MUTATE',               [false, 'Apply common mutations to the Wordlist (SLOW)', false]),
      OptPath.new('POT',                  [false, 'The path to a John POT file to use instead of the default']),
      OptBool.new('USE_CREDS',            [false, 'Use existing credential data saved in the database', true]),
      OptBool.new('USE_DB_INFO',          [false, 'Use looted database schema info to seed the wordlist', true]),
      OptBool.new('USE_DEFAULT_WORDLIST', [false, 'Use the default metasploit wordlist', true]),
      OptBool.new('USE_HOSTNAMES',        [false, 'Seed the wordlist with hostnames from the workspace', true]),
      OptBool.new('USE_ROOT_WORDS',       [false, 'Use the Common Root Words Wordlist', true])
    ], Msf::Auxiliary::PasswordCracker
  )

  register_advanced_options(
    [
      OptBool.new('DeleteTempFiles',    [false, 'Delete temporary wordlist and hash files', true]),
      OptBool.new('OptimizeKernel',     [false, 'Utilize Optimized Kernels in Hashcat', true]),
      OptBool.new('ShowCommand',        [false, 'Print the cracker command being used', true]),
    ], Msf::Auxiliary::PasswordCracker
  )
end

#john_lm_upper_to_ntlm(pwd, hash) ⇒ String?

Parameters:

  • pwd (String)

    Password recovered from cracking an LM hash

  • hash (String)

    NTLM hash for this password

Returns:

  • (String)

    `pwd` converted to the correct case to match the given NTLM hash

  • (nil)

    if no case matches the NT hash. This can happen when `pwd` came from a john run that only cracked half of the LM hash


60
61
62
63
64
65
66
67
68
69
# File 'lib/msf/core/auxiliary/password_cracker.rb', line 60

def john_lm_upper_to_ntlm(pwd, hash)
  pwd  = pwd.upcase
  hash = hash.upcase
  Rex::Text.permute_case(pwd).each do |str|
    if hash == Rex::Proto::NTLM::Crypt.ntlm_hash(str).unpack("H*")[0].upcase
      return str
    end
  end
  nil
end

#new_password_cracker(cracking_application) ⇒ nilClass, Metasploit::Framework::PasswordCracker::Cracker

This method creates a new Metasploit::Framework::PasswordCracker::Cracker and populates some of the attributes based on the module datastore options.

Returns:


77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
# File 'lib/msf/core/auxiliary/password_cracker.rb', line 77

def new_password_cracker(cracking_application)
  fail_with(Msf::Module::Failure::BadConfig, "Password cracking is not available without an active database connection.") unless framework.db.active
  cracker = Metasploit::Framework::PasswordCracker::Cracker.new(
      config: datastore['CONFIG'],
      cracker_path: datastore['CRACKER_PATH'],
      max_runtime: datastore['ITERATION_TIMEOUT'],
      pot: datastore['POT'],
      optimize: datastore['OptimizeKernel'],
      wordlist: datastore['CUSTOM_WORDLIST']
  )
  cracker.cracker = cracking_application
  begin
    cracker.binary_path
  rescue Metasploit::Framework::PasswordCracker::PasswordCrackerNotFoundError => e
    fail_with(Msf::Module::Failure::BadConfig, e.message)
  end
  # throw this to a local variable since it causes a shell out to pull the version
  cracker_version = cracker.cracker_version
  if cracker.cracker == 'john' && (cracker_version.nil? || !cracker_version.include?('jumbo'))
    fail_with(Msf::Module::Failure::BadConfig, 'John the Ripper JUMBO patch version required.  See https://github.com/magnumripper/JohnTheRipper')
  end
  print_good("#{cracker.cracker} Version Detected: #{cracker_version}")
  cracker
end

#wordlist_file(max_len = 0) ⇒ nilClass, Rex::Quickfile

This method instantiates a Metasploit::Framework::JtR::Wordlist, writes the data out to a file and returns the Rex::Quickfile object.

Parameters:

  • max_len (Integer) (defaults to: 0)

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

Returns:

  • (nilClass)

    if there is no active framework db connection

  • (Rex::Quickfile)

    if it successfully wrote the wordlist to a file


108
109
110
111
112
113
114
115
116
117
118
119
120
121
# File 'lib/msf/core/auxiliary/password_cracker.rb', line 108

def wordlist_file(max_len = 0)
  return nil unless framework.db.active
  wordlist = Metasploit::Framework::PasswordCracker::Wordlist.new(
      custom_wordlist: datastore['CUSTOM_WORDLIST'],
      mutate: datastore['MUTATE'],
      use_creds: datastore['USE_CREDS'],
      use_db_info: datastore['USE_DB_INFO'],
      use_default_wordlist: datastore['USE_DEFAULT_WORDLIST'],
      use_hostnames: datastore['USE_HOSTNAMES'],
      use_common_root: datastore['USE_ROOT_WORDS'],
      workspace: myworkspace
  )
  wordlist.to_file(max_len)
end