metasploit-framework/lib/msf/core/auxiliary/jtr.rb

101 lines
3.9 KiB
Ruby

# -*- coding: binary -*-
require 'open3'
require 'fileutils'
require 'rex/proto/ntlm/crypt'
require 'metasploit/framework/jtr/cracker'
require 'metasploit/framework/jtr/wordlist'
module Msf
###
#
# This module provides methods for working with John the Ripper
#
###
module Auxiliary::JohnTheRipper
include Msf::Auxiliary::Report
#
# Initializes an instance of an auxiliary module that calls out to John the Ripper (jtr)
#
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_TIMOUT', [false, 'The max-run-time for each iteration of cracking']),
OptPath.new('JOHN_PATH', [false, 'The absolute path to the John the Ripper executable']),
OptBool.new('KoreLogic', [false, 'Apply the KoreLogic rules to 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::JohnTheRipper
)
end
# @param pwd [String] Password recovered from cracking an LM hash
# @param hash [String] NTLM hash for this password
# @return [String] `pwd` converted to the correct case to match the
# given NTLM hash
# @return [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
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
# This method creates a new {Metasploit::Framework::JtR::Cracker} and populates
# some of the attributes based on the module datastore options.
#
# @return [nilClass] if there is no active framework db connection
# @return [Metasploit::Framework::JtR::Cracker] if it successfully creates a JtR Cracker object
def new_john_cracker
return nil unless framework.db.active
Metasploit::Framework::JtR::Cracker.new(
config: datastore['CONFIG'],
john_path: datastore['JOHN_PATH'],
max_runtime: datastore['ITERATION_TIMEOUT'],
pot: datastore['POT'],
wordlist: datastore['CUSTOM_WORDLIST']
)
end
# This method instantiates a {Metasploit::Framework::JtR::Wordlist}, writes the data
# out to a file and returns the {Rex::Quickfile} object.
#
# @return [nilClass] if there is no active framework db connection
# @return [Rex::Quickfile] if it successfully wrote the wordlist to a file
def wordlist_file
return nil unless framework.db.active
wordlist = Metasploit::Framework::JtR::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
end
end
end