BozoCrack is a depressingly effective MD5 password hash cracker with
almost zero CPU/GPU load. Instead of rainbow tables, dictionaries, or
brute force, BozoCrack simply finds the plaintext password.
Specifically, it googles the MD5 hash and hopes the plaintext appears
somewhere on the first page of results.
It works way better than it ever should.
How?
Basic usage:
Example with output:
To show just how bad an idea it is to use plain MD5 as a password hashing mechanism. Honestly, if the passwords can be cracked with this software, there are no excuses.
Who?
BozoCrack was written by Juuso Salonen
(bozocrack.rb)
BozoCrack
It works way better than it ever should.
How?
Basic usage:
$ ruby bozocrack.rb my_md5_hashes.txtThe input file has no specified format. BozoCrack automatically picks up strings that look like MD5 hashes. A single line shouldn’t contain more than one hash.
Example with output:
$ ruby bozocrack.rb example.txtWhy?
Loaded 5 unique hashes
fcf1eed8596699624167416a1e7e122e:octopus
bed128365216c019988915ed3add75fb:passw0rd
d0763edaa9d9bd2a9516280e9044d885:monkey
dfd8c10c1b9b58c8bf102225ae3be9eb:12081977
ede6b50e7b5826fe48fc1f0fe772c48f:1q2w3e4r5t6y
To show just how bad an idea it is to use plain MD5 as a password hashing mechanism. Honestly, if the passwords can be cracked with this software, there are no excuses.
Who?
BozoCrack was written by Juuso Salonen
(bozocrack.rb)
BozoCrack
require 'digest/md5'
require 'net/http'
class BozoCrack
def initialize(filename)
@hashes = Array.new
@cache = Hash.new
File.new(filename).each_line do |line|
if m = line.chomp.match(/\b([a-fA-F0-9]{32})\b/)
@hashes << m[1]
end
end
@hashes.uniq!
puts "Loaded #{@hashes.count} unique hashes"
load_cache
end
def crack
@hashes.each do |hash|
if plaintext = @cache[hash]
puts "#{hash}:#{plaintext}"
next
end
if plaintext = crack_single_hash(hash)
puts "#{hash}:#{plaintext}"
append_to_cache(hash, plaintext)
end
sleep 1
end
end
private
def crack_single_hash(hash)
response = Net::HTTP.get URI("http://www.google.com/search?q=#{hash}")
wordlist = response.split(/\s+/)
if plaintext = dictionary_attack(hash, wordlist)
return plaintext
end
nil
end
def dictionary_attack(hash, wordlist)
wordlist.each do |word|
if Digest::MD5.hexdigest(word) == hash.downcase
return word
end
end
nil
end
def load_cache(filename = "cache")
if File.file? filename
File.new(filename).each_line do |line|
if m = line.chomp.match(/^([a-fA-F0-9]{32}):(.*)$/)
@cache[m[1]] = m[2]
end
end
end
end
def append_to_cache(hash, plaintext, filename = "cache")
File.open(filename, "a") do |file|
file.write "#{hash}:#{plaintext}\n"
end
end
end
if ARGV.size == 1
BozoCrack.new(ARGV[0]).crack
else
puts "Usage example: ruby bozocrack.rb file_with_md5_hashes.txt"
end
No comments:
Post a Comment