CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

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