mssql login : enable ntlmv2 authentification
git-svn-id: file:///home/svn/framework3/trunk@12223 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
aa72f18ec2
commit
b38a187631
|
@ -3,6 +3,7 @@ require 'msf/core/exploit/mssql_commands'
|
|||
require 'rex/proto/ntlm/crypt'
|
||||
require 'rex/proto/ntlm/constants'
|
||||
require 'rex/proto/ntlm/utils'
|
||||
require 'rex/proto/ntlm/exceptions'
|
||||
|
||||
|
||||
module Msf
|
||||
|
@ -17,16 +18,16 @@ module Exploit::Remote::MSSQL
|
|||
include Exploit::Remote::MSSQL_COMMANDS
|
||||
include Exploit::Remote::Udp
|
||||
include Exploit::Remote::Tcp
|
||||
include Exploit::Remote::NTLM::Client
|
||||
|
||||
#
|
||||
# Constants
|
||||
#
|
||||
|
||||
# Ntlm
|
||||
NTLM_CRYPT = Rex::Proto::NTLM::Crypt
|
||||
NTLM_CONST = Rex::Proto::NTLM::Constants
|
||||
NTLM_UTILS = Rex::Proto::NTLM::Utils
|
||||
|
||||
NTLM_XCEPT = Rex::Proto::NTLM::Exceptions
|
||||
|
||||
# Encryption
|
||||
ENCRYPT_OFF = 0x00 #Encryption is available but off.
|
||||
ENCRYPT_ON = 0x01 #Encryption is available and on.
|
||||
|
@ -67,15 +68,16 @@ module Exploit::Remote::MSSQL
|
|||
Opt::RPORT(1433),
|
||||
OptString.new('USERNAME', [ false, 'The username to authenticate as', 'sa']),
|
||||
OptString.new('PASSWORD', [ false, 'The password for the specified username', '']),
|
||||
|
||||
OptBool.new('USE_WINDOWS_AUTHENT', [ true, 'Use windows authentification', false]),
|
||||
], Msf::Exploit::Remote::MSSQL)
|
||||
register_advanced_options(
|
||||
[
|
||||
OptPath.new('HEX2BINARY', [ false, "The path to the hex2binary script on the disk",
|
||||
File.join(Msf::Config.install_root, "data", "exploits", "mssql", "h2b")
|
||||
])
|
||||
], Msf::Exploit::Remote::MSSQL)
|
||||
|
||||
OptPath.new('HEX2BINARY', [ false, "The path to the hex2binary script on the disk",
|
||||
File.join(Msf::Config.install_root, "data", "exploits", "mssql", "h2b")
|
||||
]),
|
||||
OptString.new('DOMAIN', [ true, 'The domain to use for windows authentification', 'WORKSTATION'])
|
||||
], Msf::Exploit::Remote::MSSQL)
|
||||
register_autofilter_ports([ 1433, 1434, 1435, 14330, 2533, 9152, 2638 ])
|
||||
register_autofilter_services(%W{ ms-sql-s ms-sql2000 sybase })
|
||||
end
|
||||
|
@ -415,9 +417,22 @@ module Exploit::Remote::MSSQL
|
|||
cname = Rex::Text.to_unicode( Rex::Text.rand_text_alpha(rand(8)+1) )
|
||||
aname = Rex::Text.to_unicode( Rex::Text.rand_text_alpha(rand(8)+1) ) #application and library name
|
||||
sname = Rex::Text.to_unicode( rhost )
|
||||
dname = Rex::Text.to_unicode( db )
|
||||
dname = Rex::Text.to_unicode( db )
|
||||
|
||||
ntlm_options = {
|
||||
:signing => false,
|
||||
:usentlm2_session => datastore['NTLM::UseNTLM2_session'],
|
||||
:use_ntlmv2 => datastore['NTLM::UseNTLMv2'],
|
||||
:send_lm => datastore['NTLM::SendLM'],
|
||||
:send_ntlm => 'NTLM::SendNTLM'
|
||||
}
|
||||
|
||||
ntlmssp_flags = NTLM_UTILS.make_ntlm_flags(ntlm_options)
|
||||
workstation_name = Rex::Text.rand_text_alpha(rand(8)+1)
|
||||
domain_name = datastore['DOMAIN']
|
||||
|
||||
# use a default value for now
|
||||
ntlmsspblob = NTLM_UTILS::make_ntlmssp_blob_init('WORKGROUP','WORKSTATION', 0xa2080205)
|
||||
ntlmsspblob = NTLM_UTILS::make_ntlmssp_blob_init(domain_name, workstation_name, ntlmssp_flags)
|
||||
|
||||
idx = pkt.size + 50 # lengths below
|
||||
|
||||
|
@ -470,38 +485,38 @@ module Exploit::Remote::MSSQL
|
|||
# is set to STATUS_NORMAL and not STATUS_END_OF_MESSAGE, then internally it waits for the ntlm_authentification
|
||||
resp = mssql_send_recv(pkt,15, false)
|
||||
|
||||
# Extract the NTLM challenge key the lazy way
|
||||
cidx = resp.index("NTLMSSP\x00\x02\x00\x00\x00")
|
||||
|
||||
#add exception and ...
|
||||
#if (cidx == -1)
|
||||
# raise XCEPT::NTLM2MissingChallenge
|
||||
#end
|
||||
#for the moment :
|
||||
raise Error,"No challenge" if not cidx
|
||||
|
||||
resp.slice!(0,cidx)
|
||||
|
||||
challenge_key = resp[24, 8]
|
||||
|
||||
#!!!TEMPORARY SOLUTION !!! (copy/paste from smb/client.rb)!!!
|
||||
# Until ntlm proto will have a wrapper in lib/msf and will be integrated in smb and here
|
||||
# we will use ntlm2_session response only and hope for the best ... (no ntlmv2 , no signing for now ...)
|
||||
|
||||
# Get default data
|
||||
begin
|
||||
blob_data = NTLM_UTILS.parse_ntlm_type_2_blob(resp)
|
||||
# a domain.length < 3 will hit this
|
||||
rescue NTLM_XCEPT::NTLMMissingChallenge
|
||||
info = {:errors => []}
|
||||
mssql_parse_reply(resp, info)
|
||||
mssql_print_reply(info)
|
||||
return false
|
||||
end
|
||||
challenge_key = blob_data[:challenge_key]
|
||||
server_ntlmssp_flags = blob_data[:server_ntlmssp_flags] #else should raise an error
|
||||
#netbios name
|
||||
default_name = blob_data[:default_name] || ''
|
||||
#netbios domain
|
||||
default_domain = blob_data[:default_domain] || ''
|
||||
#dns name
|
||||
dns_host_name = blob_data[:dns_host_name] || ''
|
||||
#dns domain
|
||||
dns_domain_name = blob_data[:dns_domain_name] || ''
|
||||
#Client time
|
||||
chall_MsvAvTimestamp = blob_data[:chall_MsvAvTimestamp] || ''
|
||||
|
||||
client_challenge = Rex::Text.rand_text(8)
|
||||
argntlm = {
|
||||
:ntlm_hash => NTLM_CRYPT::ntlm_hash(pass),
|
||||
:challenge => challenge_key
|
||||
}
|
||||
|
||||
optntlm = { :client_challenge => client_challenge}
|
||||
resp_ntlm = NTLM_CRYPT::ntlm2_session(argntlm,optntlm).join[24,24]
|
||||
# Generate the fake LANMAN hash
|
||||
resp_lm = client_challenge + ("\x00" * 16)
|
||||
spnopt = {:use_spn => datastore['NTLM::SendNTLM'], :name => self.rhost}
|
||||
|
||||
resp_lm, resp_ntlm, client_challenge, ntlm_cli_challenge = NTLM_UTILS.create_lm_ntlm_responses(user, pass, challenge_key,
|
||||
domain_name, default_name, default_domain,
|
||||
dns_host_name, dns_domain_name, chall_MsvAvTimestamp,
|
||||
spnopt, ntlm_options)
|
||||
|
||||
ntlmssp = NTLM_UTILS.make_ntlmssp_blob_auth(domain_name, workstation_name, user, resp_lm, resp_ntlm, '', ntlmssp_flags)
|
||||
|
||||
ntlmssp = NTLM_UTILS.make_ntlmssp_blob_auth('WORKGROUP','WORKSTATION', user, resp_lm, resp_ntlm,
|
||||
'', 0xa2080205)
|
||||
# Create an SSPIMessage
|
||||
idx = 0
|
||||
pkt = ''
|
||||
|
|
|
@ -2,6 +2,13 @@ module Rex
|
|||
module Proto
|
||||
module NTLM
|
||||
module Exceptions
|
||||
|
||||
class NTLMMissingChallenge < ::RuntimeError
|
||||
def to_s
|
||||
"Unable to complete, no challenge key found"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
require 'rex/proto/ntlm/constants'
|
||||
require 'rex/proto/ntlm/crypt'
|
||||
require 'rex/proto/ntlm/exceptions'
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
|
@ -8,6 +9,7 @@ class Utils
|
|||
|
||||
CONST = Rex::Proto::NTLM::Constants
|
||||
CRYPT = Rex::Proto::NTLM::Crypt
|
||||
XCEPT = Rex::Proto::NTLM::Exceptions
|
||||
|
||||
#duplicate from lib/rex/proto/smb/utils cause we only need this fonction from Rex::Proto::SMB::Utils
|
||||
# Convert a unix timestamp to a 64-bit signed server time
|
||||
|
@ -376,7 +378,7 @@ class Utils
|
|||
cidx = blob.index("NTLMSSP\x00\x02\x00\x00\x00")
|
||||
|
||||
if not cidx
|
||||
raise XCEPT::NTLM2MissingChallenge
|
||||
raise XCEPT::NTLMMissingChallenge
|
||||
end
|
||||
|
||||
data[:challenge_key] = blob[cidx + 24, 8]
|
||||
|
|
Loading…
Reference in New Issue