2005-11-26 02:34:39 +00:00
|
|
|
require 'rex/text'
|
|
|
|
|
2005-03-27 00:23:10 +00:00
|
|
|
module Rex
|
2005-07-16 07:38:31 +00:00
|
|
|
module Proto
|
2005-03-27 00:23:10 +00:00
|
|
|
module SMB
|
2005-09-16 09:27:41 +00:00
|
|
|
class Crypt
|
2005-03-27 00:23:10 +00:00
|
|
|
|
2008-11-12 22:47:21 +00:00
|
|
|
@@loaded_openssl = false
|
|
|
|
|
|
|
|
begin
|
|
|
|
require 'openssl'
|
|
|
|
@@loaded_openssl = true
|
|
|
|
rescue ::Exception
|
|
|
|
end
|
|
|
|
|
2005-11-03 04:43:19 +00:00
|
|
|
begin
|
|
|
|
|
2005-09-16 09:27:41 +00:00
|
|
|
def self.lanman_des(pass, chal)
|
2005-03-27 00:23:10 +00:00
|
|
|
e_p24( [ e_p16( [ pass.upcase()[0,14] ].pack('a14') ) ].pack('a21'), chal)
|
|
|
|
end
|
|
|
|
|
2005-09-16 09:27:41 +00:00
|
|
|
def self.e_p16(pass)
|
2005-03-27 00:23:10 +00:00
|
|
|
stat = "\x4b\x47\x53\x21\x40\x23\x24\x25"
|
|
|
|
des_hash(stat, pass[0,7]) << des_hash(stat, pass[7,7])
|
|
|
|
end
|
|
|
|
|
2005-09-16 09:27:41 +00:00
|
|
|
def self.e_p24(pass, chal)
|
2005-03-27 00:23:10 +00:00
|
|
|
des_hash(chal, pass[0,7]) << des_hash(chal, pass[7,7]) << des_hash(chal, pass[14,7])
|
|
|
|
end
|
|
|
|
|
2005-09-16 09:27:41 +00:00
|
|
|
def self.des_hash(data, ckey)
|
2008-11-12 22:47:21 +00:00
|
|
|
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
|
2005-03-27 00:23:10 +00:00
|
|
|
cipher = OpenSSL::Cipher::Cipher.new('des-ecb')
|
|
|
|
cipher.encrypt
|
|
|
|
cipher.key = des_56_to_64(ckey)
|
|
|
|
cipher.update(data)
|
|
|
|
end
|
|
|
|
|
2009-06-02 23:36:58 +00:00
|
|
|
def self.des_56_to_64(ckey56s)
|
2005-03-27 00:23:10 +00:00
|
|
|
ckey64 = []
|
2009-06-02 23:36:58 +00:00
|
|
|
ckey56 = ckey56s.unpack('C*')
|
2005-03-27 00:23:10 +00:00
|
|
|
ckey64[0] = ckey56[0]
|
|
|
|
ckey64[1] = ((ckey56[0] << 7) & 0xFF) | (ckey56[1] >> 1)
|
|
|
|
ckey64[2] = ((ckey56[1] << 6) & 0xFF) | (ckey56[2] >> 2)
|
|
|
|
ckey64[3] = ((ckey56[2] << 5) & 0xFF) | (ckey56[3] >> 3)
|
|
|
|
ckey64[4] = ((ckey56[3] << 4) & 0xFF) | (ckey56[4] >> 4)
|
|
|
|
ckey64[5] = ((ckey56[4] << 3) & 0xFF) | (ckey56[5] >> 5)
|
|
|
|
ckey64[6] = ((ckey56[5] << 2) & 0xFF) | (ckey56[6] >> 6)
|
|
|
|
ckey64[7] = (ckey56[6] << 1) & 0xFF
|
|
|
|
ckey64.pack('C*')
|
|
|
|
end
|
|
|
|
|
2005-09-16 09:27:41 +00:00
|
|
|
def self.ntlm_md4(pass, chal)
|
2006-03-07 20:19:30 +00:00
|
|
|
e_p24( [ md4_hash(Rex::Text.to_unicode(pass)) ].pack('a21'), chal)
|
2005-03-27 00:23:10 +00:00
|
|
|
end
|
|
|
|
|
2005-09-16 09:27:41 +00:00
|
|
|
def self.md4_hash(data)
|
2008-11-12 22:47:21 +00:00
|
|
|
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
|
2009-02-21 17:48:36 +00:00
|
|
|
digest = OpenSSL::Digest::MD4.digest(data)
|
2005-03-27 00:23:10 +00:00
|
|
|
end
|
2005-09-19 23:35:51 +00:00
|
|
|
|
|
|
|
def self.md5_hash(data)
|
2008-11-12 22:47:21 +00:00
|
|
|
raise RuntimeError, "No OpenSSL support" if not @@loaded_openssl
|
2009-02-21 17:48:36 +00:00
|
|
|
digest = OpenSSL::Digest::MD5.digest(data)
|
2008-10-22 22:42:52 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def self.lm2nt(pass, ntlm)
|
|
|
|
res = nil
|
|
|
|
Rex::Text.permute_case( pass.upcase ).each do |word|
|
|
|
|
if(md4_hash(Rex::Text.to_unicode(word)) == ntlm)
|
|
|
|
res = word
|
|
|
|
break
|
|
|
|
end
|
|
|
|
end
|
|
|
|
res
|
|
|
|
end
|
2005-11-03 04:43:19 +00:00
|
|
|
|
|
|
|
rescue LoadError
|
|
|
|
end
|
|
|
|
|
2005-03-27 00:23:10 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2008-10-22 22:42:52 +00:00
|
|
|
end
|