Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/auxiliary/analyze/crack_aix.rb
Views: 11779
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Auxiliary6include Msf::Auxiliary::PasswordCracker7include Msf::Exploit::Deprecated8moved_from 'auxiliary/analyze/jtr_aix'910def initialize11super(12'Name' => 'Password Cracker: AIX',13'Description' => %(14This module uses John the Ripper or Hashcat to identify weak passwords that have been15acquired from passwd files on AIX systems. These utilize DES hashing.16DES is format 1500 in Hashcat.17),18'Author' => [19'theLightCosine',20'hdm',21'h00die' # hashcat integration22],23'License' => MSF_LICENSE, # JtR itself is GPLv2, but this wrapper is MSF (BSD)24'Actions' => [25['john', { 'Description' => 'Use John the Ripper' }],26['hashcat', { 'Description' => 'Use Hashcat' }],27],28'DefaultAction' => 'john',29)3031register_options(32[33OptBool.new('INCREMENTAL', [false, 'Run in incremental mode', true]),34OptBool.new('WORDLIST', [false, 'Run in wordlist mode', true])35]36)37end3839def show_command(cracker_instance)40return unless datastore['ShowCommand']4142if action.name == 'john'43cmd = cracker_instance.john_crack_command44elsif action.name == 'hashcat'45cmd = cracker_instance.hashcat_crack_command46end47print_status(" Cracking Command: #{cmd.join(' ')}")48end4950def run51def check_results(passwords, results, hash_type, method)52passwords.each do |password_line|53password_line.chomp!54next if password_line.blank?5556fields = password_line.split(':')57# If we don't have an expected minimum number of fields, this is probably not a hash line58next unless fields.count >= 35960cred = { 'hash_type' => hash_type, 'method' => method }61if action.name == 'john'62cred['username'] = fields.shift63cred['core_id'] = fields.pop644.times { fields.pop } # Get rid of extra :65cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it66elsif action.name == 'hashcat'67cred['core_id'] = fields.shift68cred['hash'] = fields.shift69cred['password'] = fields.join(':') # Anything left must be the password. This accounts for passwords with semi-colons in it70next if cred['core_id'].include?("Hashfile '") && cred['core_id'].include?("' on line ") # skip error lines7172# we don't have the username since we overloaded it with the core_id (since its a better fit for us)73# so we can now just go grab the username from the DB74cred['username'] = framework.db.creds(workspace: myworkspace, id: cred['core_id'])[0].public.username75end76results = process_cracker_results(results, cred)77end78results79end8081tbl = tbl = cracker_results_table8283hash_types_to_crack = ['descrypt']84jobs_to_do = []8586# build our job list87hash_types_to_crack.each do |hash_type|88job = hash_job(hash_type, action.name)89if job.nil?90print_status("No #{hash_type} found to crack")91else92jobs_to_do << job93end94end9596# bail early of no jobs to do97if jobs_to_do.empty?98print_good("No uncracked password hashes found for: #{hash_types_to_crack.join(', ')}")99return100end101102# array of arrays for cracked passwords.103# Inner array format: db_id, hash_type, username, password, method_of_crack104results = []105106cracker = new_password_cracker(action.name)107108# generate our wordlist and close the file handle. max length of DES is 8109wordlist = wordlist_file(8)110unless wordlist111print_error('This module cannot run without a database connected. Use db_connect to connect to a database.')112return113end114115wordlist.close116print_status "Wordlist file written out to #{wordlist.path}"117118cleanup_files = [wordlist.path]119120jobs_to_do.each do |job|121format = job['type']122hash_file = Rex::Quickfile.new("hashes_#{job['type']}_")123hash_file.puts job['formatted_hashlist']124hash_file.close125cracker.hash_path = hash_file.path126cleanup_files << hash_file.path127128# dupe our original cracker so we can safely change options between each run129cracker_instance = cracker.dup130cracker_instance.format = format131132if action.name == 'john'133cracker_instance.fork = datastore['FORK']134end135136# first check if anything has already been cracked so we don't report it incorrectly137print_status "Checking #{format} hashes already cracked..."138results = check_results(cracker_instance.each_cracked_password, results, format, 'Already Cracked/POT')139vprint_good(append_results(tbl, results)) unless results.empty?140job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list141next if job['cred_ids_left_to_crack'].empty?142143if action.name == 'john'144print_status "Cracking #{format} hashes in single mode..."145cracker_instance.mode_single(wordlist.path)146show_command cracker_instance147cracker_instance.crack do |line|148vprint_status(" #{line.chomp}")149end150results = check_results(cracker_instance.each_cracked_password, results, format, 'Single')151vprint_good(append_results(tbl, results)) unless results.empty?152job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list153next if job['cred_ids_left_to_crack'].empty?154155print_status "Cracking #{format} hashes in normal mode..."156cracker_instance.mode_normal157show_command cracker_instance158cracker_instance.crack do |line|159vprint_status(" #{line.chomp}")160end161results = check_results(cracker_instance.each_cracked_password, results, format, 'Normal')162vprint_good(append_results(tbl, results)) unless results.empty?163job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list164next if job['cred_ids_left_to_crack'].empty?165end166167if datastore['INCREMENTAL']168print_status "Cracking #{format} hashes in incremental mode..."169cracker_instance.mode_incremental170show_command cracker_instance171cracker_instance.crack do |line|172vprint_status(" #{line.chomp}")173end174results = check_results(cracker_instance.each_cracked_password, results, format, 'Incremental')175vprint_good(append_results(tbl, results)) unless results.empty?176job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list177next if job['cred_ids_left_to_crack'].empty?178end179180next unless datastore['WORDLIST']181182print_status "Cracking #{format} hashes in wordlist mode..."183cracker_instance.mode_wordlist(wordlist.path)184# Turn on KoreLogic rules if the user asked for it185if action.name == 'john' && datastore['KORELOGIC']186cracker_instance.rules = 'KoreLogicRules'187print_status 'Applying KoreLogic ruleset...'188end189show_command cracker_instance190cracker_instance.crack do |line|191vprint_status(" #{line.chomp}")192end193194results = check_results(cracker_instance.each_cracked_password, results, format, 'Wordlist')195vprint_good(append_results(tbl, results)) unless results.empty?196job['cred_ids_left_to_crack'] = job['cred_ids_left_to_crack'] - results.map { |i| i[0].to_i } # remove cracked hashes from the hash list197next if job['cred_ids_left_to_crack'].empty?198end199200# give a final print of results201print_good(append_results(tbl, results))202203if datastore['DeleteTempFiles']204cleanup_files.each do |f|205File.delete(f)206end207end208end209end210211212