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/tools/password/hmac_sha1_crack.rb
Views: 11766
#!/usr/bin/env ruby12##3# This module requires Metasploit: https://metasploit.com/download4# Current source: https://github.com/rapid7/metasploit-framework5##67#8# This script cracks HMAC SHA1 hashes. It is strangely necessary as existing tools9# have issues with binary salt values and extremely large salt values. The primary10# goal of this tool is to handle IPMI 2.0 HMAC SHA1 hashes.11#12# Support for this format is being added to both hashcat and jtr, hopefully13# making this code obsolete.14#1516msfbase = __FILE__17while File.symlink?(msfbase)18msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))19end2021$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', '..', 'lib')))22require 'msfenv'2324$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']2526require 'rex'27require 'openssl'2829def usage30$stderr.puts("\nUsage: #{$0} hashes.txt <wordlist | - >\n")31$stderr.puts("The format of hash file is <identifier>:<hex-salt>:<hash>\n\n")32exit33end3435hash_inp = ARGV.shift || usage()36word_inp = ARGV.shift || usage()3738usage if [hash_inp, word_inp].include?("-h") or [hash_inp, word_inp].include?("--help")3940hash_fd = ::File.open(hash_inp, "rb")41word_fd = $stdin4243if word_inp != "-"44word_fd = ::File.open(word_inp, "rb")45end4647hashes = []48hash_fd.each_line do |line|49next unless line.strip.length > 050h_id, h_salt, h_hash = line.unpack("C*").pack("C*").strip.split(':', 3)5152unless h_id and h_salt and h_hash53$stderr.puts "[-] Invalid hash entry, missing field: #{line}"54next55end56unless h_salt =~ /^[a-f0-9]+$/i57$stderr.puts "[-] Invalid hash entry, salt must be in hex: #{line}"58next59end60hashes << [h_id, [h_salt].pack("H*"), [h_hash].pack("H*") ]61end62hash_fd.close6364stime = Time.now.to_f65count = 066cracked = 06768word_fd.each_line do |line|69# Preferable to strip so we can test passwords made of whitespace (or null)70line = line.unpack("C*").pack("C*").sub(/\r?\n?$/, '')71hashes.each do |hinfo|72if OpenSSL::HMAC.digest('sha1', line.to_s, hinfo[1]) == hinfo[2]73$stdout.puts [ hinfo[0], hinfo[1].unpack("H*").first, hinfo[2].unpack("H*").first, line.to_s ].join(":")74$stdout.flush75hinfo[3] = true76cracked += 177end78count += 17980if count % 2500000 == 081$stderr.puts "[*] Found #{cracked} passwords with #{hashes.length} left (#{(count / (Time.now.to_f - stime)).to_i}/s)"82end83end84hashes.delete_if {|e| e[3] }85break if hashes.length == 08687end88word_fd.close8990$stderr.puts "[*] Cracked #{cracked} passwords with #{hashes.length} left (#{(count / (Time.now.to_f - stime)).to_i}/s)"919293