forked from rapid7/metasploit-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhalflm_second.rb
executable file
·141 lines (118 loc) · 3.19 KB
/
halflm_second.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/env ruby
#
# $Id$
#
# This script cracks a half-lm challenge/response hash that uses a
# a static challenge key. The idea is you use rainbow tables to
# crack the first 7 chars and this script to complete a few remaining.
# If the password is longer than 10 characters, this script will fail.
#
# $Revision$
#
msfbase = __FILE__
while File.symlink?(msfbase)
msfbase = File.expand_path(File.readlink(msfbase), File.dirname(msfbase))
end
$:.unshift(File.expand_path(File.join(File.dirname(msfbase), '..', 'lib')))
require 'fastlib'
require 'msfenv'
$:.unshift(ENV['MSF_LOCAL_LIB']) if ENV['MSF_LOCAL_LIB']
require 'rex'
def usage
$stderr.puts("\n" + " Usage: #{$0} <options>\n" + $args.usage)
exit
end
def try(word,challenge)
buf = ::Rex::Proto::NTLM::Crypt.lanman_des(word, challenge)
buf.unpack("H*")[0]
end
hash = pass = chall = nil
$args = Rex::Parser::Arguments.new(
"-n" => [ true, "The encypted LM hash to crack" ],
"-p" => [ true, "The decrypted LANMAN password for bytes 1-7" ],
"-s" => [ true, "The server challenge (default value 1122334455667788)" ],
"-h" => [ false, "Display this help information" ])
$args.parse(ARGV) { |opt, idx, val|
case opt
when "-n"
hash = val
when "-p"
pass = val
when "-s"
chall = val
when "-h"
usage
else
usage
end
}
if (not (hash and pass))
usage
end
if (not chall)
chall = ["1122334455667788"].pack("H*")
else
if not chall =~ /^([a-fA-F0-9]{16})$/
$stderr.puts "[*] Server challenge must be exactly 16 bytes of hexadecimal"
exit
else
chall = [chall].pack("H*")
end
end
if(hash.length != 48)
$stderr.puts "[*] LANMAN should be exactly 48 bytes of hexadecimal"
exit
end
if(pass.length != 7)
$stderr.puts "[*] Cracked LANMAN password should be exactly 7 characters"
exit
end
pass = pass.upcase
hash = hash.downcase
cset = [*(1..255)].pack("C*").upcase.unpack("C*").uniq
stime = Time.now.to_f
puts "[*] Trying one character..."
0.upto(cset.length-1) do |c1|
test = pass + cset[c1].chr
if(try(test, chall) == hash)
puts "[*] Cracked: #{test}"
exit
end
end
etime = Time.now.to_f - stime
puts "[*] Trying two characters (eta: #{etime * cset.length} seconds)..."
0.upto(cset.length-1) do |c1|
0.upto(cset.length-1) do |c2|
test = pass + cset[c1].chr + cset[c2].chr
if(try(test, chall) == hash)
puts "[*] Cracked: #{test}"
exit
end
end
end
puts "[*] Trying three characters (eta: #{etime * cset.length * cset.length} seconds)..."
0.upto(cset.length-1) do |c1|
0.upto(cset.length-1) do |c2|
0.upto(cset.length-1) do |c3|
test = pass + cset[c1].chr + cset[c2].chr + cset[c3].chr
if(try(test, chall) == hash)
puts "[*] Cracked: #{test}"
exit
end
end
end
end
puts "[*] Trying four characters (eta: #{etime * cset.length * cset.length * cset.length} seconds)..."
0.upto(cset.length-1) do |c1|
0.upto(cset.length-1) do |c2|
0.upto(cset.length-1) do |c3|
0.upto(cset.length-1) do |c4|
test = pass + cset[c1].chr + cset[c2].chr + cset[c3].chr + cset[c4].chr
if(try(test, chall) == hash)
puts "[*] Cracked: #{test}"
exit
end
end
end
end
end