Patch from grutz (see #169). Added constants for SMB2

git-svn-id: file:///home/svn/framework3/trunk@5226 4d416f70-5f16-0410-b530-b9f4589650da
unstable
HD Moore 2007-12-27 17:42:32 +00:00
parent 5eda38fa5f
commit ad43a641f8
2 changed files with 111 additions and 7 deletions

View File

@ -80,6 +80,29 @@ SMB_COM_READ_BULK = 0xd8
SMB_COM_WRITE_BULK = 0xd9
SMB_COM_NO_ANDX_COMMAND = 0xff
# SMB Version 2 Commands
SMB2_OP_NEGPROT = 0x00
SMB2_OP_SESSSETUP = 0x01
SMB2_OP_LOGOFF = 0x02
SMB2_OP_TCON = 0x03
SMB2_OP_TDIS = 0x04
SMB2_OP_CREATE = 0x05
SMB2_OP_CLOSE = 0x06
SMB2_OP_FLUSH = 0x07
SMB2_OP_READ = 0x08
SMB2_OP_WRITE = 0x09
SMB2_OP_LOCK = 0x0a
SMB2_OP_IOCTL = 0x0b
SMB2_OP_CANCEL = 0x0c
SMB2_OP_KEEPALIVE = 0x0d
SMB2_OP_FIND = 0x0e
SMB2_OP_NOTIFY = 0x0f
SMB2_OP_GETINFO = 0x10
SMB2_OP_SETINFO = 0x11
SMB2_OP_BREAK = 0x12
# SMB_COM_NT_TRANSACT Subcommands
NT_TRANSACT_CREATE = 1 # File open/create
NT_TRANSACT_IOCTL = 2 # Device IOCTL
@ -356,6 +379,36 @@ SMB_HDR = Rex::Struct2::CStructTemplate.new(
)
# The SMB2 header template
SMB2_HDR = Rex::Struct2::CStructTemplate.new(
[ 'uint32n', 'Magic', 0xfe534d42 ],
[ 'uint16v', 'HeaderLen', 64 ],
[ 'uint16v', 'Reserved0', 0 ],
[ 'uint32v', 'NTStatus', 0 ],
[ 'uint16v', 'Opcode', 0 ],
[ 'uint16v', 'Reserved1', 0 ],
[ 'uint16v', 'Flags1', 0 ],
[ 'uint16v', 'Flags2', 0 ],
[ 'uint32v', 'ChainOffset', 0 ],
[ 'uint32v', 'SequenceHigh', 0 ],
[ 'uint32v', 'SequenceLow', 0 ],
[ 'uint32v', 'ProcessID', 0 ],
[ 'uint32v', 'TreeID', 0 ],
[ 'uint32v', 'UserIDHigh', 0 ],
[ 'uint32v', 'UserIDLow', 0 ],
[ 'uint32v', 'SignatureA', 0 ],
[ 'uint32v', 'SignatureB', 0 ],
[ 'uint32v', 'SignatureC', 0 ],
[ 'uint32v', 'SignatureD', 0 ],
[ 'string', 'Payload', nil, '']
)
# A basic SMB template to read all responses
SMB_BASE_HDR_PKT = Rex::Struct2::CStructTemplate.new(
[ 'template', 'SMB', SMB_HDR ],

View File

@ -378,7 +378,7 @@ CONST = Rex::Proto::SMB::Constants
# Process Type 1 NTLM Messages, return a Base64 Type 2 Message
#
def self.process_type1_message(message, nonce = "\x11\x22\x33\x44\x55\x66\x77\x88", win_domain = 'DOMAIN',
win_name = 'SERVER', dns_name = 'server', dns_domain = 'example.com')
win_name = 'SERVER', dns_name = 'server', dns_domain = 'example.com', downgrade = true)
dns_name = Rex::Text.to_unicode(dns_name + "." + dns_domain)
win_domain = Rex::Text.to_unicode(win_domain)
@ -386,8 +386,6 @@ CONST = Rex::Proto::SMB::Constants
win_name = Rex::Text.to_unicode(win_name)
decode = Rex::Text.decode_base64(message.strip)
puts "dns_name = #{dns_name}, dns_domain = #{dns_domain}"
type = decode[8]
if (type == 1)
@ -397,9 +395,18 @@ CONST = Rex::Proto::SMB::Constants
reqflags = Integer("0x" + reqflags.unpack("h8").to_s.reverse)
if (reqflags & CONST::REQUEST_TARGET) == CONST::REQUEST_TARGET
# At this time NTLMv2 and signing requirements are not supported
#flags = CONST::NEGOTIATE_UNICODE | CONST::NEGOTIATE_NTLM | CONST::NEGOTIATE_TARGET_INFO | CONST::TARGET_TYPE_DOMAIN | CONST::TARGET_TYPE_SERVER
flags = 0x00810201
if (downgrade)
# At this time NTLMv2 and signing requirements are not supported
if (reqflags & CONST::NEGOTIATE_NTLM2_KEY) == CONST::NEGOTIATE_NTLM2_KEY
reqflags = reqflags - CONST::NEGOTIATE_NTLM2_KEY
end
if (reqflags & CONST::NEGOTIATE_ALWAYS_SIGN) == CONST::NEGOTIATE_ALWAYS_SIGN
reqflags = reqflags - CONST::NEGOTIATE_ALWAYS_SIGN
end
end
flags = reqflags + CONST::TARGET_TYPE_DOMAIN + CONST::TARGET_TYPE_SERVER
tid = true
tidoffset = 48 + win_domain.length
@ -417,7 +424,7 @@ CONST = Rex::Proto::SMB::Constants
[dns_name.length].pack('v') +
dns_name
else
flags = CONST::NEGOTIATE_UNICODE | CONST::NEGOTIATE_NTLM
flags = CONST::NEGOTIATE_UNICODE + CONST::NEGOTIATE_NTLM
tid = false
end
@ -457,6 +464,50 @@ CONST = Rex::Proto::SMB::Constants
return type2msg
end
#
# Downgrading Type messages to LMv1/NTLMv1 and removing signing
#
def self.downgrade_type_message(message)
decode = Rex::Text.decode_base64(message.strip)
type = decode[8]
if (type > 0 and type < 4)
reqflags = decode[12..15] if (type == 1 or type == 3)
reqflags = decode[20..23] if (type == 2)
reqflags = Integer("0x" + reqflags.unpack("h8").to_s.reverse)
# Remove NEGOTIATE_NTLMV2_KEY and NEGOTIATE_ALWAYS_SIGN, this lowers the negotiation
# down to LMv1/NTLMv1.
if (reqflags & CONST::NEGOTIATE_NTLM2_KEY) == CONST::NEGOTIATE_NTLM2_KEY
reqflags = reqflags - CONST::NEGOTIATE_NTLM2_KEY
end
if (reqflags & CONST::NEGOTIATE_ALWAYS_SIGN) == CONST::NEGOTIATE_ALWAYS_SIGN
reqflags = reqflags - CONST::NEGOTIATE_ALWAYS_SIGN
end
# Return the flags back to the decode so we can base64 it again
flags = reqflags.to_s(16)
0.upto(8) do |idx|
if (idx > flags.length)
flags.insert(0, "0")
end
end
idx = 0
0.upto(3) do |cnt|
if (type == 2)
decode[23-cnt] = Integer("0x" + flags[idx .. idx + 1])
else
decode[15-cnt] = Integer("0x" + flags[idx .. idx + 1])
end
idx += 2
end
end
return Rex::Text.encode_base64(decode).delete("\n") # base64 encode and remove the returns
end
end
end
end